How to write production version to registry - wix

I want to write the installed version to registry using WiX. Here is the WiX code of mine:
<Product Id="B20795DC-5462-4DE6-B629-8C034D114D3C" Name="ProductName" Language="1033" Version="1.1.3" Manufacturer="Corp" UpgradeCode="8f5c57ff-71fe-4fc6-9400-9bbbb76b4262">
....
<Component Id="ProgramRegistry">
<RegistryKey Id="RegInstallDir" Root="HKLM" Key="Software\[Manufacturer]\[ProductName]" Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Name="InstallVersion" Value="[Version]"/>
</RegistryKey>
</Component>
It creates a key named "InstallVersion" but the value is empty.
My question is how to write the product version into registry, the expected value should be the same as the version attribute in <Product> tag. (1.1.3)

The ProductVersion property contains the value you're looking for.

You can use ProductVersion property, the way #Stephen suggests. Alternatively, you can use the following approach:
define the version in a WiX variable
reference this variable in both Product element and RegistryValue element
set the product version in your build script and pass it to WiX compiler
Hence, your sample might look like this:
<Product Id="B20795DC-5462-4DE6-B629-8C034D114D3C" Name="ProductName" Language="1033" Version="$(var.Version)" Manufacturer="Corp" UpgradeCode="8f5c57ff-71fe-4fc6-9400-9bbbb76b4262">
....
<Component Id="ProgramRegistry">
<RegistryKey Id="RegInstallDir" Root="HKLM" Key="Software\[Manufacturer]\[ProductName]" Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Name="InstallVersion" Value="$(var.Version)"/>
</RegistryKey>
</Component>
</Product>
And somewhere in the build script (let's pretend, it is NAnt):
<candle out="${build.fodler}" rebuild="true" extensions="${build.extensions}" exedir="${wxs.dir}">
<defines>
...
<define name="Version" value="1.1.3" />
...
</defines>
<sources basedir="${paths.wxs}">
<include name="**.wxs"/>
</sources>
</candle>

Related

Remove folder in roaming using wix3.10 installer

When uninstalling my application, I'd like to delete a folder that was added by the application.It seems like the uninstaller removes only the directories and files that were originally installed from the MSI file. How do I delete application created folder?
Following the instructions on this link:
use WixUtil extensions:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
>
then read the Folder path previously stored in the registry:
<Property Id="APPLICATIONFOLDER">
<RegistrySearch Key="SOFTWARE\$(var.Manufacturer)\$(var.SkuName)" Root="HKLM" Type="raw" Id="APPLICATIONFOLDER_REGSEARCH" Name="Path" />
</Property>
Make sure the following component is included in you installer scripts:
<DirectoryRef Id="APPLICATIONFOLDER">
<Component Id="CleanupMainApplicationFolder" Guid="*">
<RegistryValue Root="HKLM" Key="SOFTWARE\$(var.Manufacturer)\$(var.SkuName)" Name="Path" Type="string" Value="[APPLICATIONFOLDER]" KeyPath="yes" />
<!-- We need to use APPLICATIONFOLDER variable here or RemoveFolderEx
will not remove on "install". -->
<util:RemoveFolderEx On="uninstall" Property="APPLICATIONFOLDER" />
</Component>
</DirectoryRef>
Use the WiXUtil extension when you call both candle and light: -ext WixUtilExtension

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>

Bind FileVersion to property in WiX

As for binding the AssemblyVersion of a specific DLL to WiX File Version, is basically easy:
<Product Id="*"
Name="My Application"
Language="1033"
Version="!(bind.FileVersion.MyDll.dll)"
Manufacturer="My Company"
UpgradeCode="E7A0C56F-160B-4C67-9AAC-2FF69630EAF9">
Is there any way that the same can be achieved with Properties in WiX. Like this:
<Property Id="VERSION">
<![CDATA[!(bind.FileVersion.MyDll.dll)]]>
</Property>
I need to update an XML file during installation, with the same version number as the one in the specific DLL. Any suggestions?
You should have a look at the XmlFile Element. It allows you to set values/attributes:
<Component Id="webconfig" Guid="PUT-YOUR-GUID-HERE" NeverOverwrite="yes" Win64="yes">
<File Id="web.config" Source="$(var.bind.ProjectDir)\web.config" KeyPath="yes" />
<util:XmlFile Id="web.config.VersionInfo" File="[#web.config]" Action="setValue" PreserveModifiedDate="yes" ElementPath="//configuration/appSettings/add[\[]#key='VersionInfo'[\]]" Name="value" Value="[VERSION]" Sequence="1" />
</Component>

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>

How to write Product Id in registry in wix

My requirement is blow.
I need to write the Product Id in registry while install the setup.
I have the below code for Product Id.
<Product Id="{CEEE7807-F6D7-43F6-A206-110B9E25AC9C}"
Name="Sample installer"
UpgradeCode="{BFBD4770-8C5D-4A53-BA07-EF52401F0CB4}"
Language="1033"
Version="$(var.ProductVersion)"
Manufacturer="My company.">
I have below code for write Registry. I want to pass the product Id value here.
<Component Id="registry_values" Guid="{11FB6C4C-3C90-4F46-B0D2-BB95150F60E6}">
<RegistryValue
KeyPath="yes"
Root="HKCU"
Key="Software\MyProduct\Myfolder\SampleFolder\Product"
Value="[Product Id]"
Type="string" />
</Component>
Please help me to solve this problem.
Somewhat confusingly, the Id attribute of the WIX Product element maps to the Windows Installer ProductCode property.
<Component Id="registry_values" Guid="{11FB6C4C-3C90-4F46-B0D2-BB95150F60E6}">
<RegistryValue
KeyPath="yes"
Root="HKCU"
Key="Software\MyProduct\Myfolder\SampleFolder\Product"
Value="[ProductCode]"
Type="string" />
</Component>