Deploy BizTalk application msi (created with BTDF) via msiexec - wix

We are setting up deployment automation for our BizTalk MSIs that were created with BTDF.
Currently the approach we're working on is by calling msiexec from our deployment toolset. However, we need to install the application in a different folder than the MSI is set to propose.
The BTSF WiX default to C:-drive, whereas we must install to the E: drive. I have tried changing that in the msiexec call, but when passing INSTALLDIR or TARGETDIR, it just throws the msiexec help dialog in my face.
So I figured I should try and take a look at WiX, so that we could build the MSI to default to E: (if available), which would ultimately have the same end result, but WiX is a bit of mystery to me and it seems to have a lot of 'magic' for my understanding at this point.
BTDF by default uses the below structure (and mainly the lower portion of it), and I figure I would have to do something with the TARGETDIR and/or SourceDir. But I can't put my finger on which part is just some kind of variable that can be set.
<Directory Id="TARGETDIR" Name="SourceDir">
<?if $(var.CreateStartMenuShortcuts) ~= True?>
<Directory Id="ProgramMenuFolder">
<Directory Id="BizShortCuts" Name="$(var.ProductName) $(var.ProjectVersion)">
<Directory Id="BizShortCutsTools" Name="Deployment Tools" />
</Directory>
</Directory>
<?endif?>
<Directory Id="ProgramFilesFolder" Name="ProgramFiles">
<Directory Id="ProductDir" Name="$(var.ProductName)">
<Directory Id="INSTALLDIR" Name="$(var.ProjectVersion)"/>
</Directory>
</Directory>
</Directory>
Edit 20180129
Note that this problem occurs in a server environment, with restricted security for my logged in user. We are permitted to run msi installers (right click, custom option 'Run as [authorized user name]', with the msi UI.
In order to accomplish this via command line, I've launched as PS terminal under that other account, which works up until the point where I add the INSTALLDIR parameter. Then it simply displays msiexec help.
I doubt it makes a difference, but local version of msiexec (which works) is 5.0.7601.23593, and serverside (which doesn't work) is 5.0.9600.18333 (i.e. more recent).

First, upgrade to the Deployment Framework for BizTalk v5.6 or newer.
Second, in your .btdfproj, add DefaultInstallDir:
<PropertyGroup>
<!-- existing MSI properties -->
<ProductUpgradeCode>GUID-HERE</ProductUpgradeCode>
<!-- add DefaultInstallDir -->
<DefaultInstallDir>E:\MyCustomPath</DefaultInstallDir>
</PropertyGroup>
The MSI will now default to E:\MyCustomPath.

Related

How can I create a folder (at Runtime) during installation via msiexec.exe?

I am deploying one MSI via msiexec.exe, but when I specify the path=D:\folder_name, the folder is not created.
Code:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLDIR" Name="bin" />
</Directory>
</Fragment>
From the above code, I can achieve folder "bin" but I want that "bin" should go into the folder which will get created via msiexec.exe i.e
msiexec.exe /i /path/to/msi /quiet PATH=Drive/Folder_name
Can we have a workaround so that if the folder is not present then it should create it and should put the "bin" in that folder?
You need to specify the TARGETDIR and not PATH. Try the following:
msiexec.exe /i /path/to/msi TARGETDIR="DRIVE/Folder_name" /qb
It's not clear what you're asking because:
Why is PATH in your msiexec command line? If you want to specify the actual directory you should perhaps be using INSTALLDIR=....
The Directory element seems incomplete. Typically you'd have something like:
Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="MyName">
<Directory Id="MYDIR" Name="Fred" />
</Directory>
</Directory>
</Directory>
and use INSTALLDIR in the command line to specify the name within ProgramFiles or TARGETDIR to customize the entire path, or MYDIR to change the name "Fred".
To get to the question: a folder is created by specifying that files will be installed there. Maybe more of your source would show that.
If you want to create an empty directory it's done with a CreateFolder element inside a component, as here in the WiX docs:
Creating an empty folder
This is not in your question, but silent installs that require elevation will fail because silent means that the UAC elevation prompt will not be shown, and the install will proceed with limited privileges and fail.

How to find previously installed location

I am using Wix Burn to upgrade our program with some prerequisites. The program needs to be installed in the same location that previously installed. How can I find the installed location? I am thinking about to find it from the registry Uninstall folder, however, sometimes it is not even there. Even if it is there, how do I get it from Burn?
You can use AppSearch to locate components installed by the previous installation. You can then set the installation directory dynamically by using the results of that ComponentSearch. All of this is done in the msi itself, burn is not involved in that process. The only thing you have to do with the burn bundle is to change the version number and to make sure that the UpgradeCode of the previous bundle matches the UpgradeCode of the current bundle. Bear in mind that, unlike in msi packages, the last part of the version number of a burn bundle is significant. You will also need to change the version number of the msi.
To make this work, it is necessary the previous bundle installed a component of which the GUID is known to you, and that component needs to reside inside the folder you want to upgrade.
<!-- ComponentSearch -->
<Fragment>
<Property Id="PREVIOUS_INSTALL_FOLDER">
<ComponentSearch Id="MyComponentSearch" Guid="KNOWN_GUID_OF_PREVIOUSLY_INSTALLED_COMPONENT" />
</Property>
</Fragment>
<!-- Increment Product Version, Reference Component Search, Set Target Location -->
<Product
...
Version="INCREMENTED_VERSION_NUMBER"
UpgradeCode="HAS_TO_MATCH_PREVIOUSLY_INSTALLED_UC">
<SetProperty
Id="DYNAMIC_PROGRAM_LOCATION"
Value="[PREVIOUS_INSTALL_FOLDER]"
After="AppSearch" Sequence="ui" Action="SetDynamicProgramLocation">
<![CDATA[PREVIOUS_INSTALL_FOLDER]]>
</SetProperty>
</Product>
<!-- Folder Layout -->
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="DYNAMIC_PROGRAM_LOCATION" />
</Directory>
</Directory>
</Fragment>

Using WiX to target specific folder

I'm using Wix to create an installer that will search for a directory on the user's PC and install a related application to that directory. For example, I need to install to the folder ProductA\Utilities, the location of which is outside of my control.
To accomplish this, I have tried the following:
<Property Id="UTILITIES_DIR">
<DirectorySearch Id="FindUtilsDir" Path="ProductA\Utilities"/>
</Property>
<Directory Id="TARGETDIR" Name="SourceDir">
<!-- WiX requires me to use a special folder at some point -->
<Directory Id="ProgramFilesFolder" Name="ProgramFiles">
<Directory Id="UTILITIES_DIR">
<Directory Id="INSTALLFOLDER" Name="MyUtility"/>
</Directory>
</Directory>
</Directory>
This all works well when I'm running the installer by double clicking, however, when I run the installer through msiexec.exe, the UTILITIES_DIR is found, but overwritten immediately after:
From log file:
MSI (c) (C0:0C) [16:49:34:064]:
PROPERTY CHANGE: Adding TARGETDIR property. Its value is 'F:\'.
MSI (c) (C0:0C) [16:49:34:064]:
PROPERTY CHANGE: Modifying ProgramFilesFolder property.
Its current value is 'C:\Program Files (x86)\'. Its new value: 'F:\ProgramFiles\'.
MSI (c) (C0:0C) [16:49:34:064]:
PROPERTY CHANGE: Modifying UTILITIES_DIR property.
Its current value is 'C:\ProductA\Utilities'. Its new value: 'F:\ProgramFiles\'.
It's worth noting that F:\ on my machine is a network share to parts of C:\ and it reports the exact same free space as C:\, so it seems that I'm getting lucky when running the .msi directly and TARGETDIR is set to C:\, but when running from msiexec, TARGETDIR is getting set to F:.
Is there a way to accomplish finding a specific directory that may be in any root?
You can set the SourceDir to WindowsVolume. So it will not change anymore.
<SetDirectory Id="SourceDir " Value="[WindowsVolume]" />

How to give current user full access control permissions for the installed application Program files folder

I'm new to WiX. Using WiX v3.0.
I want to create one installer for the application.
If I install the application, it is installed in C:\Program Files\Appln\.
I want to give full access control to the Appln folder while installing my application.
Is it possible? I don't want to manually set the full access control permissions for the folder.
First, this isn't a recommended design. The user should not be able to modify things in ProgramFilesFolder for a great many reasons. However, you can do this with the Permission element. It'd look a little like:
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='ApplnFolder' Name='Appln'/>
</Directory>
</Directory>
<Component Id='GrantTooManyPermissionsToApplnFolder' Directory='ApplnFolder'
Guid='PUT-GUID-HERE'>
<CreateFolder>
<Permission GenericAll='yes' User='[UserSID]' />
</CreateFolder>
</CreateFolder>
The important parts are the CreateFolder and Permission elements. CreateFolder defaults to the Directory of the Component and gives a place to hang the Permission element. The Permission element is pretty self-explanatory. The UserSID property is a built-in MSI property.

WIX installer root directory and versioning

I have created a silent installer Using WIX for my application. I want it to install my application to C:\MyApps folder but its Directory Id='TARGETDIR' Name='SourceDir' tag randomly picks C or D drive. I want to enforce my installation to C drive only. Also in case, I provide version number greater than 4.0.5, I am geting an error during installation saying "This installation package cannot be installed by the Windows Installer Service. You must install a newer version of the Window Installer service." I am having Windows XP professional SP3 Version 2002.
To begin with, I think you should start your WiX journey with the tutorial available here. It contains the answers to the most of basic questions you'll face with the first thing. You should also be aware that understanding WiX means understanding the concepts of Windows Installer first - otherwise some points will seem a weird magic to you.
When you create a new WiX setup project in Visual Studio, it generates a template with some placeholders. It is recommended to start modifying this template. For instance, the directory structure:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="SetupProject1">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent" Guid="ba7d579f-5234-4448-b880-109f589d58e5"> -->
<!-- TODO: Insert files, registry keys, and other resources here. -->
<!-- </Component> -->
</Directory>
</Directory>
</Directory>
This snippet defines the INSTALLLOCATION folder under the ProgramFileFolder, and this is a better approach than to place it under the C:\ root. You can still change the installation location by modifying the INSTALLLOCATION property at install time (for instance, base on user's input).
The quick answer to your questions are:
...randomly picks C or D drive...
That's expected - it picks the drive with the most free space by the time of installation. If you stick to the way WiX template defines by default, it will fall under C: (actually, under Program Files folder).
...You must install a newer version of the Window Installer service...
Basically, it means what it says - the version Windows Installer on your machine is lower than the one you require in your package. If you try to solve the above problems with this change, then it has nothing to do with the Windows Installer version. You should require higher version than it is specified by default only in case you are going to use new features of Windows Installer.
Hope you'll make right conclusion out of this brief intro - start with the tutorial. :-)
The problem with your versions is you're changing the Windows Installer version when you change your Product version.
<Package
Id='*'
InstallerVersion='406'
Compressed='yes'
Description="Installer Number 406" />
The InstallerVersion attribute should be the minimum required version of Windows Installer required to install this package. You have Windows Installer v4.5 installed. When this is set to 406, it looks for Windows Installer v4.6 which frankly, doesn't exist. Setting this to 301 (version 3.1) is usually sufficient.
InstallerVersion='301'
While your description attribute is fine, I would find the following more meaningful:
Description="My Product v4.0.6 Installer"
Try this:
<Fragment>
<Property Id="_BrowseProperty" Value="INSTALLDIR" Secure="yes"/>
<CustomAction Id="SetDataLocationDefault" Property="INSTALLDIR" Value="[WindowsVolume]$(var.Title)\" />
<InstallUISequence>
<Custom Action="SetDataLocationDefault" After="CostFinalize" />
</InstallUISequence>
<InstallExecuteSequence>
<Custom Action="SetDataLocationDefault" After="CostFinalize" />
</InstallExecuteSequence>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLDIR" Name="$(var.Title)">
<!-- TODO: Insert your components here. -->
</Directory>
</Directory>
</Fragment>
I think this should work!
Do not rely on TARGETDIR, and use the custom property, like this:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLLOCATION" Name="SetupProject1">
<!-- TODO: Insert your components here. -->
</Directory>
</Directory>
The template is taken from Yan's answer. Set INSTALLLOCATION to the desired folder C:\MyApps, that should do the trick.