WixUI_InstallDir and ARPNOREPAIR / ARPNOMODIFY properties - wix

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"/>

Related

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 set property conditionally

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>

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>

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]" />