!-- OR Detect existing version of VC ++ 2015-2019 x64 libraries -->
<util:RegistrySearch Root="HKLM" Id="GetVC14X64Exists" Key="SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" Result="exists" Variable="vc14x64Exists" Win64="yes"/>
<util:RegistrySearch Root="HKLM" Id="GetVC14X64Version" Key="SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" Result="version" Variable="vc14x64Version" Win64="yes" /
<util:RegistrySearch Root="HKLM" Id="GetVC14X86onX64Exists" Key="SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" Result="exists" Variable="vc14x86onx64Exists" Win64="yes"/>
<util:RegistrySearch Root="HKLM" Id="GetVC14X86onX64Version" Key="SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" Result="version" Variable="vc14x86onx64Version" Win64="yes" Format="raw" />
<util:RegistrySearch Root="HKLM" Id="GetVC14X86onX86Exists" Key="SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" Result="exists" Variable="vc14x86onx86Exists" Win64="no"/>
<util:RegistrySearch Root="HKLM" Id="GetVC14X86onX86Version" Key="SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" Result="version" Variable="vc14x86onx86Version" Win64="no"/>
Always DetectCondition fails for equal versions Anybody suggests here?
Related
Note that I'm not asking for a registry value. Just the key. How do I do that with WiX?
The following doesn't work when HKLM\SOFTWARE\Microsoft\VSTO Runtime Setup\v4 key exists:
<Property Id="VSTOINST1">
<RegistrySearch Id="idVsto1" Root="HKLM" Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4" Type="directory" />
</Property>
<Condition Message="Visual Studio 2010 Tools for Office Runtime is not installed. You can get it from: https://www.microsoft.com/en-us/download/details.aspx?id=56961">
<![CDATA[Installed OR (VSTOINST1)]]>
</Condition>
PS. For clarity I'm testing it on a 32-bit Windows OS.
I create it in this way:
<Directory Id="TARGETDIR" Name="SourceDir">
...
<ComponentGroup Id="REGISTRYENTRIES" Directory="INSTALLFOLDER">
<Component Id="Registry" Guid="..." >
<RegistryKey Root="HKLM" Key="Software\...\..." Action="createAndRemoveOnUninstall">
<RegistryValue Name="Version" Value="[BuildVersioProp]" Type="string" />
<RegistryValue Name="InstallSource" Value="[PATH]" Type="string" />
<RegistryValue Name="Publisher" Value="Comapny" Type="string" />
</RegistryKey >
</Component>
</ComponentGroup>
Product:
<Product>
...
<Feature Id="ProductFeature4" Title="CCC" Level="1" >
<ComponentGroupRef Id="REGISTRYENTRIES" />
</Feature>
</Product>
and add to property:
<Property Id="PATH">
<RegistrySearch Id='my_app_dir' Type='raw' Root='HKLM' Key='SOFTWARE\WOW6432Node\...\...' Name='InstallSource' />
</Property>
In the released MSI, I had the hard-coded port number, e.g.
<Property Id="HTTP_PORT1" Secure="yes" Value="1000" />
<Component Id="my.exe" Guid="*" Win64="yes" >
<File Id="my.exe" KeyPath="yes" Source="my.exe" />
<RegistryValue Root="HKLM" Key="SOFTWARE\MyCompany" Name="Port1" Value="[HTTP_PORT1]" Type="integer" />
<RegistryValue Root="HKLM" Key="SOFTWARE\MyCompany" Name="Port2" Value="9000" Type="integer" />
</Component>
And for the patch, my Patch.wxs looked like this:
<PatchFamily Id="Rollup" Version="1.0.100" Supersede="yes">
<ComponentRef Id="my.exe"/>
</PatchFamily>
When I manually change those regs to "1111" and "9999" and applied the patch MSP, those Port1 and Port2 were set back to "1000" and "9000" respectively. So I changed "HTTP_PORT1" and added "INT_HTTP_PORT2" like this:
<Property Id="HTTP_PORT1" Secure="yes" Value="#1000" >
<RegistrySearch Root="HKLM" Key="SOFTWARE\MyCompany" Name="Port1" Type="raw" Win64="yes" />
</Property>
<Property Id="INT_HTTP_PORT2" Secure="yes" Value="#9000" >
<RegistrySearch Root="HKLM" Key="SOFTWARE\MyCompany" Name="Port2" Type="raw" Win64="yes" />
</Property>
<Component Id="my.exe" Guid="*" Win64="yes" >
<File Id="my.exe" KeyPath="yes" Source="my.exe" />
<RegistryValue Root="HKLM" Key="SOFTWARE\MyCompany" Name="Port1" Value="[HTTP_PORT1]" Type="string" />
<RegistryValue Root="HKLM" Key="SOFTWARE\MyCompany" Name="Port2" Value="[INT_HTTP_PORT2]" Type="string" />
</Component>
And I changed Patch.wxs like this:
<PatchFamily Id="Rollup" Version="1.0.100" Supersede="yes">
<ComponentRef Id="my.exe"/>
<PropertyRef Id="HTTP_PORT1"/>
<PropertyRef Id="INT_HTTP_PORT2"/>
</PatchFamily>
However, both Port1 and Port2 are changed back to the original values (although Port1 is now REG_SZ.)
Is this an expected behavior? Is it possible to make it work in the patch without using Type1 custom action?
The executable in that component is the keypath item. I'd verify that you increased the version of that exe because it effectively controls whether that component is updated. You could create a verbose log of the patch install to see exactly what's going on.
What you need to look for in the verbose log is what it says about my.exe, whether it's Overwrite or something else. Also, note that if the component rules were broken in the patch it will effectively result in nothing being patched. You will see SELMGR in the log if that's the case.
Similar questions to this one have been asked before but I believe that things have changed with Windows 8 so that this is not a duplicate.
Method 1
What looks like the best windows desktop documentation suggests that a program uses OpenWithProgids. Although some MSDN documentation reports this registry key is only supported in Windows XP, other documentation indicates it is somehow used with the Windows Store, introduced with Windows 8. Just looking on my computer, most programs still use this registry key, so I plan to add it rather than only be confused by the documentation.
Method 2
In the Application Registration section of the window desktop documentation the suggested method for adding a program to the “Open With” context menu is using a SupportedTypes registry key.
Summary
Both methods work on Windows 7, but neither seems to be working on Windows 8.
Some may suggest trying out the “Default Programs” interface but, although it’s a good idea anyway, the documentation on it generally points you elsewhere for getting on the “Open With” menu. I would generally expect an application to be and stay on the “Open With” menu regardless of whether it is currently the default program.
Still, staying on the Default Programs topic, in this thread someone “stumbled” into a solution where setting a program as the default once added it to the “Open With” menu. I unfortunately do not get the same behavior on my system, with my file extensions.
<Component Id="ConsoleApplication" Guid="*">
<File Id="ConsoleApplication.exe" Name='ConsoleApplication.exe' DiskId='1'
Source='$(var.ConsoleApplication.TargetDir)/ConsoleApplication.exe'
KeyPath='yes' />
<!-- ProgID (always required) -->
<RegistryValue Root="HKLM"
Key="SOFTWARE\Classes\ConsoleApplication.MyProgId"
Name="FriendlyTypeName"
Value="ConsoleApplication ProgID"
Type="string" />
<ProgId Id="ConsoleApplication.MyProgId"
Description="ConsoleApplication MyProgId"
Advertise="yes">
<Extension Id="xyz">
<Verb Id="open"
Command="Open"
Argument=""%1""/>
</Extension>
</ProgId>
<!-- Method 1: Add to the "Open With" menu using a ProgID -->
<RegistryValue Root="HKLM"
Key="SOFTWARE\Classes\.xyz\OpenWithProgids"
Name="ConsoleApplication.MyProgId"
Value=""
Type="string" />
<!-- Method 2: Add to the "Open With" menu using "Application Registration" -->
<RegistryValue Root="HKLM"
Key="SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\ConsoleApplication.exe"
Value="[!ConsoleApplication.exe]"
Type="string" />
<RegistryValue Root="HKLM"
Key="SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\ConsoleApplication.exe"
Name="Path"
Value="[INSTALLFOLDER]"
Type="string" />
<RegistryValue Root="HKLM"
Key="SOFTWARE\Classes\Applications\ConsoleApplication.exe\SupportedTypes"
Name=".xyz"
Value=""
Type="string" />
<RegistryValue Root="HKLM"
Key="SOFTWARE\Classes\Applications\ConsoleApplication.exe\shell\open"
Name="FriendlyAppName"
Value="My FriendlyAppName"
Type="string" />
<!-- "Default Programs" registration -->
<RegistryValue Root="HKLM"
Key="SOFTWARE\ConsoleApplication\Capabilities"
Name="ApplicationDescription"
Value="Console application."
Type="string" />
<RegistryValue Root="HKLM"
Key="SOFTWARE\ConsoleApplication\Capabilities"
Name="ApplicationIcon"
Value="[INSTALLFOLDER]ConsoleApplication.exe,0"
Type="string" />
<RegistryValue Root="HKLM"
Key="SOFTWARE\ConsoleApplication\Capabilities"
Name="ApplicationName"
Value="ConsoleApplication"
Type="string" />
<RegistryValue Root="HKLM"
Key="SOFTWARE\ConsoleApplication\Capabilities\DefaultIcon"
Value="[INSTALLFOLDER]ConsoleApplication.exe,0"
Type="string" />
<RegistryValue Root="HKLM"
Key="SOFTWARE\ConsoleApplication\Capabilities\FileAssociations"
Name=".xyz"
Value="ConsoleApplication.MyProgId"
Type="string" />
<RegistryValue Root="HKLM"
Key="SOFTWARE\ConsoleApplication\Capabilities\shell\open\command"
Value=""[INSTALLFOLDER]ConsoleApplication.exe" "%1""
Type="string" />
<RegistryValue Root="HKLM"
Key="SOFTWARE\RegisteredApplications"
Name="ConsoleApplication"
Value="SOFTWARE\ConsoleApplication\Capabilities"
Type="string" />
</Component>
Read this:
https://superuser.com/questions/690106/add-items-to-the-open-with-list-in-windows-8
This is apparently new in Win 8, but unless you provide the two properties, the application does not appear on the menu.
The below component does everything as expected, but fails to write the last registry key value. I get no errors.
<Component Id="ProgramMenuDir" Guid="68977683-3F36-45EF-9FF4-7B9461A42D06">
<RemoveFolder Id="ProgramMenuDir" On="uninstall" />
<RegistryKey Root="HKLM" Key="Software\Wow6432Node\[Manufacturer]\[ProductName]" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
<RegistryValue Type="string" Name="APIUrl" Value="http://api.blah/" KeyPath="yes" />
<RegistryValue Type="string" Name="Token" Value="blah" />
</RegistryKey>
<RegistryKey Root="HKLM" Key="Software\Wow6432Node\[Manufacturer]\[ProductName]\Tokens" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes" />
<RegistryKey Root="HKLM" Key="Software\Wow6432Node\[Manufacturer]\[ProductName]\Tokens\WOvN+Lac+d3wRtY0uBUsAeHTYg4x7j2/NWpftWv/16qaOz3J6TpDQmvjUpQmoCWPSFdMpbrcpi4rJd56aBKkkvSR54RsS5xueaYfPgk1QmQ=" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes" />
<RegistryValue Root="HKLM" Action="write" Key="Software\Microsoft\Windows\CurrentVersion\Run" Name="[ProductName]" Value="blah" Type="string" />
</Component>
Why no write, yet no errors?
Are you just looking in the wrong place, if this is a 32 bit installer then you need to check the following location - HKLM\Software\Wow6432Node\Microsoft
Remember that these are the equivalent nodes depending on your install architecture:
32bit installer on 64bit machine:
HKLM\Software\Wow6432Node\Microsoft
32bit installer on 32bit machine or 64bit installer on 64bit machine:
HKLM\Software\Microsoft
I have some ExecPackages chained in my bundle.wxs. I have a PackageGroup section for installing .Net Framework 4.0. This has been hooked in the beginning of the chain as a PackageGroupRef.
When I double click on the bootstrapper, a .Net framework installation window pops up which installs .Net Fwk. After the installation of .Net, I would expect the bootstrapper to display the managed UI and continue with the actual installation activities.
But, the issue is that it just stops after the .Net framework installation. I have to execute the bootstrapper a second time for the UI to pop up and resume the installation. The bundle.wxs content goes like this:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Bundle Name="My-Installer"
Version="3.0"
Manufacturer="XXXX"
HelpUrl="XXXX"
UpdateUrl="XXXX"
UpgradeCode="XXXX">
<!--Compressed="no"-->
<!--Custom dialog is a WPF form-->
<BootstrapperApplicationRef Id='ManagedBootstrapperApplicationHost'>
<Payload Name='BootstrapperCore.config' SourceFile='..\MyBootstrapperCustomUI\MyBootstrapperCustomUI\MyBootstrapperCustomUI.BootstrapperCore.config' />
<Payload SourceFile='..\MyBootstrapperCustomUI\MyBootstrapperCustomUI\bin\$(var.Configuration)\MyBootstrapperCustomUI.dll' />
</BootstrapperApplicationRef>
<Chain>
<PackageGroupRef Id='Netfx4Full' />
<ExePackage Id="MyPackage1"..../>
<ExePackage Id="MyPackage2"..../>
</Chain>
<Fragment>
<WixVariable Id="WixMbaPrereqPackageId" Value="Netfx4Full" />
<WixVariable Id="WixMbaPrereqLicenseUrl" Value="NetfxLicense.rtf" />
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full" Value="Version" Variable="Netfx4FullVersion" />
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full" Value="Version" Variable="Netfx4x64FullVersion" Win64="yes" />
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v3.5" Value="Version" Variable="Netfx35Version"/>
<PackageGroup Id="Netfx4Full">
<ExePackage Id="Netfx35" Cache="no" Compressed="no" PerMachine="yes" Permanent="yes" Vital="yes" SourceFile="..\MyApp\dotNETFramework3.5SP1\dotnetfx35.exe" Name="MyApp\dotNETFramework3.5SP1\dotnetfx35.exe" DetectCondition="Netfx35Version AND (Netfx35Version >= v3.5.30729.1)" InstallCommand="/q /norestart" UninstallCommand="/q /norestart"
InstallCondition="(NOT Netfx35Version OR (Netfx35Version < v3.5.30729.1)) AND NOT VersionNT >= v6.0"/><!--donot install if win7-->
<ExePackage Id="Netfx4Full" Cache="no" Compressed="no" PerMachine="yes" Permanent="yes" Vital="yes" SourceFile="..\MyApp\dotNETFramework4.0\dotNetFx40_Full_x86_x64.exe" Name="MyApp\dotNETFramework4.0\dotNetFx40_Full_x86_x64.exe" InstallCommand="/passive /norestart" DetectCondition="Netfx4FullVersion AND (NOT VersionNT64 OR Netfx4x64FullVersion)" />
</PackageGroup>
</Fragment>
</Wix>
</Bundle>