Wix, customAction set property - wix

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?

Related

In my Windows WiX Installer my Custom Actions don't run

I want to have the installer/uninstaller remove a folder that contains content generated by the application at run time. I figured a Custom Action would be the way to go.
We are using WiX 3.6.
(I want it in the installer sequence for a specific reason that is not important to this question.)
Here is my CustomAction definitions in the xml:
<Binary Id="CustomActionLib" SourceFile="$(var.CustomActionLibrary.TargetDir)$(var.CustomActionLibrary.TargetName).CA.dll" />
<CustomAction Id="DeleteLocalizedCA" Impersonate="yes" BinaryKey="CustomActionLib" DllEntry="DeleteLocalized" Return="check" />
<CustomAction Id="DeleteResourcesCA" Impersonate="yes" BinaryKey="CustomActionLib" DllEntry="DeleteResources" Return="check" />
Here are my references to them:
<InstallExecuteSequence>
<Custom Action="DeleteLocalizedCA" Before="InstallFiles"/>
<FindRelatedProducts Before="LaunchConditions" />
<RemoveExistingProducts After="InstallFinalize" />
<RemoveShortcuts>Installed AND NOT UPGRADINGPRODUCTCODE</RemoveShortcuts>
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="DeleteLocalizedCA" Before="InstallFiles"/>
<FindRelatedProducts Before="LaunchConditions" />
</InstallUISequence>
I added the CustomActionLibrary project to the solution and added a reference to it from the installer project but it never runs, I never see it in the logs, nothing!
And thus my question, Why Don't my WiX Custom Actions Run?
After several hours of googling and reading (Blog posts, documentation, Stackoverflow, etc.) and testing I finally found a solution that none of my reading pointed to.
I had to put an InstallExecuteSequence to contain my references in a fragment that contained a ComponentGroup:
<Fragment>
<InstallExecuteSequence>
<Custom Action="DeleteLocalizedCA" Before="InstallFiles">NOT Installed</Custom>
</InstallExecuteSequence>
<ComponentGroup Id='StringsComponents'>
...
</ComponentGroup>
</Fragment>
The Fragment that I had previously put the CustomAction reference in only had steps but no Component or ComponentGroup so apparently doesn't do anything. (I am not the original author of the installer, just taking over for a co-worker who wasn't able to help me on this).
Hopefully this helps others who are struggling with the same issue.

How to set TARGETDIR or INSTALLDIR from a registry entry?

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..:)

IIS 7.5 Installation required only once if IIS is disable

Hi i am using the below code to enable the IIS 7.5 in windows 7 . its working fine. but problem is every time when is run the setup (.MSi) IIS installs and uninstall time also its enable the IIS7.5 , how to put a condition to check if iis7.5 is disable then i want to install IIS. i am using wix3.5
Please help me.
<CustomAction Id="InstallIISCA" PatchUninstall="no" Return="check" Property="INSTALLIISPROP" Execute="oncePerProcess" HideTarget="yes" Impersonate="yes"
ExeCommand=" /Online /Enable-Feature /FeatureName:IIS-WebServerRole /FeatureName:IIS-ApplicationDevelopment /FeatureName:IIS-ASPNET /FeatureName:IIS-IIS6ManagementCompatibility /FeatureName:IIS-WebServerManagementTools /FeatureName:IIS-ISAPIFilter /FeatureName:IIS-ISAPIExtensions /FeatureName:IIS-NetFxExtensibility /FeatureName:IIS-WindowsAuthentication /FeatureName:IIS-IISCertificateMappingAuthentication /FeatureName:IIS-IPSecurity /FeatureName:IIS-ISAPIExtensions /FeatureName:IIS-ISAPIFilter /FeatureName:IIS-ManagementConsole "/>
<InstallExecuteSequence>
<Custom Action="InstallIISCA" Before="ConfigureIIs" />
</InstallExecuteSequence>
<Property Id="INSTALLIISPROP" Value="dism.exe"></Property>
You can add multiple conditions that limit when the custom action will run. To only run your IIS check at install time, change your Custom element to this:
<Custom Action="InstallIISCA" Before="ConfigureIIs">
Not Installed
</Custom>
Your description has a few run-on sentences about the conditions. I think you are also asking for a condition to not do the install if IIS is enabled (? maybe you mean installed ?). To do this, first set a property for that condition (here, checking the version of IIS to determine if its installed)
<Property Id="IIS_MAJOR_VERSION">
<RegistrySearch Id="CheckIISVersion" Root="HKLM" Key="SOFTWARE\Microsoft\InetStp" Name="MajorVersion" Type="raw" />
</Property>
And then include the property in the custom action condition:
<Custom Action="InstallIISCA" Before="ConfigureIIs">
Not Installed AND IIS_MAJOR_VERSION
</Custom>
And guessing that you already have some condition for the "ConfigureIIS" action, so its not unnecesarily run.

Wix: Is it possible to manually run a RemoveFolderEx element from a custom action?

I'm wondering if it's possible to manually run a RemoveFolderEx element from a custom action. I'm guessing probably not but someone may know a way that I'm not aware of.
My problem is I want to run the RemoveFolderEx element but only on an true UNINSTALL however my program executes it when upgrading as I've set it to uninstall before reinstalling.
I tried it via this method
Wix: condition on property not working
however it didn't work and still ran when doing a reinstall.
The only thing I can think of is being able to manually set a RemoveFolderEx off from a custom action which I know that I run at the correct point and only on a true uninstall. Perhaps my custom action could use a c++ dll and then manually add the command to the MSI interface but if I'm going that far it might just be as well to fully write the deletion logic myself.
Thanks. Neil
EDIT: I finally got this working, here is some example wix to show what I did.
<Property Id='P.REMOVEDATAFOLDER' Secure='yes' />
<DirectoryRef Id="DATADIR">
<Component Id="C.RemoveDataFolder" Guid="myguid" KeyPath="yes">
<util:RemoveFolderEx On="uninstall" Property="P.REMOVEDATAFOLDER" />
</Component>
</DirectoryRef>
<CustomAction Id="CA.SetDataFolder" Property="P.REMOVEDATAFOLDER" Value='[DATADIR]' />
<InstallExecuteSequence>
<Custom Action="CA.SetDataFolder" Before="ValidateProductID" >(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
</InstallExecuteSequence>
The property P.REMOVEDATAFOLDER only gets set on a true uninstall immediately after DATADIR is read from the registry but before the CostInitialize action.
I would use the following approach. Do not condition RemoveFolderEx operation, but use a conditioned custom action to set the appropriate value for the target property.
Taking some advice from this question, the condition that denotes uninstall is REMOVE="All" AND NOT UPGRADINGPRODUCTCODE.
Something like this may work:
<Component Id="RemoveMyFolder">
<Condition> REMOVE="All" AND NOT UPGRADINGPRODUCTCODE </Condition>
<RemoveFolderEx ... />
</Component>

Why isn't my Wix Property being evaluated?

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.