I'm trying to simulate the InstallURL property of a VS.net install MSI... I've got to the ponit where the WIX MSI will open a browser to the download page that I want it to go to. I thought things were going great because on my test machine, the web page opened when I didn't have the MSXML6 component installed. However things went downhill when I discovered that the web page opened even when I DID have the component installed.
I'm searching for the MSXML6 component using a Property w/ a RegistrySearch. However, as best as I can tell, the registry value isn't even being evaluated, and thus it "always" looks like it isn't installed.
Here's the relevant portion of my WXS:
<Property Id="MSXML6">
<RegistrySearch Id="MSXML6Search" Root="HKCR" Key="Msxml2.DOMDocument.6.0" Type="raw" />
</Property>
<Property Id="TEST">
<RegistrySearch Id="TESTSearch" Root="HKLM" Type="raw" Name="Version" Key="SOFTWARE\Microsoft\DirectX" />
</Property>
<Property Id="cmd.exe" Value="cmd.exe" />
<CustomAction Id="OpenMSXML6Download" Property="cmd.exe" ExeCommand="/c start http://www.microsoft.com/downloads/details.aspx?FamilyID=993c0bcf-3bcf-4009-be21-27e85e1857b1" Execute="immediate" Return="check" />
<CustomAction Id="OpenMSXML6DownloadError" Error="This component requires MSXML6. =[MSXML6]=[cmd.exe]=[TEST]= A web browser has been opened to the download page. Please install MSXML6 and then re-install the connector." />
<!-- installation execution sequence -->
<InstallExecuteSequence>
<!-- wires the error dialog to the downgrade event -->
<Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
<!-- execution to delete old install info after upgrade-->
<RemoveExistingProducts After="InstallValidate" />
<!-- Forces MSXML6 to be pre-installed -->
<!-- <Custom Action="OpenMSXML6Download" Before="FindRelatedProducts">NOT MSXML6</Custom> -->
<Custom Action="OpenMSXML6Download" Before="FindRelatedProducts">NOT MSXML6</Custom>
<Custom Action="OpenMSXML6DownloadError" After="OpenMSXML6Download">NOT MSXML6</Custom>
</InstallExecuteSequence>
<!-- ui information for the custom actions above. -->
<InstallUISequence>
<Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
<Custom Action="OpenMSXML6Download" Before="FindRelatedProducts">NOT MSXML6</Custom>
<Custom Action="OpenMSXML6DownloadError" After="OpenMSXML6Download">NOT MSXML6</Custom>
</InstallUISequence>
What this does is if MSXML6 isn't defined then it opens the web page and then prints the custom error message. Note that I'm trying to print the value of the property in the error message (I'm not sure if this is valid or not, but it seems to be.) The text that I see says "This component requires MSXML6. ==[cmd.exe]==..." so it is printing the value of the 'cmd.exe' property but not the other two... maybe that's because I define the property explicitly, I'm not sure... Anyway, I also ran the MSI with debugging on, and in the log file, I see absolutely no reference at all to the MSXML6 or the TEST properties ever being set. I've confirmed that the registry values are indeed set, although I'm not 100% sure how to handle the Msxml2 registry key, since it doesn't have any real values, only a default value. (I'm assuming that leaving off the 'Name' parameter is the right way to handle this.)
Help??
I managed to figure this one out... it was quite a simple answer. Basic issue was that the Custom Actions were executing before AppSearch, which is where the RegistrySearch properties get evaluated. See my blog post at CTICoder for details.
Related
I have a WiX 3.10 installer that installs an add-on module for an existing application. For this reason I use RegistrySearch to obtain the installation folder where the add-on should be put. After that an already pre-existing (meaning this is part of the base application and not the add-on) utility in the same directory must be executed with some parameters.
I tried this:
<Property Id="INSTALLFOLDER">
<RegistrySearch Id='InstallPathRegistry' Type='raw' Root='HKLM' Key='SOFTWARE\Vendor\Application' Name='InstallPath' Win64='no'/>
</Property>
<Condition Message="Application installation folder not found.">
<![CDATA[Installed OR INSTALLFOLDER]]>
</Condition>
<Property Id="WixQuietExecCmdLine" Value="RegAddOn.exe /f [INSTALLFOLDER]\Addon.RegFile" />
<CustomAction Id="QtExec" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="immediate" Return="check" />
<InstallExecuteSequence>
<Custom Action="QtExec" OnExit="success"/>
</InstallExecuteSequence>
Unfortunately, [INSTALLFOLDER] is not resolved. Obviously, as I also get a compiler warning about this.
How can I resolve the property?
Your warning says what to do:
Warning The 'X1' Property contains '[X2]' in its value which is an illegal reference to another property. If this value is a string literal, not a property reference, please ignore this warning. To set a property with the value of another property, use a CustomAction with Property and Value attributes.
Note: use a CustomAction with Property and Value attributes.
So you need to define your property with no value
<Property Id="WixQuietExecCmdLine" Value=" " />
and use custom action to fill it
<CustomAction Id="SetProp" Property="WixQuietExecCmdLine" Value="RegAddOn.exe /f [INSTALLFOLDER]\Addon.RegFile"></CustomAction>
and run it before your current custom action
<InstallExecuteSequence>
<Custom Action="SetProp" OnExit="success"/>
<Custom Action="QtExec" After="SetProp"/>
</InstallExecuteSequence>
I have the following WiX excerpt which works perfectly during an install but doesn't during uninstall. I'm quite new to WiX so apologies if it's a glaring error. Can anyone see the problem?
<Property Id="APPFOLDER" >
<RegistrySearch Id="APPInstalledFolderReg"
Root="HKLM"
Key="SOFTWARE\$(var.MANUFACTURER)\One Of My Web Services"
Name="Folder"
Type="raw"
Win64="yes" />
</Property>
<CustomAction Id="SetAPPFolderProperty"
Property="APPInstalledFolder"
Value="[APPFOLDER]"
Execute="immediate"
/>
<InstallExecuteSequence>
<Custom Action="SetAPPFolderProperty"
After="AppSearch"
>APPFOLDER</Custom>
<Custom Action='MyUnregisterAction'
After='InstallInitialize'
>REMOVE="ALL"</Custom>
</InstallExecuteSequence>
During "MyUnregisterAction", the APPInstalledFolder is not set. The MsiExec Install Log reports:
Skipping action: SetAPPFolderProperty (condition is false)
I understand this means the CustomAction's not executing because the Property APPFOLDER is not set. Is the RegistrySearch not performed during Uninstall?
The Registry search is definitely performed during an uninstall.
As a matter of fact, i tried your same snippet and could get it to work.
Are you running the installation in full UI mode?
In that case, the registry search will be run in the UI mode. Probably, what is happening here is that , the value of the property APPFOLDER is not passed into the Execute sequence.
For the value of the property to be passed to the execute sequence, you need to secure the property ie. add the APPFOLDER property to SecureCustomProperties in the Property table.
Once you do this, you code snippet should start working.
In general, under normal circumstances, the values of public properties are passed from the UI sequence to the execute sequence. However, there could be lockdown conditions where the property needs to be explicitly added to the SecureCustomProperties list in the Property table for the value to propogate to the Execute sequence.
Hope this helps.
Regards,
Kiran Hegde
I`m trying to set some launch conditions, so I just look after some registry and if they exists the installation can continue... if not it should stop...
Problem is, that it`s not working...
<Property Id="MSGEOPATHV8">
<RegistrySearch Id='msGeoV8_PathRegistry' Type='raw'
Root='HKLM' Key='SOFTWARE\Bentley\MicroStation GeoGraphics\08.01' Name='PathName' Win64='no'/>
</Property>
<CustomAction Id="caGeoPathV8" Execute="firstSequence" Property="MSGEOPATH" Value="[MSGEOPATHV8]" />
<Condition Message="[MSGEOPATH] Installation of requires previous installation of MicroStation GeoGraphics V8 or Bentley MAP XM/V8i.">MSGEOPATH</Condition>
...
...
<InstallExecuteSequence>
<Custom Action='caGeoPathV8' After='LaunchConditions' />
</InstallExecuteSequence>
I found that I need to do it after appSearch... so I checked it with orca... But custom action is scheduled after app search and before launchConditions.... so it should be ok... Also I read that probably the variable name should be upper case... something like global... so I did it and still nothing...
Any help?
Thanks
EDIT:
What I forgot to say... if I in condition mesasage replace MSGEOPATH by MSGEOPATHV8 it print actually the path what it found....
Ok, I solved it... the problem is that I don`t have defined installationUI sequence...
<InstallUISequence>
<Custom Action='caGeoPathV8' Before='LaunchConditions'>NOT Installed</Custom>
</InstallUISequence>
With this it works... but still not sure why? Because if I`m right the is executing every time or not?
I am using Properties to set the values of Registry entries. This is so that on install the first time I have a default value and then on upgrade the current registry value is used.
I need to have a property that sets the path to the user's local folder and to the programs folder. I know the below code is wrong but how do I do it. I think at least I want to do a Type 51 custom action but don't understand the documentation.
I believe there are three relevant parts
<InstallExecuteSequence>
<Custom Action="SetUserFolder" Before="InstallInitialize"/>
<Custom Action="SetInstallFolder" Before="InstallInitialize"/>
</InstallExecuteSequence>
Custom Action
<CustomAction Id="SetUserFolder" Property="UserFolder" Value="[%USERPROFILE]" />
<CustomAction Id="SetInstallFolder" Property="P_InstallFolder" Value="[%PROGRAMFILES]" />
The property.
<Property Id="P_MyAPPPATH" Value="[P_InstallFolder]MyApp\">
<RegistrySearch Id="S_MyAppPath" Type="raw" Root="HKCU" Key="Software\MyApp\Settings" Name="MyAppPath"/>
</Property>
<Property Id="P_MyAPPDB" Value="[UserFolder]\MyApp\MyAppData\">
<RegistrySearch Id="S_MyAPPDB" Type="raw" Root="HKCU" Key="Software\MyApp\Settings" Name="MyAppdb"/>
</Property>
As an alternative to using the properties you're defining, you might be able to use some built-in properties to better effect.
Instead of %USERPROFILE, consider LocalAppDataFolder. This will avoid your data from being copied between machines as a user roams between machines on a network domain. I'm guessing you don't need that but, if you do, use AppDataFolder and beware of the latencies involved.
Instead of %PROGRAMFILES, consider ProgramFilesFolder. This seems to be what you intend.
I've got great problems setting the install dir from a value in the Windows registry which I set the last time the setup ran. This to default the path correctly. The odd thing here is that we always let the user set the installation path, even on an upgrade and if it differs from the folder of the last installation, then we don't do RemoveExistingProducts in order to let the user run several versions of the application side-by-side.
Now, I've been searching the web for a solution and I've found many suggestions but none of these actually affects my INSTALLDIR which I can see in the setup UI where I get to choose where to install.
Here's what I got at the moment:
<Property Id="PREVINSTALLDIR">
<RegistrySearch Id="PrevInstallDir"
Root="HKCU"
Key="Software\MyCompany\MyApp"
Name="InstallDir"
Type="raw" />
</Property>
<CustomAction Id="SetTargetDir" Property="TARGETDIR"
Value="[PREVINSTALLDIR]"
Execute="firstSequence" />
<InstallExecuteSequence>
<Custom Action="SetTargetDir" Before="CostFinalize"></Custom>
<RemoveExistingProducts After="InstallFinalize">PREVINSTALLDIR ~= INSTALLDIR</RemoveExistingProducts>
</InstallExecuteSequence>
Can anyone spot what I'm doing wrong here?
Note, the RemoveExistingProducts part works so PREVINSTALLDIR has been read. In the setup log I can also see this:
Action start 13:50:27: AppSearch.
AppSearch: Property: PREVINSTALLDIR, Signature: PrevInstallDir
Action ended 13:50:27: AppSearch. Return value 1.
When exiting the setup, properties are dumped into the log file and I see this:
Property(C): PREVINSTALLDIR = C:\Some\Path\MyApp
Property(C): TARGETDIR = C:\
Property(C): MyAppDir = C:\ProgramData\Microsoft\Windows\Start Menu\Programs\MyApp\
Property(C): INSTALLDIR = C:\Program Files (x86)\MiTek\MyApp\
INSTALLDIR is not affected by my wix script above, neither is TARGETDIR which I would assume would be C:\Some\Path\MyApp as well.
I've tried a bunch of things here but regardless I just can't make TARGETDIR nor INSTALLDIR change.
This worked for me:
<!-- Existing install path -->
<Property Id="EXISTINGINSTALLDIR" Secure="yes">
<RegistrySearch Id="Locate_EXISTINGINSTALLDIR" Root="HKCU" Key="Software\$(var.CompanyName)\$(var.ProductName)" Name="InstallDir" Type="directory" />
</Property>
<!-- custom action specification -->
<CustomAction Id="Set_INSTALLDIR" Execute="firstSequence" Property="INSTALLDIR" Value="[EXISTINGINSTALLDIR]" />
<InstallExecuteSequence>
<Custom Action="Set_INSTALLDIR" After="FileCost"><![CDATA[NOT Installed AND (NOT INSTALLDIR) AND EXISTINGINSTALLDIR]]></Custom>
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="Set_INSTALLDIR" After="FileCost"><![CDATA[NOT Installed AND (NOT INSTALLDIR) AND EXISTINGINSTALLDIR]]></Custom>
</InstallUISequence>
Hi I managed to get my INSTALLLOCATION changed using this:
<SetDirectory Id="INSTALLLOCATION" Value="[$(var.PlatformProgramFilesFolder)]\[$(var.Manufacturer)]\[ProductName]" Sequence="both"></SetDirectory>
Value has to be a full path..hope this helps..:)