I need to check if Application Initialization is installed on a 2008R2 Server.
The app is not installed as a feature, it is an IIS Module that I downloaded from the following link.
The problem I'm having is where does the folders actually get placed to be able to perform a search in my WiX project to see if they exist or not.
TLDR:
Look for the Version value in HKLM\SOFTWARE\Microsoft\IIS Extensions\Application Initilaization. Current version is 7.1.1636.0.
Full answer:
Since this is a MSI installation package, you can open it using Orca and search for any registry key being created.
Then in Orca, you open the Registry table and find the
row with Registry=reg8BD5741527F144C70BDB7B0134BC7B84. In it, you will find the Key where the value will be created, the Name of it and the Value.
This way, you can easily perform a registry search and evaluate if the module is installed.
EDIT
To perform a search during launch and verify if the module is installed, add the following code:
<Property Id="MODULEINSTALLED">
<RegistrySearch Id="IsModuleInstalled"
Root="HKLM"
Key="SOFTWARE\Microsoft\IIS Extensions\Application Initilaization"
Name="Version"
Type="raw" />
</Property>
Then use the property in a condition:
<Condition Message="This application requires Application Initialization module. Please install the Application Initialization module then run this installer again.">
<![CDATA[Installed OR MODULEINSTALLED]]>
</Condition>
Related
I have a merge module which searches for some registry locations to read values and save to Properties. Here is the code segment:
<Fragment Id="RegSearch">
<Property Id="HOST_APP_PATH" >
<RegistrySearch Id="HOST_App"
Root="HKLM"
Key="SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\HOST.exe"
Name="Path"
Type="raw"
/>
</Property>
<Property Id="HOST_ROOT_PATH" >
<RegistrySearch Id="HOST_Root"
Root="HKLM"
Key="SOFTWARE\HostApplication\Installation Info"
Name="HOST_Root"
Type="raw"
/>
</Property>
Windows Installer puts this search in AppSearch custom action.
Problem: AppSearch executes this search very early, before WriteRegistryValues of Host Installer, it won't get any values and properties with this search won't be defined, because registry to search was never written there.
Question 1: Can we reschedule this registry search from merge module after WriteRegistryValues of Host Installer?
Question 2: Is there any other way to search registry after Host Installer executes WriteRegistryValues? Probably with some custom action?
AppSearch is a standard action provided by the windows installer and by design is intended to run very early. This is because it's frequently used by the LaunchConditions standard action to decide if an installation can continue or not. It's also useful for deciding whether features and components should be installed.
MSI is a very opinionated framework. I suspect that there is something wrong with your current design that is going to be incompatible with MSI.
Is host installer the same MSI or a different MSI? Assuming it's the same, why couldn't you just put your data in some MSI properties and use those properties to write to the registry? Then you wouldn't need to read the values back in because you'd already have them in properties.
What do you need these properties for after writing them to the registry? Usually writing them to the registry would be the end game. I'm not sure what else you are doing next.
If host.msi is a different MSI, why are you having one MSI install another MSI? That's not MSI design. In this case you would need a bootstrapper. Host MSI would run first then this MSI. But even then it's kinda strange that a second MSI would depend on properties set by a first MSI. I'd think the bootstrapper UI and Application would gather this information and pass it as secure custom public properties to both MSIs.
To answer question 1: No a merge module can only insert actions into the sequence. It can't reschedule actions. 2: You would have to use a custom action. But as I said above, this feels like the wrong path to me.
I have a program which is dependent upon postgres. The installer I made will install postgres for the user; however, I would like this to only happen if Postgres is not already installed. I'm attempting to do this through a custom action with conditions, however, I cannot seem to get it to work. Any help would be greatly appreciated. This is what I currently have.
<Property Id="POSTGRESINSTALLED">
<RegistrySearch Id="POSTGRESINSTALLED_SEARCH" Key="SOFTWARE\PostgreSQL\Installations\postgresql-x64-9.5" Root="HKLM" Type="raw" Name="Branding" />
</Property>
<InstallExecuteSequence>
<Custom Action='postgres_install_action' After='vc_redist_install_action'> ( NOT POSTGRESINSTALLED ) OR ( REINSTALL ) </Custom>
</InstallExecuteSequence>
It's not clear which part is not working, the detection or the install.
If you run the install and produce a log (msiexec /I [path to msi] /l*vx [path to text log]) you'll see if POSTGRESINSTALLED_SEARCH is being set. The install doesn't need to complete because the search is early. Assuming you've got the general idea correct, you haven't explicitly said whether to search the 32-bit registry or the 64-bit registry. It may simply be looking in the wrong place.
If the search works, then the install can easily fail. The custom action appears to be immediate (the default) so it will not run elevated and is therefore likely to fail. The same is true of the vc redist install custom action.
The model for installing prerequisites is to use a bundle to install them first. These should help, but that's the way you should be doing this:
http://wixtoolset.org/documentation/manual/v3/bundle/
http://www.c-sharpcorner.com/UploadFile/cb88b2/installing-prerequisites-using-wix-bootstrapper-project-and/
How to include prerequisites with msi/Setup.exe in WIX
WiX - Install Prerequisites and 3rd party applications
I have a WIX installer in which I install my program and .NET Core 1.0.5. The .NET Core is installed in silent mode:
<ExePackage InstallCommand="/q" Id = "DotNetCore.Setup" SourceFile="..\DotNetCore\DotNetCore.exe" />
On a clean system, the installer just goes fine. If I try to reinstall it, I get a reboot. Probably the .NET installer detected to be already installed and triggered the repair feature on its own. Is there any way to skip the .NET Core installation if it's already installed?
I tried looking for command line parameters but nothing seems useful
The ExePackage element has the DetectCondition property. This means that you can specify a condition such that, if the condition evaluates to false, the package will be installed. You can combine this with an util:RegistrySearch element which can be used to search through the registry to detect if the .NET Core has already been installed.
In order to perform the registry search, you will first need to find a registry key which is present whenever .NET is installed.
Find the "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\",
(or "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\" on 64-bit machines) key in your registry, then locate the subkey which corresponds to the .NET Core - this key should have a value for "DisplayName" which should be ".NET Core" or something similar.
The correct key, once found, should have a name which is a string of hex characters - this is one of the GUIDs corresponding to the .NET Core program. You can then use the following code to allow the installer to search for the presence of this key:
<util:RegistrySearch Id="VCRedistTest32" Root="HKLM" Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{YOUR_GUID_HERE}" Result="exists" Variable="DOTNETPresent" Win64="no"/>
(Use Win64="yes" instead for the 64-bit registry)
You can then use the following for the ExePackage:
<ExePackage InstallCommand="/q" Id = "DotNetCore.Setup" SourceFile="..\DotNetCore\DotNetCore.exe" DetectCondition="DOTNETPresent"/>
Don't forget to add the reference to the util extension to the top-level wix element:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
You need to use DetectCondition attribute and registry search that assign property in case the .net Core is installed.
ExePackage Element - DetectCondition
"A condition that determines if the package is present on the target system. This condition can use built-in variables and variables returned by searches. This condition is necessary because Windows doesn't provide a method to detect the presence of an ExePackage. Burn uses this condition to determine how to treat this package during a bundle action; for example, if this condition is false or omitted and the bundle is being installed, Burn will install this package."
I am using wix registry search in order to locate a plugin directory for a program I am trying to integrate with. The value of the registry key looks like this:
%PROGRAMFILES%\Product\Plugins
When I do a registry search with type="raw" like this:
<Property Id="PLUGINDIR_STRING">
<RegistrySearch Id="PluginDirSearchString"
Root="HKLM"
Key="$(var.PluginDirRegKey)"
Name="$(var.PluginDirRegKeyName)"
Type="raw"
Win64="yes" />
</Property>
I will get the exact string.
When I use type Directory like this:
<Property Id="PLUGINDIR">
<RegistrySearch Id="PluginDirSearch"
Root="HKLM"
Key="$(var.PluginDirRegKey)"
Name="$(var.PluginDirRegKeyName)"
Type="directory"
Win64="yes" />
</Property>
I will get an empty string. I am checking the values like this:
<Condition Message='plugin dir "[PLUGINDIR_STRING]" found using registry key "$(var.PluginDirRegKey)" is not a valid path, make sure the path exist'>PLUGINDIR_STRING AND NOT PLUGINDIR</Condition>
<Condition Message='Unable to find registry key "$(var.PluginDirRegKey)", make sure $(var.PRODUCT) is installed'>PLUGINDIR_STRING</Condition>
The first message is displayed indicating that PLUGINDIR_STRING is found, but not PLUGINDIR. I thought the Directory option should expand %programfiles%? How to correctly handle a registry value like this?
%PROGRAMFILES%\Product\Plugins
The raw search does not work the same as directory search. A raw search returns the values in the registry item. A directory search retrieves the value then checks to see if that registry exists - it literally is a directory search for the directory in that registry item and if it doesn't exist then it will not set the property value. The idea is that if you want to use that directory as an install location it tells you that it doesn't exist.
Anyway a verbose log should verify if this is going on - look at the AppSearch and you may find something like a 1314 error saying that the directory in that registry item does not exist.
I cannot reproduce the error you are seeing. Both raw and directory registry searches are expanding %programfiles% correctly. Everything else you are doing seems correct, so the most likely issue with your failing directory search is that your setup is a 32-bit setup and you are attempting to locate a 64-bit directory. Your AppSearch in a 32-bit install will locate the %programfiles% string in your registry entry, but it will invoke WIN64DUALFOLDERS, and search for the directory in the ProgramFiles(x86) folder. If the directory isn't there you will see an empty property value returned.
Use the well defined MSI property to get the program files location.
You can find the list of well defined properties here
So set your property to [ProgramFilesFolder]\Product\Plugins. There is also ProgramFiles64Folder but from the snippets you supplied I can't tell which one you should be using. Ideally you use a 32-bit installer to install into Program Files on a 32-bit OS and Program Files (x86) on a 64-bit OS and you would use a 64-bit installer to install into Program File on a 64-bit OS.
I'm writing a WiX installer for an application which was deployed previously using ClickOnce.
I would like to detect if the application was installed on the client computer and abort the MSI installation. I searched similar questions on Stack Overflow, but I couldn't find a way to do that.
If I can find a path or some registry key that tells me where the application was installed, I can abort the MSI installation via a Condition.
Using the answer for this question, I was able to get somewhere. The ClickOnce shortcuts are files with the .appref-ms extension. This is the code I use:
<Property Id="APP_CLICKONCE_INSTALLED">
<DirectorySearch Id="dirSearch.APP.CLICKONCE" AssignToProperty="yes" Path="[StartMenuFolder]" Depth="2">
<FileSearch Id="fileSearch.APP.CLICKONCE" Name="APP.appref-ms" />
</DirectorySearch>
</Property>
<Condition Message="App is already installed. Please uninstall it then re-run this setup.">
<![CDATA[APP_CLICKONCE_INSTALLED = "" OR INSTALLED]]>
</Condition>
However, StartMenuFolder gives the location for AllUsers profile, whereas the click once application is installed for the current user. I am still digging.
Using perUser installation the StartMenuFolder gives the current user location (I was using perMachine):
<Package InstallerVersion="200" Compressed="yes" InstallScope="perUser" />
All is good now.
I don't know anything about WiX, but another way to tell if a ClickOnce application is installed is to iterate through the uninstall strings in the registry, which are here:
HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall
You'll want to search for one where the product name of your application matches the Display Name for that set of keys.