Create registry entry but not delete it - wix

Working on something for Server2012 (Win8) and it's communicating with a website that uses TLS 1.2. So, for those OSes I need to add TLS 1.2 protocols since Server 2012 doesn't support on a default install. I know how to do that. I know how to not do it for a version less than Windows 10 and not doing it if it's already been enabled. The big question is:
Is there a way not using Custom Actions to create the registry entry but not delete it afterward? I'm concerned about another program maybe needing it.
For instance,
<Property Id="WIN10FOUND">
<DirectorySearch Id="searchSystem" Path="[SystemFolder]" Depth="0">
<FileSearch Id="searchFile" Name="advapi32.dll" MinVersion="6.3.10000.0"/>
</DirectorySearch>
</Property>
<Property Id="TLS12CLIENTFOUND">
<RegistrySearch Id="SearchTLS12Client" Root="HKLM" Key="SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" Name="Enabled" Type="raw"/>
</Property>
Later on in a feature,
<!-- For Server2012 add necessary registry entries to support TLS 1.2 -->
<Component Location="local" Id="Win8TLS12Registry" Guid="00000000-1111-2222-3333-123456789ABC">
<Condition><![CDATA[not WIN10FOUND and ((not TLS12CLIENTFOUND) or (TLS12CLIENTFOUND="#0"))]]></Condition>
<RegistryKey Root="HKLM" Key="SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" ForceCreateOnInstall="no">
<RegistryValue Name="DisabledByDefault" Type="integer" Value="0"/>
<RegistryValue Name="Enabled" Type="integer" Value="1"/>
</RegistryKey>
</Component>
If some other installer comes along, and at least tries to create the key and value, as it stands now, I think an uninstall will cause this to delete the key and value.
I've tested what I have, and if the key /value exists and is non-zero, then it does not create/set it and uninstall leaves it untouched. However, if it did not exist beforehand (or was 0), then the key / value are deleted.
Is there a way to create the key/value if they don't exist, but not delete on uninstall short of a Custom Action?

Sure. Make the <Component Permanent="yes".

Related

Wix install location

I have a WIX setup that allows the user to select the install location. When uninstalling, I need to run a custom action that should activate a file in the install location. I tried getting the install location from session["INSTALLDIR"] but it results in the default path and not the one given by the user.
How can I reach that location?
I've done this in my own installer - the following should work.
This adds a property to retrieve the install location value from the registry.
<Property Id="INSTALLDIR">
<RegistrySearch Id='Registry' Type='raw' Root='HKCU' Key='Software\$(var.Manufacturer)\$(var.ProductName)' Name='Location' />
</Property>
This sets the install location in the registry.
<Component Id="Registry" Guid="*">
<RegistryKey Root="HKCU" Key="Software\$(var.Manufacturer)\$(var.ProductName)">
<RegistryValue Name="Location"
Type="string"
Value="[INSTALLDIR]"
Action="write"
KeyPath="yes" />
</RegistryKey>
<util:RemoveFolderEx On="uninstall" Property="INSTALLDIR" />
If you want INSTALLDIR for a later time such as uninstallation you should use Remember property pattern described in link below.
"The root issue is that the Windows Installer does not save Property values for you. That means if the user enters values in the install UI or passes them on the command-line, those values will be not be present during repair, upgrade nor uninstall."
http://robmensching.com/blog/posts/2010/5/2/the-wix-toolsets-remember-property-pattern/

Is it possible to read from 64 and 32-bit registry entries in the same installation?

In my installation I need to check presence of 64-bit entry at first.
And read its value if it is present in 64-bit part of registry.
If entry is absent then I need to try to read this entry from 32-bit registry part(Wow6432Node).
I need to read it directly from wxs file or from custom action on VBScript.
Is it possible to do?
If you're running a 64bit MSI you can set two AppSearch/RegLocator entries using the style:
<Property Id="MY_32BIT_REG">
<RegistrySearch Id="my32bitreg"
Root="HKLM"
Key="SOFTWARE\My Company"
Name="foo"
Type="raw"
Win64="no" />
</Property>
<Property Id="MY_64BIT_REG">
<RegistrySearch Id="my64bitreg"
Root="HKLM"
Key="SOFTWARE\My Company"
Name="foo"
Type="raw"
Win64="yes" />
</Property>
These entries will check the appropriate "HKLM\SOFTWARE\My Company" and "HKLM\SOFTWARE\Wow6432Node\My Company" registry hives.

Unable to read value with RegistrySearch

My installer need to distinguish between Intel and AMD processor manifacturer, in order to drop the corresponding components (Drivers). I've seen that is possible to catch such information from a registry key. I've done the following
<Property Id="REGMANIFACTURER">
<RegistrySearch Id="RegCPU"
Root="HKLM"
Key="HARDWARE\DESCRIPTION\System\ControlProcessor\0"
Name="VendorIdentifier"
Type="raw"
Win64="yes"
>
</RegistrySearch>
And after drop in such way (this is the AMD case for example)
<ComponentGroup Id="Xxxxxx" Directory="Yyyy">
<!--Catalog-->
<Component Id="xxx.cat" Guid="7d79a20a-2742-4d38-be85-35a60ac512f1" Win64="yes" >
<Condition>
<![CDATA[Installed OR (REGMANIFACTURER <> "GenuineIntel")]]>
</Condition>
<File Id="xxx.cat" Source="xxx\yyy\xxx.cat" KeyPath="yes" Checksum="yes" />
</Component>
From MSI install logs I can see an Error 1402 (Could not open key), could you please let me know where the error is, and/or how to achieve the goal?
Many thanks for your time!
You have a typo in your Key attribute: It should be
HARDWARE\DESCRIPTION\System\CentralProcessor\0

Using WiX, how to skip a component when a certain registry key does not exist?

I want to copy some files into a directory in another product's installation tree, but only if that product is installed. So I figured I could set a property based on a registry search to find that product's installation root. Then I could use the property in a condition element on the component element.
Here is my code. For some reason, I am getting an error when the other product is not installed and the registry search comes up empty since the registry key will not be found.
<Property Id="PRODUCTPATH">
<RegistrySearch Id="PRODUCTPATH" Root="HKLM" Key="_MY_KEY_" Name="_MY_NAME_" Type="raw" />
</Property>
<SetProperty Id="PRODUCTBINPATH" Value="[PRODUCTPATH]\BIN" After="AppSearch"/>
<Component Id="CommonDLLs" Guid="_MY_GUID_" Directory="INSTALLLOCATION">
<Condition>PRODUCTPATH</Condition>
<RegistryValue Id="_MY_ID_" Root="HKLM" Key="_MY_KEY_2" Name="Installed" Value="1" Type="integer" KeyPath="yes" />
<CopyFile Id="myfile1.dll" FileId="myfile1.dll" DestinationProperty="PRODUCTPATH" DestinationName="myfile1.dll"/>
<CopyFile Id="myfile2.dll" FileId="myfile2.dll" DestinationProperty="PRODUCTPATH" DestinationName="myfile2.dll"/>
</Component>
Try to use the util:RegistrySearch instead of RegistrySeach
This element comes with Util Extension. Check here if you don't know how to use extensions.
The util:RegistrySearch has an attribute (Result) for only checking if the key exists or not.
It would be like that:
<util:RegistrySearch
Id="PRODUCTPATH"
Variable="PRODUCTPATH"
Root="HKLM"
Key="_MY_KEY_"
Format="raw"
Result="exists">
Actually, all you have to do is add a condition to the SetProperty element like this:
<Property Id="PRODUCTPATH">
<SetProperty Id="PRODUCTBINPATH" Value="[PRODUCTPATH]\BIN" After="AppSearch">PRODUCTPATH</SetProperty>

Associate file type to external program in WiX

Is there a way to associate a file extension to an external program in my WiX setup?
For example, my application uses .xyz files, but I use a third party program to edit them, like Notepad++. I would include Notepad++ during the setup or bootstrap its installer. Is there a way to associate Notepad++ with my .xyz files using only WiX?
I've looked at the ProgId element, but I don't think it can do this.
Unfortunately, the strongly typed elements cannot be used to refer to an executable outside of the install today. However, you can write the registry keys yourself. Something like:
<RegistryValue Root="HKCR" Key=".xyz" Value="xyz-progid" Type="string" />
<RegistryKey Root="HCKR" Key="xyz-progid>
<RegistryValue Key="shell\Open\command" Value="[NOTEPADPLUSPLUSPATH]" Type="string" />
<RegistryValue Key="DefaultIcon" Value="[!NOTEPADPLUSPLUSPATH]" Type="string" />
</RegistryKey>
For this to work, you'll need to find Notepad++ on the machine. I'm not sure how to do that but let's say there was a registry key that told you:
<Property Id="NOTEPADPLUSPLUSPATH">
<RegistrySearch Id="FindNotepadPlusPlus" Root="HKLM" Key="Software\NotepadPlusPlus"
Name="InstallPath" Type="raw" />
</Property>