ExePackage RemotePayload hash value issue - wix

I have implemented prerequisites using ExePackage with RemotePayload because I need to download package using runtime webinstaller (DownloadURL). But in that when package is upgraded after sometime like quarterly update that time package version and hash value is also changed. So, I get error like 0x80091007 (Hash value is not correct). So, please help me if anyone have idea about how to ignore hash value check. Below is code which I have implemented:
<ExePackage
Id="MicrosoftEdgeWebview2"
DisplayName="Microsoft Edge Webview2 Runtime"
Compressed="no"
Cache="no"
PerMachine="yes"
Vital ="yes"
Permanent ="yes"
InstallSize="1"
InstallCommand="/silent /install"
DetectCondition="MicrosoftEdgeWebview2Version >= $(var.MicrosoftEdgeWebview2MinimumVersion) OR MicrosoftEdgeWebview2Version64 >= $(var.MicrosoftEdgeWebview2MinimumVersion)"
Name="MicrosoftEdgeWebview2Setup.exe"
DownloadUrl="https://go.microsoft.com/fwlink/p/?LinkId=2124703">
<RemotePayload
ProductName="Microsoft Edge Webview2 Runtime"
Description="Microsoft Edge Webview2 Runtime Setup"
Hash="080e3e4cdcfc809762a32e8fa7cdc0f37b8e36a5"
Size="1778968" Version="1.3.153.47" />

For security reasons, the Burn engine will always verify the payload. To avoid hash validation, you have to specify certificate information in the RemotePayload so it validates the digital signature instead. You should use heat.exe payload ... to harvest this information.
"%WIX%\bin\heat.exe" payload windowsdesktop-runtime-5.0.5-win-x64.exe -o windowsdesktop-runtime-5.0.5-win-x64.exe.wxs
<RemotePayload
CertificatePublicKey="F49F9B33E25E33CCA0BFB15A62B7C29FFAB3880B"
CertificateThumbprint="ABDCA79AF9DD48A0EA702AD45260B3C03093FB4B"
Description="Microsoft Windows Desktop Runtime - 5.0.5 (x64)"
Hash="9CE1E77FE51E3F104D1DF7670F83F12B8ABF82F6"
ProductName="Microsoft Windows Desktop Runtime - 5.0.5 (x64)"
Size="54977944"
Version="5.0.5.29917"
/>

Related

How to install Microsoft Access Runtime 2013 32-Bit Silently?

I am trying to install Microsoft Access Runtime 2013 32-Bit silently using quiet property, but still it is showing the Installation UI window and asking to accept EULA. Earlier I was using Access Database Engine 2007 which was getting installed silently with quiet command. What am I missing? I am using below code to install it silently:
<ExePackage DisplayName="Microsoft Access Runtime 2013"
SourceFile="..\Prerequisites\Microsoft Access x86 Runtime 2013\AccessRuntime_x86_en-us.exe"
InstallCommand="/quiet"
InstallCondition="NOT ACCESS_ENGINE=5"
Permanent="yes"
Compressed ="yes"
/>
Please read the following tips from itninja.com (formerly appdeploy.com):
https://www.itninja.com/software/microsoft/access-runtime/2013-14
https://www.itninja.com/question/packaging-access-runtime-2013
Essentially:
Extract files using AccessRuntime_x86_en-us.exe /extract:ExtractedFiles.
Create a config.xml as described in the links above. Let me just duplicate it here in case the links go dead. And obviously update the paths for your purpose and for your environment:
<Configuration Product="AccessRT">
<Display Level="None" CompletionNotice="no" SuppressModal="yes" AcceptEula="yes" />
<Logging Type="standard" Path="C:\Windows\Temp\" Template="Microsoft_Access_2013_Runtime_Setup(*).log" />
<COMPANYNAME Value="Company Name" />
<Setting Id="SETUP_REBOOT" Value="Never" />
</Configuration>
Install with setup.exe /config config.xml.

Remove component with in next update in WiX

I have a service component installed twice in one of my previous releases.
<Component Id="MyServiceWin7" Guid="{GUID_WIN7}">
<File Id="mysvc_Win7"
Name="mysvc.exe"
Source=mysvc.exe"
KeyPath = "yes"/>
<ServiceControl Id="MYSVC_Win7"
Name="MYSVC"
Remove="uninstall"
Start="install"
Stop="both"
Wait="no" />
<ServiceInstall Id="My_Svc_Win7"
Name="MYSVC"
DisplayName="MYSVC"
Type="ownProcess"
Start="auto"
ErrorControl="normal"
LoadOrderGroup=""
Description="My service">
</component>
<Component Id="MyServiceWin8" Guid="{GUID_WIN8}">
<File Id="mysvc_Win8"
Name="mysvc.exe"
Source=mysvc.exe"
KeyPath = "yes"/>
<ServiceControl Id="MYSVC_Win8"
Name="MYSVC"
Remove="uninstall"
Start="install"
Stop="both"
Wait="no" />
<ServiceInstall Id="My_Svc_Win8"
Name="MYSVC"
DisplayName="MYSVC"
Type="ownProcess"
Start="auto"
ErrorControl="normal"
LoadOrderGroup=""
Description="My service">
</component>
So there will be two instances of the MYSVC component. Both are mapping to MYSVC.exe.
I missed the OS version condition check in the previous release.
It runs successfully.
I am thinking to delete the dummy additional COMPONENT (GUID_Win7 or GUID_WIN8) in the next update.
How I can delete it, do I need to write a custom action?
Any help would be appreciated.
EDIT::
Please find answers,
mysvc is having some third party lib dependancy os specific Win7 and Win8, it works means it installed successfully if we check sc qc mysvc I get service created and mysvc.exe is mapped to service binpath
yes these two service components targets same destinationand there is only one component when I do sc query mysvc
No there only one entry of service. mysvc.exe is win8 version on disk.
Thanks for suggestions, that breaking link.
Currently I have %ProgramFiles%\MyApp\mysvc.exe common path for both win 7 and win8.
So my question if create new common path to break previous link.
ProgramFiles%\MyApp\mysvc\mysvc.exe [[NEW_GUID1]] for win7
ProgramFiles%\MyApp\mysvc\mysvc.exe [[NEW_GUID2]] for win8
Components with [[OLD_GUID1]] , [[OLD_GUID2]] will be on system forever
until my product is uninstalled, so cant we just delete components with [[OLD_GUID1]], [[OLD_GUID2]] to clean stale(non functional) components
Thanks
Some Questions:
First of all, can we ask why you decided to install the service in two flavors? Does this mean that the service has different binaries for Win7 and Win8? If so, then it is unclear why you say it works as it stands.
Do these service components target two different installation locations so they both run side-by-side, or do you target the same target destination with both components? (so there is only one instance of the file after installation).
Are there two entries in the list of services on the box after installation? If you target the same location with both components, what file version of mysvc.exe made it onto the disk? (if they are different).
I wrote the below before the above questions. Please update your question with the answers to the questions. The below might be irrellevant - we need more information.
Sins of The Past: If you have installed the same file twice with two different component GUIDs in the previous version then this is wrong and I would recommend you "break the link" to the sins of the past by setting two new component GUIDs for the new release and crucially: set a new absolute installation location for each component (do not target the same absolute key path with two different GUIDs! - conditions or not).
The idea is to de-couple the old and new versions so that you start with a clean(er) slate.
Something like:
Comp 1: {77777777-7777-7777-7777-777777777777}, [ProgramFilesFolder]My App\Win7\mysvc.exe
Comp 2: {42424242-4242-4242-4242-424242424242}, [ProgramFilesFolder]My App\Win8\mysvc.exe
Personally I would avoid the Windows version number and maybe use something else. How about a year?
Comp 1: {77777777-7777-7777-7777-777777777777}, [ProgramFilesFolder]My App\2007\mysvc.exe
Comp 2: {42424242-4242-4242-4242-424242424242}, [ProgramFilesFolder]My App\2014\mysvc.exe
Just to not hard code a misleading value if the Win8 version runs on Win10 for example.
N.B!: Note that the above, sample GUIDs are well-known and dysfunctional GUIDs and
should not be copied and used! This is of high cruciality :-).

How to Create a Patch in WiX with the different product codes

I use Purely WiX approach to making patches and am trying to make a single MSP work for 2 different MSI's.
I have v1.1 MSI and v1.2 MSI, and plan to create an MSP using v1.2 MSI, so that the MSP can be used for both v1.1 and v1.2.
I set Validate/#ProductId='no' as its description says:
Requires that the installed ProductCode match the target ProductCode
used to create the transform. The default is 'yes'.
However, it only works for v1.2. So far, the only way I was able to work was to add 2 TargetProductCode/#Id as below.
Is this a bug for Validate/#ProductId? Or Is that the right way to do?
<Media Id="5000" Cabinet="RTM.cab" >
<PatchBaseline Id="RTM" >
<Validate ProductId='no' ProductLanguage='no' ProductVersion="Update" ProductVersionOperator='LesserOrEqual' UpgradeCode='no' />
</PatchBaseline>
</Media>
<!-- Why do I need this when Validate/#ProductId='no'? -->
<TargetProductCodes Replace='no'>
<TargetProductCode Id='{xxx}' />
<TargetProductCode Id='{xxx}' />
</TargetProductCodes>
<PatchFamilyRef Id="myRollup"/>
There is a same question but both didn't work.
I had the same issue, the Validate/#ProductId='no' doesn't seem to do much for me, unless I'm doing something wrong.
What I've found is you need to keep the ProductId the same for each update, and only change it for a major version upgrade (at which point there is no MSP to go from v1.x to v2.0, it's an upgrade install via an MSI).
Then you can build the MSP based on v1.0 and set ProductVersionOperator to GreaterOrEqual, or build it based on v1.1 and set it to LesserOrEqual, and the MSP's will work on any v1.x MSI.

Detect whether MS Office installed is 32bit or 64bit by using registry

I want to install vsto addin based on the excel version (32 bit or 64 bit).
I am planning to bundle both 32bit and 64 bit msis and install one by determining the excel version.
I am able to find this link to detect whether 2010 office is 32 bit or 64 bit by using registry.
Detect whether Office is 32bit or 64bit via the registry
But i want to check for excel 2007 and 2013 whether they are 32 bit or 64 bit.
Is it possible to detect them via registry.
First, look for the installed version of Outlook in this key:
HKEY_CLASSES_ROOT\Outlook.Application\CurVer
The value will be Outlook.Application.15 (for 2013). Then parse that value to get the integer and lookup this key:
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Office\15.0\Outlook
If it exists, check the value of Bitness to determine if it is 32-bit (x86) or 64-bit (x64). If it doesn't exist, assume 32-bit.
You can't reliably detect it from registry (direct call). Better is to create Custom installer module in C# or VB.net, fetch ProductCode of application. From product code, you can get the Bitness.
Product code is also fetched from registry, but let Office application handle it.
Private IsExcel32Bit As Boolean = False
Private IsExcel64Bit As Boolean = False
Private ReadOnly STR_prdCodeDelimeter As Char = CChar("-")
Private Sub GetExcelBitness(ByVal exApp As Microsoft.Office.Interop.Excel.Application)
Dim prdCode As String = exApp.ProductCode
If Not String.IsNullOrEmpty(prdCode) AndAlso CInt(prdCode.Split(STR_prdCodeDelimeter)(3)(0).ToString) = 0 Then
IsExcel32Bit = True
ElseIf Not String.IsNullOrEmpty(prdCode) AndAlso CInt(prdCode.Split(STR_prdCodeDelimeter)(3)(0).ToString) = 1 Then
IsExcel64Bit = True
End If
End Sub
Btw keeping both installer separately is going to help you in future. Sometimes product code might be null or wrong if MS Office is not installed properly.
Given: Office32 is installed into "Program Files (x86)", this works for me.
I basically check to see if winword.exe is somewhere below the key. If they don't install the word part, well, tough at this point. I use this to variably run 32-bit or 64-bit msi installers for office.
<Fragment>
<Property Id="IS_32BITOFFICE">
<DirectorySearch Path="[ProgramFilesFolder]\Microsoft Office"
Depth="4"
AssignToProperty="no"
Id="IS_32BIT_OFFICE_DIRSEARCH">
<FileSearch Name="winword.exe" />
</DirectorySearch>
</Property>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="WIN64_OFFICE32_MSI">
<File Id="WIN64_OFFICE32_MSI" src="WIN64_OFFICE32.txt"/>
<Condition>IS_32BITOFFICE</Condition>
</Component>
<Component Id="WIN64_OFFICE64_MSI">
<File Id="WIN64_OFFICE64_MSI" src="WIN64_OFFICE64.txt"/>
<Condition>NOT IS_32BITOFFICE</Condition>
</Component>
</ComponentGroup>
</Fragment>
You can use the product code (GUID) to identify the bitness of Office applications. See How to detect whether installed MS Office 2010 is 32 or 64 bit for more information.

How to check an installed version of a product from MSI

After review a lot of posts in this site finally I decide to put mine.
I am preparing an MSI file with Wix.
I need to check if a particular version of an enterprise product is installed, before to install my system. I have the GUID of that product (which is the same for all versions), but I need to check if 1.10.0 version is installed.
Any idea, please.
Thanks in advance.
PD: I am newbie in Wix, so at this moment I am just using the wxs file created by default with the Setup Project.
Clarifying: I don't want to upgrade the software that I am installing, I need to check another program and version which my installer depends.
To do it properly, you probably want to use a custom action. Inside the custom action, use the MsiGetProductInfo function.
A way of doing it in pure-WiX would be to modify the example found here: How do I compare registry versions in WiX?
First create a RegistrySearch element:
<Property Id="PRODUCTVERSION">
<RegistrySearch Id="ProductVersionSearch" Root="HKLM" Key="software\Microsoft\Windows\Current Version\Uninstall\[PRODUCTCODE]" Name="DisplayVersion" Type="raw" />
</Property>
Then use a Condition element:
<Condition Message="Product version 1.10.0 must be installed">
<![CDATA[PRODUCTVERSION AND PRODUCTVERSION = "1.10.0"]]>
</Condition>
This would search for exactly version 1.10.0, so may not be what you want if you're looking for something like "v1.10.0 or newer"... But should get you started.
Perhaps try the proposed solution in this post: WiX Installer: getting version of the product being upgraded
It involves using the Upgrade table to identify the installed product, and a custom action using VBScript to determine the version.
If you want to do something like create an error message or fail the install if that version is present you can have multiple upgrade entries. Have one that has something like this, bad syntax...
<Property Id="VERSION110INSTALLED" Secure="yes" />
<Upgrade Id="YOUR_GUID">
<UpgradeVersion
Minimum="1.10.0" Maximum="1.10.0"
Property="VERSION110SINSTALLED"
IncludeMinimum="yes" IncludeMaximum="yes" OnlyDetect="yes" />
</Upgrade>
Then you have that property set if version 1.10.0 is present, and if you want to produce an error message condition it on VERSION110SINSTALLED, and sequence it after FindRelatedProducts.