Wix - How do I set property conditionally - wix

I'm trying to do is:
if registrySearch exist then
set INSTALL_DIR to C:\Program Files\MyCompany\MySoftware
else
set INSTALL_DIR to C:\ProgramData\MyCompany\Folder
Anyone know to do this?

Let say this the registry key you searched.
<Property Id="REGSEARCH">
<RegistrySearch Id="TestReg"
Root="HKLM"
Key="Software\TestKey\TestKey2"
Name="Test"
Type="raw" />
</Property>
This is how to set the property conditionally.
Keep the default value as the value you need to put when the registry does not exist.
<Property Id="INSTALL_DIR" Value="C:\ProgramData\MyCompany\Folder" />
Then set the property value as follows if the registry exists.
<SetProperty Id="INSTALL_DIR" After="AppSearch" Value="C:\Program Files\MyCompany\MySoftware" Sequence="first" >
<![CDATA[REGSEARCH]]>
</SetProperty>

Related

Check file version from file full path

I need to check service executable version before proceed my installation.
I have read full path for registered service, from registry:
<Property Id="SOME_SERVICE_PATH">
<RegistrySearch Id="FindServicePath" Type="raw" Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\TARGET_SERVICE" Name="ImagePath" />
</Property>
After that I tried to perform file search like below:
<Property Id="TARGET_SERVICE_UNSUPPORTED">
<DirectorySearch Id="ServiceParticularVersionSearch" Path="[SOME_SERVICE_PATH]">
<FileSearch Name="Service.exe" MaxVersion="2.5.0.1" />
</DirectorySearch>
</Property>
And this not ganed me results.
I suppose the problem is in the value I passed to DirectorySearch Path property.
According to the Wix documentaion Path should be initialized with
"Path on the user's system. Either absolute, or relative to containing directories"
Unfortunately, there is no place in the registry I can read service installation directory. This is 3d party component.
Are there any solutions here? important moment - Its forbidden to use custom actions in our project
As it turned out, the answer was in Type parameter of RegistrySearch element. If I assign "file" to it, I will be able to apply FileSearch on path I read and check executable version.
Another solution here is to use remark from RegistrySearch Element documentation
file
The registry value contains the path to a file. To return the full file path you must add a FileSearch element as a child of this element; otherwise, the parent directory of the file path is returned.
I mean "otherwise, the parent directory of the file path is returned"
Solution 1
<Property Id="TARGET_SERVICE_UNSUPPORTED">
<RegistrySearch Id="FindServicePath" Type="file" Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\TARGET_SERVICE" Name="ImagePath" />
<FileSearch Name="Service.exe" MaxVersion="2.5.0.1" />
</DirectorySearch>
</Property>
Solution 2
<Property Id="SOME_SERVICE_PATH">
<RegistrySearch Id="FindServicePath" Type="file" Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\TARGET_SERVICE" Name="ImagePath" />
</Property>
<Property Id="TARGET_SERVICE_UNSUPPORTED">
<DirectorySearch Id="ServiceParticularVersionSearch" Path="[SOME_SERVICE_PATH]">
<FileSearch Name="Service.exe" MaxVersion="2.5.0.1" />
</DirectorySearch>
</Property>

WixUI_InstallDir and ARPNOREPAIR / ARPNOMODIFY properties

I would like to delete repair / modify buttons from Add or Remove Programs.
I would also like to use WixUI_InstallDir Dialog Set.
This is my code:
<UI>
<UIRef Id="WixUI_InstallDir"/>
</UI>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR"/>
<Property Id="ARPNOREPAIR" Value="yes" Secure="yes" />
<Property Id="ARPNOMODIFY" Value="yes" Secure="yes" />
But this causes
error LGHT0091 : Duplicate symbol 'Property:ARPNOMODIFY' found
I understand that WixUI_InstallDir defines these properties and the only decision I see is to define my own UI that is similar to WixUI_InstallDir except for these properties.
But is this the only way?
Can I overwrite these properties somehow?
Yes, use setproperty.
<SetProperty Id="ARPNOMODIFY" Value="1" After="InstallValidate" Sequence="execute"/>

Conditional property in wix script

I used the below property so i could avoid the add or remove option in the control panel
<Property Id="ARPSYSTEMCOMPONENT" Value="1" />
But i need to make it dynamic .I want to read the value in the registry. If a value mathes my condition i will include this orelse i wont include this line my partial code is as follows
<Property Id="NETFRAMEWORK20">
<RegistrySearch Id="NetFramework20"
Root="HKLM"
Key="Software\Microsoft\NET Framework Setup\NDP\v2.0.50727"
Name="Install"
Type="raw" />
</Property>
//Some Conditon
<Condition Message="I will create the Add or remove option since the softwar i look for s not present">
<![CDATA[Installed OR NETFRAMEWORK20]]>
</Condition>
<Property Id="ARPSYSTEMCOMPONENT" Value="1" />
//or else
Thank in Advance
Try using SetProperty. Means, instead of:
<Property Id="ARPSYSTEMCOMPONENT" Value="1" />
try:
<SetProperty Id="ARPSYSTEMCOMPONENT" After="InstallInitialize" Value="1">
<![CDATA[~~~CONDITION~~~]]>
</SetProperty>
As a side note, I would recommend first, not to hide staff you install from add/remove, and second, use standard .NET framework extension for checking if .NET framework is installed instead of inventing your own method with registry search.

WiX - How do I get different registry keys for allusers and single user

My program will be installed to a path in registry, which has two different values for single user and all users.
So I'd like to have something like:
<Property Id="MYINSTALLDIR">
if single user, then <RegistrySearch Id='MyRegistry' Type='raw' Root='HKCU' Key='Software\MyApp\Foo' Name='InstallDir' />
else if ALLUSERS, then <RegistrySearch Id='MyRegistry' Type='raw' Root='HKLM' Key='Software\MyApp\Foo' Name='InstallDir' />
</Property>
Is this possible?
Perform the two registry searches to two different properties and then use a SetProperty custom action to assign one of the two properties to the real property based on which one has data and which one has a higher priority ( use conditions to drive the execution ).
Finally, it is working now...
With following snippet in wxs file, ALLUSER=1 or 2 can be passed to msiexec to enable HKLM registry search.
<Property Id="INSTALLDIR1">
<RegistrySearch Id='RegistryCU' Type='raw' Root='HKCU' Key='Software\Foo' Name='InstallDir' />
</Property>
<Property Id="INSTALLDIR2">
<RegistrySearch Id='RegistryLM' Type='raw' Root='HKLM' Key='Software\Foo' Name='InstallDir' />
</Property>
<CustomAction Id="PerUserInstall" Property="InstallDir" Value="[INSTALLDIR1]" Execute="immediate" />
<CustomAction Id="PerMachineInstall" Property="InstallDir" Value="[INSTALLDIR2]" Execute="immediate" />
<InstallExecuteSequence>
<Custom Action="PerUserInstall" After="AppSearch">ALLUSERS="" OR (ALLUSERS=2 AND (NOT Privileged))</Custom>
<Custom Action="PerMachineInstall" After="AppSearch">ALLUSERS=1 OR (ALLUSERS=2 AND Privileged)</Custom>
</InstallExecuteSequence>
In my case, both HKCU and HKLM contain values and they have same priority, so the only way to do is to set property of ALLUSER in command line.

Wix CopyFile only on target machine

I need to be able to copy a file that exists on the target machines hard-drive based on a registry setting that holds the folder path.
I have been trying to get this going for a day or two and am having difficulty, can anyone help?
Thanks,
B
Try something along these lines:
<Component Id="MyComponent" Guid="E5FF53DE-1739-42c4-BE37-60F810C9CD69">
<Condition>MYTESTDIR</Condition>
<CopyFile Id="fileToCopy.datCopy" SourceName="[MYTESTDIR]fileToCopy.dat" DestinationProperty="WEBSERVICEBINFOLDER" />
</Component>
You can populate MYTESTDIR with a value from the registry using a RegistrySearch.
You can first search your registry for the file as follows:
<Property Id="PROPERTYNAME" Secure="yes">
<RegistrySearch Id="SomeID"
Root="HKLM"
Type="raw"
Key="SOFTWARE\SomeFolder\SomeSubFolder"
Win64="yes"
Name="InstallPath">
<DirectorySearch Id="REQUIREDDIRECTORY" AssignToProperty="yes" Depth="1" Path="THEEXPECTEDPATH">
</DirectorySearch>
</RegistrySearch>
</Property>
Then use a Custom Action to set the file name
<CustomAction Id="SETFILE"
Property="FILE"
Value="[PROPERTYNAME]file.extension" />
and then copy file as described by the previous answer...
<CopyFile Id="fileToCopy.datCopy" SourceName="[FILE]" DestinationProperty="[YOURDESTINATION]" />