I'm trying to explore instance transforms with WiX version 3.7.1224.0. I created a test project (source below) and I can install the default ProductCode propertly, but when I try to install the resulting MSI, I get an error:
msiexec /i SetupProject1.msi /l*vx install.log MSINEWINSTANCE=1 TRANSFORMS=":Alpha"
Error applying transforms. Verify that the specified transform paths are valid
The install.log seems to suggest there's a row in the Property table that the "regular transform" is expecting to find and modify, but I'm not sure what property it might be looking for. I've been reading the MSDN documentation on multiple instance transforms as well as the WiX documentation and blog posts describing how <InstanceTransforms> works, but I'm at a loss for what it's looking for.
Compilation
"%WIX%\bin\candle.exe" -out obj\Debug\ -arch x86 Product.wxs
"%WIX%\bin\Light.exe" -out SetupProject1.msi -cultures:null obj\Debug\Product.wixobj
Product.wxs
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="SetupProject1" Language="1033" Version="1.0.0.0"
Manufacturer="ABC"
UpgradeCode="ce6fdce7-5c23-4379-af59-f70c520ad1b6">
<Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<Property Id="INSTANCENAME" Secure="yes" />
<InstanceTransforms Property="INSTANCENAME">
<Instance Id="Alpha" ProductCode="{16756BA2-9FAC-4BA4-9FFD-FC2F06B1315E}" ProductName="SetupProject1 Alpha"/>
<Instance Id="Bravo" ProductCode="{D32D3643-5A46-421E-9216-1B1C9037DC37}" ProductName="SetupProject1 Bravo"/>
<Instance Id="Charlie" ProductCode="{ED9BC4F0-8CB8-4813-B677-F0E4A52D1890}" ProductName="SetupProject1 Charlie"/>
</InstanceTransforms>
<Feature Id="ProductFeature" Title="SetupProject1" Level="1">
<ComponentRef Id="FileComponent" />
</Feature>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SetupProject1">
<Component Id="FileComponent" Guid="*">
<File Source="File1.txt" KeyPath="yes" />
</Component>
</Directory>
</Directory>
</Directory>
</Product>
</Wix>
install.log excerpt
MSI (c) (E4:8C) [13:49:28:343]: TRANSFORM: Applying regular transform to database.
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: _Tables 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: _Columns 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: _Validation 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: AdminExecuteSequence 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: AdminUISequence 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: AdvtExecuteSequence 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: Component 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: Directory 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: Feature 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: FeatureComponents 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: File 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: InstallExecuteSequence 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: InstallUISequence 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: LaunchCondition 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2262 2: Media 3: -2147287038
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 2254 2: 3: Property
DEBUG: Error 2254: Database: Transform: Cannot update row that doesn't exist. Table: Property
1: 2254 2: 3: Property
Error applying transforms. Verify that the specified transform paths are valid.
Alpha
MSI (c) (E4:8C) [13:49:28:343]: Note: 1: 1708
MSI (c) (E4:8C) [13:49:28:344]: Product: SetupProject1 Alpha -- Installation failed.
MSI (c) (E4:8C) [13:49:28:344]: Windows Installer installed the product. Product Name: SetupProject1 Alpha. Product Version: 1.0.0.0. Product Language: 1033. Manufacturer: ABC. Installation success or error status: 1624.
It turns out the transform is setting the INSTANCENAME property (obvious, in retrospect). The property needs to have a default value so it's listed in the Property table.
<Property Id="INSTANCENAME" Value="Default" />
Related
I've added MajorUpgrade element to msi. Increased version, changed UpgradeCode, ProductId is the same. Here what it looks like
<?define Config = "Release" ?>
<?define ProductId = "{87FEDA58-2732-4BBA-9C1E-B7A9AE1A46F6}" ?>
<?define UpgradeCode = "{B414C827-8D81-4B4A-B3B6-338C06DE3A11}" ?>
<?define ProductName = "Some Product" ?>
<?define Version = "2.0.0.0" ?>
<?define Company = "Some Inc." ?>
<?define Description = "Installs Some Product" ?>
In version 1.0.0.0 ProductId is different. MajorUpgrade is set like this
<MajorUpgrade
Schedule="afterInstallValidate"
DowngradeErrorMessage="A newer version of [ProductName] is already installed."
AllowSameVersionUpgrades="yes" />
During the upgrade it successfully identifies previous version on FindRelatedProducts stage
Action start 22:31:06: FindRelatedProducts.
MSI (s) (38:78) [22:31:06:557]: PROPERTY CHANGE: Adding WIX_UPGRADE_DETECTED property. Its value is '{3E786878-358D-43AD-82D1-1435ADF9F6EA}'.
MSI (s) (38:78) [22:31:06:557]: PROPERTY CHANGE: Adding MIGRATE property. Its value is '{3E786878-358D-43AD-82D1-1435ADF9F6EA}'.
MSI (s) (38:78) [22:31:06:557]: Doing action: AppSearch
MSI (s) (38:78) [22:31:06:557]: Note: 1: 2205 2: 3: ActionText
Action ended 22:31:06: FindRelatedProducts. Return value 1.
RemoveExistingProducts starts the uninstallation RemoveFolderEx removes some folders and RemoveExistingProducts stage returns code 1 (success right?). But it doesn't remove entries in registry. Product is still there. Components not remove. Here is the log.
Action start 22:35:25: RemoveExistingProducts.
MSI (s) (38:78) [22:35:25:190]: Note: 1: 2205 2: 3: Error
MSI (s) (38:78) [22:35:25:190]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 23
MSI (s) (38:AC) [22:35:25:190]: Resetting cached policy values
MSI (s) (38:AC) [22:35:25:190]: Machine policy value 'Debug' is 0
MSI (s) (38:AC) [22:35:25:190]: ******* RunEngine:
******* Product: {3E786878-358D-43AD-82D1-1435ADF9F6EA}
******* Action:
******* CommandLine: **********
MSI (s) (38:AC) [22:35:25:205]: Note: 1: 2265 2: 3: -2147287035
MSI (s) (38:AC) [22:35:25:205]: End dialog not enabled
MSI (s) (38:AC) [22:35:25:205]: Original package ==> C:\Windows\Installer\bd684.msi
MSI (s) (38:AC) [22:35:25:205]: Package we're running from ==> C:\Windows\Installer\bd684.msi
MSI (s) (38:AC) [22:35:25:221]: APPCOMPAT: Uninstall Flags override found.
MSI (s) (38:AC) [22:35:25:221]: APPCOMPAT: Uninstall VersionNT override found.
MSI (s) (38:AC) [22:35:25:221]: APPCOMPAT: Uninstall ServicePackLevel override found.
MSI (s) (38:AC) [22:35:25:221]: APPCOMPAT: looking for appcompat database entry with ProductCode '{3E786878-358D-43AD-82D1-1435ADF9F6EA}'.
MSI (s) (38:AC) [22:35:25:221]: APPCOMPAT: no matching ProductCode found in database.
MSI (s) (38:AC) [22:35:25:221]: Machine policy value 'DisablePatch' is 0
MSI (s) (38:AC) [22:35:25:221]: Machine policy value 'AllowLockdownPatch' is 0
MSI (s) (38:AC) [22:35:25:221]: Machine policy value 'DisableLUAPatching' is 0
MSI (s) (38:AC) [22:35:25:221]: Machine policy value 'DisableFlyWeightPatching' is 0
MSI (s) (38:AC) [22:35:25:237]: APPCOMPAT: looking for appcompat database entry with ProductCode '{3E786878-358D-43AD-82D1-1435ADF9F6EA}'.
MSI (s) (38:AC) [22:35:25:237]: APPCOMPAT: no matching ProductCode found in database.
MSI (s) (38:AC) [22:35:25:237]: Transforms are not secure.
MSI (s) (38:AC) [22:35:25:237]: Command Line: UPGRADINGPRODUCTCODE={87FEDA58-2732-4BBA-9C1E-B7A9AE1A46F6} CLIENTPROCESSID=2520 CLIENTUILEVEL=3 MSICLIENTUSESEXTERNALUI=1 REMOVE=ALL
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding PackageCode property. Its value is '{0C30C985-B880-4BEF-90B5-52ED8736B108}'.
MSI (s) (38:AC) [22:35:25:237]: Product Code passed to Engine.Initialize: '{3E786878-358D-43AD-82D1-1435ADF9F6EA}'
MSI (s) (38:AC) [22:35:25:237]: Product Code from property table before transforms: '{3E786878-358D-43AD-82D1-1435ADF9F6EA}'
MSI (s) (38:AC) [22:35:25:237]: Product Code from property table after transforms: '{3E786878-358D-43AD-82D1-1435ADF9F6EA}'
MSI (s) (38:AC) [22:35:25:237]: Product registered: entering maintenance mode
MSI (s) (38:AC) [22:35:25:237]: Determined that existing product (either this product or the product being upgraded with a patch) is installed per-machine.
MSI (s) (38:AC) [22:35:25:237]: MSI_LUA: Nested installation UAC elevation tracks that of parent (is not elevated)
MSI (s) (38:AC) [22:35:25:237]: Product {3E786878-358D-43AD-82D1-1435ADF9F6EA} is admin assigned: LocalSystem owns the publish key.
MSI (s) (38:AC) [22:35:25:237]: Product {3E786878-358D-43AD-82D1-1435ADF9F6EA} is managed.
MSI (s) (38:AC) [22:35:25:237]: MSI_LUA: Credential prompt not required, user is an admin
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding ProductState property. Its value is '5'.
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding ProductToBeRegistered property. Its value is '1'.
MSI (s) (38:AC) [22:35:25:237]: Package name retrieved from configuration data: 'aep_monolith.msi'
MSI (s) (38:AC) [22:35:25:237]: Note: 1: 2205 2: 3: Error
MSI (s) (38:AC) [22:35:25:237]: Note: 1: 2262 2: AdminProperties 3: -2147287038
MSI (s) (38:AC) [22:35:25:237]: Machine policy value 'DisableMsi' is 1
MSI (s) (38:AC) [22:35:25:237]: Machine policy value 'AlwaysInstallElevated' is 0
MSI (s) (38:AC) [22:35:25:237]: User policy value 'AlwaysInstallElevated' is 0
MSI (s) (38:AC) [22:35:25:237]: Product {3E786878-358D-43AD-82D1-1435ADF9F6EA} is admin assigned: LocalSystem owns the publish key.
MSI (s) (38:AC) [22:35:25:237]: Product {3E786878-358D-43AD-82D1-1435ADF9F6EA} is managed.
MSI (s) (38:AC) [22:35:25:237]: Running product '{3E786878-358D-43AD-82D1-1435ADF9F6EA}' with elevated privileges: Product is assigned.
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding UPGRADINGPRODUCTCODE property. Its value is '{87FEDA58-2732-4BBA-9C1E-B7A9AE1A46F6}'.
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding CLIENTPROCESSID property. Its value is '2520'.
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding CLIENTUILEVEL property. Its value is '3'.
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding MSICLIENTUSESEXTERNALUI property. Its value is '1'.
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding REMOVE property. Its value is 'ALL'.
MSI (s) (38:AC) [22:35:25:237]: Machine policy value 'DisableAutomaticApplicationShutdown' is 0
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding MsiRestartManagerSessionKey property. Its value is '7dad24bc7ce3134db335b2318702e12c'.
MSI (s) (38:AC) [22:35:25:237]: RESTART MANAGER: Session opened.
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding MsiSystemRebootPending property. Its value is '1'.
MSI (s) (38:AC) [22:35:25:237]: TRANSFORMS property is now:
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding PRODUCTLANGUAGE property. Its value is '1033'.
MSI (s) (38:AC) [22:35:25:237]: PROPERTY CHANGE: Adding VersionDatabase property. Its value is '301'.
Here is the ending of it
MSI (s) (38:78) [22:39:08:694]: Note: 1: 2205 2: 3: Error
MSI (s) (38:78) [22:39:08:694]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 16
MSI (s) (38:78) [22:39:08:694]: Note: 1: 2205 2: 3: Error
MSI (s) (38:78) [22:39:08:694]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 21
MSI (s) (38:78) [22:39:08:694]: Doing action: ProcessComponents
MSI (s) (38:78) [22:39:08:694]: Note: 1: 2205 2: 3: ActionText
Action ended 22:39:08: RemoveExistingProducts. Return value 1.
And at the very end I get
MSI (s) (38:78) [22:42:18:570]: Windows Installer installed the product. Product Name: Some Product. Product Version: 2.0.0.0. Product Language: 1033. Manufacturer: Some Inc.. Installation success or error status: 0.
Could you help me please? I ran out of any ideas.
The easiest way to author a major upgrade is to not author as many GUIDs as possible. See this example. Don't even author component GUIDs if you don't have to, i.e. if they contain more than one resource - but try to avoid that.
For example, this makes an easy major upgrade:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="Sample Product" Language="1033" Version="1.0.0.0" Manufacturer="Heath Stewart" UpgradeCode="f10d913e-7669-4962-aa3f-963425ecf10b">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="SampleProduct" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SampleProduct" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component>
<File Source="$(var.SampleApp.TargetPath)" />
</Component>
<Component>
<RegistryKey Root="HKLM" Key="Software\[Manufacturer]\[ProductName]">
<RegistryValue Name="InstallDir" Type="string" Value="[INSTALLFOLDER]" />
<RegistryValue Name="Version" Type="string" Value="[ProductVersion]" KeyPath="yes" />
</RegistryKey>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Notice that Product/#Id="*" is authored, and there's no package ID. There are really no good reasons to hardcode them, nor should you. Only the Product/#UpgradeCode should be hardcoded, and only if the root install folder is the same. You don't want to change the folder when the component GUIDs remain the same, of vice versa. It creates all sorts of shared component issues, which I've blogged a lot about in the past: https://devblogs.microsoft.com/setup/tag/shared-components/
Using WiX 3.11 I've developed a simple installation file which installs one DLL in the global assembly cache:
<Directory Id="TARGETDIR" Name="SourceDir">
<Component Id="CMP_ABC"
Guid="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
Permanent="no"
Shared="yes" >
<File Id="File_ABC"
Assembly=".net"
Source="ABC.dll"
KeyPath="yes"
Vital="yes"/>
</Component>
</Directory>
Installation works and the file is placed in the GAC_32 folder. When trying to uninstall the package and the file is currently in use by a different process (loaded in Visual Studio for example), the file does not get uninstalled and the WiX installation package does not return any error:
MSI (s) (68:EC) [09:24:58:210]: MsiProvideAssembly is returning: 1607
MSI (s) (68:EC) [09:24:58:429]: Assembly Error:The process cannot access the file because it is being used by another process.
MSI (s) (68:EC) [09:24:58:429]: Note: 1: 1935 2: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} 3: 0x80070020 4: IAssemblyCache 5: UninstallAssembly 6: ABC,version="X.YY.ZZ.0",culture="neutral",publicKeyToken="XXXXXXXXXXXXXXXX",processorArchitecture="x86"
MSI (s) (68:EC) [09:24:58:429]: Note: 1: 2205 2: 3: Error
MSI (s) (68:EC) [09:24:58:429]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1935
The last line however always shows
MSI (c) (30:88) [09:24:59:505]: Product: ABC -- Configuration completed successfully.
Is it possible to fail the uninstallation if the file is currently in use or for some other reason cannot be removed?
Major upgrade does not work correctly for following installation.
If the previous version of the application is installed on the current PC, then during major upgrade old version will be automatically uninstalled, but new version is not installed by some reason.
I need to run this new installation twice in order to uninstall the old version and then install new one.
But if I comment out the custom action LaunchApplication in the old version of installation, then there will not be any problems and old version will be uninstalled and new version will be installed during the one run of the new installation.
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Name='Foobar 2.0.0' Id='GUID' UpgradeCode='GUID'
Language='1033' Codepage='1252' Version='2.0.0' Manufacturer='Acme Ltd.'>
<Package Id='*' Keywords='Installer' Description="Acme's Foobar 2.0.0 Installer"
Comments='Foobar is a registered trademark of Acme Ltd.' Manufacturer='Acme Ltd.'
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
<Property Id="ALLUSERS" Secure="yes" Value="2" />
<Property Id="MSIINSTALLPERUSER" Secure="yes" Value="1" />
<Property Id='ApplicationFolderName' Value="Acme" />
<Property Id='WixAppFolder' Value="WixPerUserFolder" />
<Upgrade Id='GUID'>
<UpgradeVersion OnlyDetect='no' Property='PREVIOUSFOUND'
Minimum='0.0.1' IncludeMinimum='yes'
Maximum='2.0.0' IncludeMaximum='no' />
<UpgradeVersion OnlyDetect='yes' Property='NEWERFOUND'
Minimum='2.0.0' IncludeMinimum='no' />
</Upgrade>
<Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
<Property Id='DiskPrompt' Value="Acme's Foobar 2.0.0 Installation [1]" />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='Acme' Name='Acme'>
<Directory Id='INSTALLDIR' Name='Foobar 2.0.0'>
</Directory>
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="INSTALLDIR">
<Component Id='start.vbs' Guid='GUID'>
<File Id='start.vbs' Name='start.vbs' DiskId='1' Source='start.vbs' KeyPath='yes' >
</File>
</Component>
</DirectoryRef>
<Feature Id='Complete' Title='Foobar 2.0.0' Description='The complete package.'
Display='expand' Level='1' ConfigurableDirectory='INSTALLDIR'>
<Feature Id='MainProgram' Title='Program' Description='The main executable.' Level='1'>
<ComponentRef Id='start.vbs' />
</Feature>
</Feature>
<CustomAction Id='AlreadyUpdated' Error='[ProductName] has already been updated to 2.0.0 or newer.' />
<CustomAction Id='NoDowngrade' Error='A later version of [ProductName] is already installed.' />
<Property Id="WixShellExecTarget" Value="[#start.vbs]" />
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Execute="immediate"
Impersonate="yes" />
<InstallExecuteSequence>
<Custom Action='AlreadyUpdated' After='FindRelatedProducts'>SELFFOUND</Custom>
<Custom Action="NoDowngrade" After="FindRelatedProducts">NEWERFOUND</Custom>
<RemoveExistingProducts Before="InstallInitialize" />
<Custom Action="LaunchApplication" After="InstallFinalize"/>
</InstallExecuteSequence>
</Product>
</Wix>
What could be wrong with this installation or with custom action?
VBS procedure is empty.
start.vbs:
Private Function startServerSub()
End Function
startServerSub
What should be changed to have ability to uninstall previous version and install new one during one run of new application?
UPDATE:
I changed my installation a little.
1. RemoveExistingProducts will be executed after InstallInitialize.
2. Added SELFFOUND to Upgrade element.
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Name='TestApp 2.0.0' Id='GUID' UpgradeCode='GUID'
Language='1033' Codepage='1252' Version='2.0.0' Manufacturer='TestManufacturer Ltd.'>
<Package Id='*' Keywords='Installer' Description="TestManufacturer's TestApp 2.0.0 Installer"
Comments='TestAppis a registered trademark of TestManufacturer Ltd.' Manufacturer='TestManufacturer Ltd.'
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
<Property Id="ALLUSERS" Secure="yes" Value="2" />
<Property Id="MSIINSTALLPERUSER" Secure="yes" Value="1" />
<Property Id='ApplicationFolderName' Value="TestManufacturer" />
<Property Id='WixAppFolder' Value="WixPerUserFolder" />
<Upgrade Id='GUID'>
<UpgradeVersion OnlyDetect='yes' Property='SELFFOUND'
Minimum='2.0.0' IncludeMinimum='yes'
Maximum='2.0.0' IncludeMaximum='yes' />
<UpgradeVersion OnlyDetect='no' Property='PREVIOUSFOUND'
Minimum='0.0.1' IncludeMinimum='yes'
Maximum='2.0.0' IncludeMaximum='no' />
<UpgradeVersion OnlyDetect='yes' Property='NEWERFOUND'
Minimum='2.0.0' IncludeMinimum='no' />
</Upgrade>
<Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
<Property Id='DiskPrompt' Value="TestManufacturer's TestApp 2.0.0 Installation [1]" />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='TestManufacturer' Name='TestManufacturer'>
<Directory Id='INSTALLDIR' Name='TestApp 2.0.0'>
</Directory>
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="INSTALLDIR">
<Component Id='start.vbs' Guid='GUID'>
<File Id='start.vbs' Name='start.vbs' DiskId='1' Source='start.vbs' KeyPath='yes' >
</File>
</Component>
</DirectoryRef>
<Feature Id='Complete' Title='TestApp 2.0.0' Description='The complete package.'
Display='expand' Level='1' ConfigurableDirectory='INSTALLDIR'>
<Feature Id='MainProgram' Title='Program' Description='The main executable.' Level='1'>
<ComponentRef Id='start.vbs' />
</Feature>
</Feature>
<CustomAction Id='AlreadyUpdated' Error='[ProductName] has already been updated to 2.0.0 or newer.' />
<CustomAction Id='NoDowngrade' Error='A later version of [ProductName] is already installed.' />
<Property Id="WixShellExecTarget" Value="[#start.vbs]" />
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
DllEntry="WixShellExec"
Execute="immediate"
Impersonate="yes" />
<InstallExecuteSequence>
<Custom Action='AlreadyUpdated' After='FindRelatedProducts'>SELFFOUND</Custom>
<Custom Action="NoDowngrade" After="FindRelatedProducts">NEWERFOUND</Custom>
<RemoveExistingProducts After="InstallInitialize" />
<Custom Action="LaunchApplication" After="InstallFinalize"/>
</InstallExecuteSequence>
</Product>
</Wix>
Then I created 4 installation packages:
1. Version 1.0.0 with custom action LaunchApplication after InstallFinalize.
2. Version 1.0.0 without custom action LaunchApplication.
3. Version 2.0.0 with custom action LaunchApplication after InstallFinalize.
4. Version 2.0.0 without custom action LaunchApplication.
It is impossible to install any type of version 2.0.0, if version 1.0.0 with custom action was installed.
I tried to install version 2.0.0(without custom action) after version 1.0.0(with custom action):
=== Verbose logging started: 7/22/2015 18:37:48 Build type: SHIP UNICODE 5.00.7601.00 Calling process: C:\Windows\system32\msiexec.EXE ===
...
Action 18:37:48: FindRelatedProducts. Searching for related applications
Action start 18:37:48: FindRelatedProducts.
FindRelatedProducts: Found application: {GUID of 1.0.0}
MSI (c) (A8:A4) [18:37:48:221]: PROPERTY CHANGE: Adding PREVIOUSFOUND property. Its value is '{GUID of 1.0.0}'.
...
Action start 18:37:48: InstallInitialize.
MSI (s) (F4:0C) [18:37:48:299]: Machine policy value 'AlwaysInstallElevated' is 0
MSI (s) (F4:0C) [18:37:48:299]: User policy value 'AlwaysInstallElevated' is 0
MSI (s) (F4:0C) [18:37:48:299]: BeginTransaction: Locking Server
MSI (s) (F4:0C) [18:37:48:299]: Note: 1: 1715 2: TestApp 2.0.0
MSI (s) (F4:0C) [18:37:48:299]: Note: 1: 2262 2: Error 3: -2147287038
MSI (s) (F4:0C) [18:37:48:299]: Calling SRSetRestorePoint API. dwRestorePtType: 0, dwEventType: 102, llSequenceNumber: 0, szDescription: "Installed TestApp 2.0.0".
MSI (s) (F4:0C) [18:37:48:299]: The System Restore service is disabled. Returned status: 1058. GetLastError() returned: 1058
MSI (s) (F4:0C) [18:37:48:299]: Server not locked: locking for product {GUID of 2.0.0}
Action ended 18:37:48: InstallInitialize. Return value 1.
MSI (s) (F4:0C) [18:37:48:845]: Doing action: RemoveExistingProducts
MSI (s) (F4:0C) [18:37:48:845]: Note: 1: 2205 2: 3: ActionText
Action start 18:37:48: RemoveExistingProducts.
MSI (s) (F4:0C) [18:37:48:845]: Note: 1: 2262 2: Error 3: -2147287038
MSI (s) (F4:0C) [18:37:48:845]: Note: 1: 2262 2: Error 3: -2147287038
...
Action start 18:37:48: InstallFinalize.
...
MSI (s) (F4:AC) [18:37:48:939]: Verifying accessibility of file: start.vbs
MSI (s) (F4:AC) [18:37:48:939]: Note: 1: 2318 2:
MSI (s) (F4:AC) [18:37:48:939]: Note: 1: 2318 2:
...
Action ended 18:37:48: InstallFinalize. Return value 1.
MSI (s) (F4:AC) [18:37:48:939]: Doing action: LaunchApplication
MSI (s) (F4:AC) [18:37:48:939]: Note: 1: 2205 2: 3: ActionText
Action start 18:37:48: LaunchApplication.
MSI (s) (F4:AC) [18:37:48:939]: Creating MSIHANDLE (9) of type 790542 for thread 8108
MSI (s) (F4:B0) [18:37:48:939]: Invoking remote custom action. DLL: C:\Windows\Installer\MSIECB.tmp, Entrypoint: WixShellExec
MSI (s) (F4:24) [18:37:48:939]: Generating random cookie.
MSI (s) (F4:24) [18:37:48:939]: Created Custom Action Server with PID 8596 (0x2194).
MSI (s) (F4:48) [18:37:48:970]: Running as a service.
MSI (s) (F4:48) [18:37:48:970]: Hello, I'm your 32bit Impersonated custom action server.
MSI (s) (F4!74) [18:37:49:001]: Creating MSIHANDLE (10) of type 790541 for thread 1140
MSI (s) (F4!74) [18:37:49:001]: Creating MSIHANDLE (11) of type 790531 for thread 1140
MSI (s) (F4!74) [18:37:49:001]: Closing MSIHANDLE (11) of type 790531 for thread 1140
MSI (s) (F4!74) [18:37:49:001]: Creating MSIHANDLE (12) of type 790531 for thread 1140
WixShellExec: Error 0x80070002: ShellExec failed with return code 2
MSI (s) (F4!74) [18:37:49:001]: Closing MSIHANDLE (12) of type 790531 for thread 1140
MSI (s) (F4!74) [18:37:49:017]: Creating MSIHANDLE (13) of type 790531 for thread 1140
WixShellExec: Error 0x80070002: failed to launch target
MSI (s) (F4!74) [18:37:49:017]: Closing MSIHANDLE (13) of type 790531 for thread 1140
MSI (s) (F4!74) [18:37:49:017]: Closing MSIHANDLE (10) of type 790541 for thread 1140
CustomAction LaunchApplication returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
MSI (s) (F4:B0) [18:37:49:017]: Closing MSIHANDLE (9) of type 790542 for thread 8108
Action ended 18:37:49: LaunchApplication. Return value 3.
Action ended 18:37:49: INSTALL. Return value 3.
...
Property(N): WixShellExecTarget = [#start.vbs]
...
CustomAction returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
MSI (s) (F4:0C) [18:37:49:017]: Note: 1: 2262 2: Error 3: -2147287038
MSI (s) (F4:0C) [18:37:49:017]: Note: 1: 2262 2: Error 3: -2147287038
Action ended 18:37:49: RemoveExistingProducts. Return value 3.
MSI (s) (F4:0C) [18:37:49:017]: User policy value 'DisableRollback' is 0
MSI (s) (F4:0C) [18:37:49:017]: Machine policy value 'DisableRollback' is 0
MSI (s) (F4:0C) [18:37:49:017]: Executing op: Header(Signature=1397708873,Version=500,Timestamp=1190565049,LangId=1033,Platform=0,ScriptType=2,ScriptMajorVersion=21,ScriptMinorVersion=4,ScriptAttributes=0)
MSI (s) (F4:0C) [18:37:49:017]: Executing op: DialogInfo(Type=0,Argument=1033)
MSI (s) (F4:0C) [18:37:49:017]: Executing op: DialogInfo(Type=1,Argument=TestApp 1.0.0)
MSI (s) (F4:0C) [18:37:49:017]: Executing op: RollbackInfo(,RollbackAction=Rollback,RollbackDescription=Rolling back action:,RollbackTemplate=[1],CleanupAction=RollbackCleanup,CleanupDescription=Removing backup files,CleanupTemplate=File: [1])
MSI (s) (F4:0C) [18:37:49:017]: Executing op: SetTargetFolder(Folder=C:\Users\user1\AppData\Local\Programs\TestManufacturer\TestApp 1.0.0\)
MSI (s) (F4:0C) [18:37:49:017]: Executing op: FileCopy(SourceName=C:\Config.Msi\1bc1cc05.rbf,,DestName=C:\Users\user1\AppData\Local\Programs\TestManufacturer\TestApp 1.0.0\start.vbs,Attributes=40992,FileSize=331,PerTick=0,,VerifyMedia=0,ElevateFlags=1,,,,,,,InstallMode=4194308,,,,,,,)
MSI (s) (F4:0C) [18:37:49:017]: File: C:\Users\user1\AppData\Local\Programs\TestManufacturer\TestApp 1.0.0\start.vbs; To be installed; Won't patch; No existing file
...
MSI (s) (F4:0C) [18:37:49:126]: Executing op: End(Checksum=0,ProgressTotalHDWord=0,ProgressTotalLDWord=0)
MSI (s) (F4:0C) [18:37:49:126]: Error in rollback skipped. Return: 5
MSI (s) (F4:0C) [18:37:49:126]: No System Restore sequence number for this installation.
MSI (s) (F4:0C) [18:37:49:126]: Unlocking Server
MSI (s) (F4:0C) [18:37:49:173]: Note: 1: 2205 2: 3: Control
Action ended 18:37:49: INSTALL. Return value 3.
...
MSI (s) (F4:0C) [18:37:49:173]: MainEngineThread is returning 1603
MSI (s) (F4:78) [18:37:49:173]: RESTART MANAGER: Session closed.
MSI (s) (F4:78) [18:37:49:173]: RESTART MANAGER: Session closed.
MSI (s) (F4:78) [18:37:49:173]: No System Restore sequence number for this installation.
MSI (s) (F4:78) [18:37:49:173]: User policy value 'DisableRollback' is 0
MSI (s) (F4:78) [18:37:49:173]: Machine policy value 'DisableRollback' is 0
MSI (s) (F4:78) [18:37:49:173]: Incrementing counter to disable shutdown. Counter after increment: 0
MSI (s) (F4:78) [18:37:49:173]: Note: 1: 1402 2: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\Rollback\Scripts 3: 2
MSI (s) (F4:78) [18:37:49:173]: Note: 1: 1402 2: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\Rollback\Scripts 3: 2
MSI (s) (F4:78) [18:37:49:189]: Decrementing counter to disable shutdown. If counter >= 0, shutdown will be denied. Counter after decrement: -1
MSI (s) (F4:78) [18:37:49:189]: Restoring environment variables
MSI (s) (F4:78) [18:37:49:189]: Destroying RemoteAPI object.
MSI (s) (F4:24) [18:37:49:189]: Custom Action Manager thread ending.
MSI (c) (A8:A4) [18:37:49:189]: Back from server. Return value: 1603
MSI (c) (A8:A4) [18:37:49:189]: Decrementing counter to disable shutdown. If counter >= 0, shutdown will be denied. Counter after decrement: -1
MSI (c) (A8:A4) [18:37:49:189]: PROPERTY CHANGE: Deleting SECONDSEQUENCE property. Its current value is '1'.
Action ended 18:37:49: ExecuteAction. Return value 3.
Action ended 18:37:49: INSTALL. Return value 3.
...
=== Logging stopped: 7/22/2015 18:37:49 ===
MSI (c) (A8:A4) [18:37:49:189]: Note: 1: 1708
MSI (c) (A8:A4) [18:37:49:189]: Note: 1: 2262 2: Error 3: -2147287038
MSI (c) (A8:A4) [18:37:49:189]: Note: 1: 2262 2: Error 3: -2147287038
MSI (c) (A8:A4) [18:37:49:189]: Product: TestApp 2.0.0 -- Installation failed.
As I understand the root cause problem is that I do not use "NOT Installed AND NOT UPGRADINGPRODUCTCODE" condition in custom action LaunchApplication.
<Custom Action="LaunchApplication" After="InstallFinalize">NOT Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
In this case installer during installation of new version removes the old version, and then tries to run custom action LaunchApplication from the old version, but all files are already removed. That's why installation fails.
I added condition "NOT Installed AND NOT UPGRADINGPRODUCTCODE" to LaunchApplication and now it is possible to perform major upgrade of my application.
But I am not sure which condition should I use - "NOT Installed AND NOT UPGRADINGPRODUCTCODE" or "NOT Installed".
I need to run custom action LaunchApplication during first installation and during all major upgrades.
Not sure this is an answer but there's too much for a comment.
First, do the upgrades with verbose logging, msiexec.exe command with a /L*vx to see what's going on because there are a number of things that don't make sense.
Your custom action is after InstallFinalize, which means it is after the install has completed and committed so it cannot cause the the upgrade to fail.
Your RemoveExistingProducts is before InstallInitialize. This means that it is outside the install transaction that starts at InstallInitialize. It really needs to be just after InstallInitialize to be included in the transation because currently it is independent of your new product install, and so you can get any combination of the remove failing or working and your install failing or working and you can end up with an indeterminate set of products on your system. None, noth or one of them.
What's SELFFOUND? I'd expect an Upgrade element to refer to it but there isn't one. In general you should look at the MajorUpgrade element and set attributes such as AllowSameVersionUpgrades to No if you want to prevent installing a major upgrade with the same version. If SELFFOUND is intended to prevent installing the same MSI file twice, then don't bother because Windows won't let you do that anyway.
So there's not really enough info to see what's going on, but that CA can't be responsible. The most likely explanation is that the first upgrade fails - it removes the older product, then your new install fails, and because the remove is outside the transaction all you see is the remove working and your install failing. When you install again it's a fresh system, that's the main difference. Check the logs!
I did everything as explained in tutorial, but my executable wasn't launched after product installation completed.
There is a nuance that my executable is delivered with .msm module, so in .wxs file for .msi I do the following to launch application:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product>
<!-- I omit here features and elements which are irrelevant to the question-->
<Feature Id="Configurator" Display="hidden" Level="1">
<MergeRef Id="MergeConfigurator"/>
</Feature>
<UI>
<UIRef Id="WixUI_Minimal"/>
<Publish Dialog="ExitDialog" Control="Finish" Event="DoAction"
Value="LaunchConfigurator">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
</UI>
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="!(loc.ExitDlgCheckBoxText)" />
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1"/>
<Property Id="WixShellExecTarget" Value="[#SystemConfigurator.exe.81c0fa8f-9a8e-49d8-9dc2-ce01ca163146]" />
<CustomAction Id="LaunchConfigurator" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
</Product>
<Fragment>
<DirectoryRef Id="TARGETDIR">
<Merge Id="MergeConfigurator" SourceFile="$(var.MergeModulesPath)\ConfiguratorSetup_$(var.Platform).msm" DiskId="1" Language="1033"/>
</DirectoryRef>
</Fragment>
</Wix>
For the property with Id=WixShellExecTarget I have tried to pass value both with and without GUID (this is Package/#Id of .msm with my executable).
I opened my .msi with Orca and saw the exact ID of my executable (it's SystemConfigurator.exe.81c0fa8f-9a8e-49d8-9dc2-ce01ca163146, that's why I pass this very value).
But what it's wrong?
I logged installation process using /l*v option, and there is a portion from log:
Action 18:47:57: LaunchConfigurator.
Action start 18:47:57: LaunchConfigurator.
MSI (c) (54:68) [18:47:58:106]: Invoking remote custom action. DLL: C:\Users\AAGENO~1\AppData\Local\Temp\MSIB233.tmp, Entrypoint: WixShellExec
MSI (c) (54:08) [18:47:58:106]: Cloaking enabled.
MSI (c) (54:08) [18:47:58:106]: Attempting to enable all disabled privileges before calling Install on Server
MSI (c) (54:08) [18:47:58:106]: Connected to service for CA interface.
MSI (c) (54!04) [18:47:58:476]: Note: 1: 2715 2: SystemConfigurator.Client.exe.81c0fa8f-9a8e-49d8-9dc2-ce01ca163146
MSI (c) (54!04) [18:47:58:476]: Note: 1: 2715 2: SystemConfigurator.Client.exe.81c0fa8f-9a8e-49d8-9dc2-ce01ca163146
Action ended 18:47:58: LaunchConfigurator. Return value 3.
MSI (c) (54:34) [18:47:58:476]: Note: 1: 2205 2: 3: Error
MSI (c) (54:34) [18:47:58:476]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 2896
DEBUG: Error 2896: Executing action LaunchConfigurator failed.
Error 2715 means that the file key you're using isn't actually in the file table. Assuming it's referring to SystemConfigurator.exe.81c0fa8f-9a8e-49d8-9dc2-ce01ca163146 I would open the MSI file with Orca and see if that is the correct value AND keep in mind that Windows Installer proiperties are case-sensitive so if if it really is upper-case then use upper case. Make sure it really is a dash too, and not an underscore.
This is my .wxs file
Particularly I managed to install a service as a LocalSystem user, and started it:
<!-- Directory where [prey]/versions/[version] will be -->
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="Prey">
<Directory Id="VersionsDir" Name="versions">
<Directory Id="VersionDir" Name="$(var.ProductVersion)">
<Directory Id="BinDir" Name="bin">
<Directory Id="BinWindowsDir" Name="windows">
<Component Id="CronServiceExe"
Guid="ECC25B2A-FB2E-425A-92AD-DCF1D34204FF">
<File Id="file_8FF048AD40124B9F9C07126F2C14A765"
Checksum="yes"
KeyPath="yes"
Source="source-msi\versions\0.10.0\bin\windows\cronsvc.exe" />
<ServiceInstall Id="CronServiceInstaller"
Type="ownProcess"
Vital="yes"
Name="CronService"
DisplayName="Cron Service"
Start="auto"
Account="LocalSystem"
ErrorControl="normal"
Interactive="no">
</ServiceInstall>
<ServiceControl Id="StartService"
Start="install"
Stop="both"
Remove="uninstall"
Name="CronService"
Wait="yes" />
</Component>
<Component Id="CronServiceDll"
Guid="75C4129B-C28A-45A8-9F06-CB496259FE7F">
<File Id="file_11D016207EA34826A20A52524A3A82BC"
Checksum="yes"
KeyPath="yes"
Source="source-msi\versions\0.10.0\bin\windows\Cronsvclib.dll" />
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
And it runs fine. Everything is OK, except when I get to uninstall the product. Because despite being asked in an UAC dialog I get (Screenshot), the installer insist that I don't have permissions to stop the service.
Here is the screenshot of the Error, which says:
Service 'Cron Service' (CronService) could not be stopped. Verify that you have sufficient privileges to stop system services.
And, here is the specific logs (I'm uninstalling with /L*v option to get verbose logs). You can get the full file in this gist.
Lines 2220 - 2226
MSI (s) (90:80) [19:11:54:953]: Note: 1: 2205 2: 3: Icon
MSI (s) (90:80) [19:11:54:953]: Note: 1: 2205 2: 3: TypeLib
MSI (s) (90:80) [19:11:54:953]: Note: 1: 2727 2:
MSI (s) (90:80) [19:11:54:973]: RESTART MANAGER: Detected that the service CronService will be stopped due to a service control action authored in the package before the files are updated. So, we will not attempt to stop this service using Restart Manager
MSI (s) (90:80) [19:11:54:973]: Note: 1: 2727 2:
MSI (s) (90:80) [19:11:54:973]: Doing action: InstallInitialize
MSI (s) (90:80) [19:11:54:973]: Note: 1: 2205 2: 3: ActionText
Action ended 19:11:54: InstallValidate. Return value 1.
Lines 4624 - 4635
MSI (s) (90:80) [19:11:57:196]: Executing op: ActionStart(Name=StopServices,Description=Stopping services,Template=Service: [1])
MSI (s) (90:80) [19:11:57:196]: Executing op: ProgressTotal(Total=1,Type=1,ByteEquivalent=1300000)
MSI (s) (90:80) [19:11:57:196]: Executing op: ServiceControl(,Name=CronService,Action=2,Wait=1,)
MSI (s) (90:80) [19:12:27:239]: Note: 1: 2205 2: 3: Error
MSI (s) (90:80) [19:12:27:239]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1921
MSI (s) (90:80) [19:16:38:940]: Note: 1: 2205 2: 3: Error
MSI (s) (90:80) [19:16:38:940]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1709
MSI (s) (90:80) [19:16:38:940]: Product: Prey Anti-theft -- Error 1921. Service 'Cron Service' (CronService) could not be stopped. Verify that you have sufficient privileges to stop system services.
MSI (s) (90:80) [19:17:08:983]: Note: 1: 2205 2: 3: Error
MSI (s) (90:80) [19:17:08:983]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1921
MSI (c) (48:84) [19:12:27:239]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg
Given all that information. I infere that somewhere I have to manage to start my MSI as an administrator. Or not?
That's my problem:
Is there a way to set up my .msi installer as an "admin only" one? (If that choice does exist).
The weird thing is that all posts and google results I'm getting are about problems INSTALLING and STARTING the service, rather than STOPPING it. So I'm in a dead end.
Please, all help will be very useful and appreciated.
The error message includes the suggestion that it's a permissions problem. That's rarely the case, since installing services requires elevated permissions to begin with. Failure to stop a service is usually as simple as the service not responding to the stop request quickly enough. Does CronService implement the service interface to respond to stop requests? Neither MSI nor Windows will kill a service process to stop it.