Unable to read value with RegistrySearch - wix

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

Related

Wix tools Ignore registry fail and continue

I need to insert a registry key in wix but the result is not important
how can I Ignore error.
sometimes because of permission reg creation fails
<Component Id="EXTEND_ADVANCE_TEXT_SERVICE" Guid="*">
<RegistryKey Root="HKLM" Key="SOFTWARE\Microsoft\CTF\SystemShared" Action="createAndRemoveOnUninstall">
<RegistryValue Type="integer" Name="CUAS" Value="1" KeyPath="yes"/>
</RegistryKey>
<Condition><![CDATA[VersionNT >= 501 AND VersionNT <= 502]]></Condition>
</Component>
The RegistryKey element does not have any error handling. Use a custom action and ignore the return code. There are plenty ways to do this, you can either author one in code or use a quiet execution custom action.

Windows Installer not deleting all files on uninstall

I've seen some similar questions asked on here, but none of the solutions given were very clear or worked for me.
I have an installer (created with WiX) which installs certain files and folders. However, when running the installed application, this creates some folders and copies some files into it. These files and folders are not removed on uninstall.
Edited to Show Code so Far:
This INSTALLDIR property:
<Property Id="INSTALLDIR">
<RegistrySearch Id='Registry' Type='raw' Root='HKLM' Key='Software\$(var.Manufacturer)\$(var.ProductName)' Name='Location' />
</Property>
This Component which should set the install location in the registry:
<Component Id="Registry" Guid="*">
<RegistryKey Root="HKMU" Key="Software\$(var.Manufacturer)\$(var.ProductName)">
<RegistryValue Name="Location"
Type="string"
Value="[INSTALLDIR]"
Action="write"
KeyPath="yes" />
</RegistryKey>
<util:RemoveFolderEx On="uninstall" Property="INSTALLDIR" />
</Component>
This does create a record in the registry with the install location, but I'm not sure how to adapt this code to making note of the 'public' directory and removing it - I don't know where the util:RemoveFolderEx should go either (inside which component)
The clearest tutorial I've seen is this one (except that it does have an apparent error).
Replace this block:
<!--
RemoveFolderEx requires that we "remember" the path for uninstall.
Read the path value and set the APPLICATIONFOLDER property with the value.
-->
<Property Id="APPLICATIONFOLDER">
<RegistrySearch Key="SOFTWARE\$(var.Manufacturer)\$(var.SkuName)" Root="HKLM" Type="raw" Id="APPLICATIONFOLDER_REGSEARCH" Name="Path" />
</Property>
with this one:
<!--
RemoveFolderEx requires that we "remember" the path for uninstall.
Read the path value and set the FOLDERTOREMOVE property with the value.
-->
<Property Id="FOLDERTOREMOVE">
<RegistrySearch Key="SOFTWARE\$(var.Manufacturer)\$(var.SkuName)" Root="HKLM" Type="raw" Id="APPLICATIONFOLDER_REGSEARCH" Name="Path" />
</Property>
and this block:
<util:RemoveFolderEx On="uninstall" Property="APPLICATIONFOLDER" />
with this one:
<util:RemoveFolderEx On="uninstall" Property="FOLDERTOREMOVE" />
and you should have a working test.
The reason for using two different properties is given here and here (among with other places).
If you can derive the path from other values you may have set during installation that Windows Installer will preserve for you, such as ARPINSTALLLOCATION, then you can adjust the above implementation to get what you need without having to create your own registry keys.
Builds on B. Murri's answer:
Example: your application installs new files or folders in 'installdir/public'. These files aren't being deleted as they weren't added by the installer.
First, you need to create a registry value which will store where your public directory is installed. This is in case the user changes the install directory.
<!-- Note that the RegistryValue Value is being set to the 'public' directory ID -->
<DirectoryRef Id='INSTALLDIR'>
<Component Id="RemovePublicDir" Guid="your-guid-here">
<RegistryKey Root="HKCU" Key="Software\$(var.Manufacturer)\$(var.ProductName)">
<RegistryValue Name="Location"
Type="string"
Value="[PUBLIC]"
Action="write"
KeyPath="yes" />
</RegistryKey>
<CreateFolder Directory="PUBLIC"/>
<util:RemoveFolderEx Property="FINDPUBLICDIR" On="uninstall"/>
<RemoveFolder Id="PUBLIC" On="uninstall"/>
</Component>
</DirectoryRef>
You now need to add a property which will search for this registry value later on. Make sure your Root value above matches the one below:
<Property Id="FINDPUBLICDIR">
<RegistrySearch Id='Registry' Type='raw' Root='HKCU' Key='Software\$(var.Manufacturer)\$(var.ProductName)' Name='Location' />
</Property>
Add your manufacturer name and product name to variables, like this:
<?define Manufacturer = "My Company"?>
<?define ProductName = "Test Application"?>
Now make sure you call this Component in your Feature tag:
<Feature Id="FeatureId">
<ComponentRef Id="RemovePublicDir" />
</Feature>

How can I record a 32-bit key in the registry on a 64-bit machine using WiX?

I have this key:
<Package
InstallerVersion="200"
Compressed="yes"
SummaryCodepage="1251"
Platform="x64"
InstallScope="perMachine"/>
<Component Id="RegistryEntries1" Guid="*">
<RegistryKey Root="HKLM"
Key="Software\SolidWorks\Addins\{GUID-PLACEHOLDER}"
Action="createAndRemoveOnUninstall">
<RegistryValue Type="integer" Value="0"/>
<RegistryValue Name="Description" Value="SomeText" Type="string"/>
<RegistryValue Name="Title" Value="ProductName" Type="string"/>
</RegistryKey>
</Component>
This key needs to be written in the 32-bit registry section, even if the Windows edition is 64-bit. How can I do this?
As #PhilDW correctly pointed out, your installation package platform is targeting the x64 but your registry key is being created in the Wow6432Node. This node is a source of confusion for me, so here is its definition:
The Wow6432Node registry entry indicates that you are running a 64-bit Windows version. The operating system uses this key to display a separate view of HKEY_LOCAL_MACHINE\SOFTWARE for 32-bit applications that run on 64-bit Windows versions.
Since the registry key is being created in the HKLM\SOFTWARE\Wow6432Node\SolidWorks\Addins\, it means it's 32-bit. If you want to explicitly create it for 64-bit, add the Win64="yes" attribute to the Component.
<Component Id="RegistryEntries1" Guid="*" Win64="yes">
<RegistryKey Root="HKLM"
Key="Software\SolidWorks\Addins\{GUID-PLACEHOLDER}"
Action="createAndRemoveOnUninstall">
...
</RegistryKey>
</Component>

Wix - Get user input to create a registry entry

I need to create an installer that gets the user input to create a registry entry. I've looked into Wix tutorials and it's very clear how to install registry entries but I need the user to give some info(in this case it's an url) so that url can be used on the registry entry.
How can I do this?
Duplicate question!?
Please take a look at this answer if it helps: https://stackoverflow.com/a/20679626/1331719
Edit - slightly modifying the answer found in the link:
Start by adding this component, notice the property in Value [USERINPUT]
<DirectoryRef Id="INSTALLDIR">
<Component Id="RegistryEntries" Guid="{YOURGUID}">
<RegistryKey Root="HKLM" Key="Software\Company123\App123" Action="create">
<RegistryValue Type="string" Name="UserInput" Value="[USERINPUT]" />
</RegistryKey>
</Component>
</DirectoryRef>
Reference the component in your feature:
<Feature>
<ComponentRef Id="RegistryEntries" />
...
</Feature>
Get user input when you install using msiexec:
msiexec /i your.msi /qb+ USERINPUT="http://urlYouWantToStoreIn.Registry"
Check registry HKLM\Software\Company123\App123\UserInput, the url should be there.

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>