I have WiX 4.0 project. I'm using Util to create Windows EventLog event source. The problem is, the Registry entry to the EventMessageFile gets the path prepended with "#%". Therefore, the EventLog will display errors for events created by this event source.
Code to create the EventSource:
<Include xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
<PropertyRef Id="NETFRAMEWORK40FULLINSTALLROOTDIR64"/>
<PropertyRef Id="NETFRAMEWORK40CLIENTINSTALLROOTDIR64"/>
<PropertyRef Id="NETFRAMEWORK40CLIENT"/>
<PropertyRef Id="NETFRAMEWORK40FULL"/>
.
.
.
<ComponentGroup Id="EventLog" Directory="INSTALLFOLDER">
<!-- 64 bit -->
<Component Id="CreateEventSource64BitFullNet4" DiskId="1" Guid="{9978592B-3E96-4AAA-B7A6-34B0421FDD02}" Condition="NETFRAMEWORK40FULLINSTALLROOTDIR64 AND VersionNT64">
<CreateFolder/>
<util:EventSource Log="Application" Name="ScholarshipSapQueue" EventMessageFile="[NETFRAMEWORK40FULLINSTALLROOTDIR64]EventLogMessages.dll" />
</Component>
<Component Id="CreateEventSource64BitClientNet4" DiskId="1" Guid="{B42622A1-B7C0-48CB-B306-65F3558C6678}" Condition="NETFRAMEWORK40CLIENTINSTALLROOTDIR64 AND NOT NETFRAMEWORK40FULL AND VersionNT64">
<CreateFolder/>
<util:EventSource Log="Application" Name="ScholarshipSapQueue" EventMessageFile="[NETFRAMEWORK40CLIENTINSTALLROOTDIR64]EventLogMessages.dll" />
</Component>
</ComponentGroup>
</Include>
Looking at the log file from installing the MSI, the value of the properties does look correct:
MSI (c) (B4:68) [10:05:27:331]: PROPERTY CHANGE: Adding NETFRAMEWORK40FULLINSTALLROOTDIR64 property. Its value is 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\'.
But the Registry entry is wrong:
MSI (s) (3C:28) [10:05:33:008]: Executing op: ActionStart(Name=WriteRegistryValues,Description=Writing system registry values,Template=Key: [1], Name: [2], Value: [3])
Action 10:05:33: WriteRegistryValues. Writing system registry values
MSI (s) (3C:28) [10:05:33:014]: Executing op: ProgressTotal(Total=1,Type=1,ByteEquivalent=13200)
MSI (s) (3C:28) [10:05:33:014]: Executing op: RegOpenKey(Root=-2147483646,Key=SYSTEM\CurrentControlSet\Services\EventLog\Application\ScholarshipSapQueue,,BinaryType=0,,)
MSI (s) (3C:28) [10:05:33:014]: Executing op: RegAddValue(Name=EventMessageFile,Value=##%C:\Windows\Microsoft.NET\Framework64\v4.0.30319\EventLogMessages.dll,)
WriteRegistryValues: Key: \SYSTEM\CurrentControlSet\Services\EventLog\Application\ScholarshipSapQueue, Name: EventMessageFile, Value: ##%C:\Windows\Microsoft.NET\Framework64\v4.0.30319\EventLogMessages.dll
That smells like a WiX v4 bug. Please open an issue at https://github.com/wixtoolset/issues/issues/new/choose.
Related
MajorUpgrade element is scheduled after install finalize in our product's MSI:
<MajorUpgrade Schedule="afterInstallFinalize" AllowSameVersionUpgrades="yes" DowngradeErrorMessage="!(loc.NewerVersionInstalled)" IgnoreRemoveFailure="no"/>
There are some folders written by app at runtime that we want to keep on upgrade and only remove on uninstall initiated from Add/Remove programs. So we use this condition: (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL").
<DirectoryRef Id="TARGETDIR">
...
<Directory Id="LocalAppDataFolder"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Component Id="CreatePrivateMyAppFolder" Guid="FA1F4375-71DA-4E61-9A02-BE7FD2D4C87D">
<RegistryValue Root="HKCU" Key="Software\Company\Product" Name="PrivateFolderMyApp" Type="string" Value="[PrivateDataMyApp]" KeyPath="yes"/>
</Component>
<Component Id="RemoveLocalAppDataMyAppUninstall" Guid="*" Transitive="yes">
<Condition><![CDATA[(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")]]></Condition>
<RegistryValue Root="HKCU" Key="Software\Company\Product" Name="PrivateFolderMyApp" Type="string" Value="[PrivateDataMyApp]" KeyPath="yes"/>
<util:RemoveFolderEx On="uninstall" Property="PRIVATEMYAPPFOLDER"/>
</Component>
<Directory></Directory>
...
</Directory>
</DirectoryRef>
I need to change the MajorUpgrade schedule from afterInstallFinalize to afterInstallInitialize for some new requirements. I install version 1 with new schedule. Then install versions 2. However during uninstall sequence of version 2, folders written by runtime are being removed.
From logs, both UPGRADINGPRODUCTCODE and REMOVE properties are set for the uninstall part. Based on that the condition (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") should evaluate to false for the component RemoveLocalAppDataMyAppUninstall.
MSI (s) (C4:58) [22:58:11:060]: Doing action: RemoveExistingProducts
Action 22:58:11: RemoveExistingProducts. Removing applications
Action start 22:58:11: RemoveExistingProducts.
RemoveExistingProducts: Application: {8F890AE0-BE0A-5ED9-B406-F7459B3390F9}, Command line: UPGRADINGPRODUCTCODE={70705091-36C8-5619-9E35-73E455CA17F7} CLIENTPROCESSID=4756 CLIENTUILEVEL=0 REMOVE=ALL
....
MSI (s) (C4:4C) [22:58:11:076]: Command Line: UPGRADINGPRODUCTCODE={70705091-36C8-5619-9E35-73E455CA17F7} CLIENTPROCESSID=4756 CLIENTUILEVEL=0 REMOVE=ALL
MSI (s) (C4:4C) [22:58:11:279]: Dir (target): Key: _PRIVATEMYAPPFOLDER_4 , Object: C:\Users\Windows_10\AppData\Local\MyApp\
MSI (s) (C4:4C) [22:58:11:279]: Dir (target): Key: _PRIVATEMYAPPFOLDER_3 , Object: C:\Users\Windows_10\AppData\Local\MyApp\1753de9b-15a7-49b1-8715-f93a967d12e5\
...
MSI (s) (C4:4C) [22:58:11:826]: Doing action: InstallValidate
MSI (s) (C4:4C) [22:58:11:826]: Component: RemoveLocalAppDataMyAppUninstall; Installed: Local; Request: Absent; Action: Absent
...
MSI (s) (C4:4C) [22:58:12:732]: Doing action: RemoveFiles
MSI (s) (C4:4C) [22:58:12:919]: Counted 6 foreign folders to be removed.
MSI (s) (C4:4C) [22:58:12:919]: Removing foreign folder: C:\Users\Windows_10\AppData\Local\MyApp\1753de9b-15a7-49b1-8715-f93a967d12e5\
MSI (s) (C4:4C) [22:58:12:919]: Removing foreign folder: C:\Users\Windows_10\AppData\Local\MyApp\
Any help in understanding why the condition is being applied during uninstall will be appreciated.
Component conditions only affect install and, with the transitive bit set, reinstall. Uninstall isn't affected. RemoveFolderEx in WiX v4 has a Condition that lets you do what you want to do.
I'm using wix tool 3.11 to create a msi which install a service. The installer runs a Custom Action and returns vars to wix to write to registry (HKLM). The service starts and try to read the registry but it can't be done and it fails. If I wrote the registry manually the installer works perfectly.
Error message from msi logs:
Product: Installer-- Error 1920. Service 'XPTO Server' (xpto_server) failed to start. Verify that you have sufficient privileges to start system services.
My Wix XML:
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" InstallPrivileges="elevated" />
...
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="CMP_RegistryEntries" Guid="xxxxxxxxx" >
<RegistryKey Root="HKLM" Key="SOFTWARE\XPTOInc\XPTO\XPTOServer\BetaVersion">
<RegistryValue Name="token" Action="write" Value="[TOKEN]" Type="string" KeyPath="yes" />
<RegistryValue Name="[IDENTIFIER_TYPE]" Action="write" Value="[INSTALLEDID]" Type="string" />
<RegistryValue Name="installDir" Action="write" Value="[INSTALLFOLDER]" Type="string" />
</RegistryKey>
</Component>
<Component Id="CMP_XPTOServerEXE" Guid="xxxxxx">
<File Id="FILE_XPTOServerEXE" Name="xpto-server.exe" Source="Work\xpto-server.exe" KeyPath="yes" />
<ServiceInstall Id="InstallExporterService" Name="xpto_server" DisplayName="XPTO Server" Description="Read data from Registry and do simple stuff" ErrorControl="normal" Start="auto" Type="ownProcess" />
<ServiceControl Id="ServiceStateControl" Name="xpto_server" Remove="uninstall" Start="install" Stop="both" />
</Component>
</ComponentGroup>
EDIT: When I manually wrote the vars to Registry, the service installs with msi pkg or running with sc.exe
EDIT 2: Here follows the log where sets the registry and then star service
MSI (s) (70:74) [15:40:37:560]: Created Custom Action Server with PID 16808 (0x41A8).
MSI (s) (70:E4) [15:40:37:613]: Running as a service.
MSI (s) (70:E4) [15:40:37:615]: Hello, I'm your 32bit Elevated Non-remapped custom action server.
MSI (s) (70:38) [15:40:37:973]: Executing op: ActionStart(Name=WriteRegistryValues,Description=Writing system registry values,Template=Key: [1], Name: [2], Value: [3])
Action 15:40:37: WriteRegistryValues. Writing system registry values
MSI (s) (70:38) [15:40:37:974]: Executing op: ProgressTotal(Total=3,Type=1,ByteEquivalent=13200)
MSI (s) (70:38) [15:40:37:975]: Executing op: RegOpenKey(Root=-2147483646,Key=SOFTWARE\XPTOInc\XPTO\XPTOServer\BetaVersion,,BinaryType=0,,)
MSI (s) (70:38) [15:40:37:975]: Executing op: RegAddValue(Name=token,Value=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,)
WriteRegistryValues: Key: \SOFTWARE\XPTOInc\XPTO\XPTOServer\BetaVersion, Name: token, Value: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
MSI (s) (70:38) [15:40:37:976]: Executing op: RegAddValue(Name=envId,Value=xxxxxxxxxxxxxxxxxxxxxxxx,)
WriteRegistryValues: Key: \SOFTWARE\XPTOInc\XPTO\XPTOServer\BetaVersion, Name: envId, Value: xxxxxxxxxxxxxxxxxxxxxxxxx
MSI (s) (70:38) [15:40:37:976]: Executing op: RegAddValue(Name=installDir,Value=C:\Program Files (x86)\XPTOInc\XPTO\XPTO Server Beta\,)
WriteRegistryValues: Key: \SOFTWARE\XPTOInc\XPTO\XPTOServer\BetaVersion, Name: installDir, Value: C:\Program Files (x86)\XPTOInc\XPTO\XPTO Server Beta\
MSI (s) (70:38) [15:40:37:977]: Executing op: ActionStart(Name=InstallServices,Description=Installing new services,Template=Service: [2])
Action 15:40:37: InstallServices. Installing new services
MSI (s) (70:38) [15:40:37:977]: Executing op: ProgressTotal(Total=1,Type=1,ByteEquivalent=1300000)
MSI (s) (70:38) [15:40:37:978]: Executing op: ServiceInstall(Name=xpto_server,DisplayName=XPTOServer,ImagePath="C:\Program Files (x86)\XPTOInc\XPTO\XPTO Server Beta\xpto-server.exe",ServiceType=16,StartType=2,ErrorControl=1,,Dependencies=[~],,,Password=**********,Description=Read data from Registry and do simple stuff,,)
InstallServices: Service:
MSI (s) (70:38) [15:40:37:980]: Executing op: ActionStart(Name=StartServices,Description=Starting services,Template=Service: [1])
Action 15:40:37: StartServices. Starting services
MSI (s) (70:38) [15:40:37:981]: Executing op: ProgressTotal(Total=1,Type=1,ByteEquivalent=1300000)
MSI (s) (70:38) [15:40:37:981]: Executing op: ServiceControl(,Name=xpto_server,Action=1,,)
StartServices: Service: XPTO Server
Error 1920. Service 'XPTO Server' (xpto_server) failed to start. Verify that you have sufficient privileges to start system services.
Solution: The problem in this case was that the registry keys were not found in the expected location in the registry due to 32-bit / 64-bit issues.
64-bit section: HKEY_LOCAL_MACHINE\SOFTWARE\Company\App - MyValue
32 bit section: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Company\App - MyValue
End of answer. Leaving debugging efforts in place below though:
Round 1:
Maybe try to read these two recent answers and check if anything rings a bell:
Wix Service Installer sometimes fails to install or start
Wix - ServiceControl start takes four minutes to fail, should be 30 sec
What does it say in the event viewer? (Windows + R eventvwr and OK)
Round 2:
Bitness: Are you sure you are reading from the right location in the registry? Are you installing a 32-bit MSI or a 64-bit MSI? (looks like 32-bit)
64-bit section: HKEY_LOCAL_MACHINE\SOFTWARE\Company\App
32 bit section: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Company\App
Permissions: Did you check the permissions for the registry keys and values your setup writes using regedit.exe to inspect? Right click => Permissions (have to ask).
Privileges: What account do you use to run the service? It sort of looks like standard LocalSystem? The account needs the SeServiceLogonRight privilege. See second line on section above for details.
Logging: Do you use log4net or some other logging feature in your service? Did you try the verbose, debug MSI logging found in the first link in the top section?
Here's my scenario:
Using Wix 3.6
Using the WixUI_Advanced dialog set (adds ability able to control individual features during install)
Setting NeverOverwrite="yes" for a web.config component (so that local changes post-install aren't lost)
However, the installer still seems to remove and re-install the web.config file during upgrade.
Best I can tell the WixUI_Advanced dialog set has something like the following configured:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize"/>
</InstallExecuteSequence>
Here are logs snippets from the install:
MSI (s) (74:8C) [18:37:00:959]: Executing op: ActionStart(Name=InstallInitialize,,)
Action 18:37:00: InstallInitialize.
...
Action 18:37:00: ProcessComponents. Updating component registration
...
Action 18:37:00: UnpublishFeatures. Unpublishing Product Features
...
UnpublishFeatures: Feature: ProductFeature
...
UnpublishFeatures: Feature: AdditionalFeature
...
MSI (s) (74:8C) [18:37:00:967]: Executing op: ActionStart(Name=RemoveFiles,Description=Removing files,Template=File: [1], Directory: [9])
Action 18:37:00: RemoveFiles. Removing files
MSI (s) (74:8C) [18:37:00:967]: Executing op: ProgressTotal(Total=2,Type=1,ByteEquivalent=175000)
MSI (s) (74:8C) [18:37:00:967]: Executing op: SetTargetFolder(Folder=C:\Program Files (x86)\MyTestApp\WebApp\)
MSI (s) (74:8C) [18:37:00:967]: Executing op: FileRemove(,FileName=web.config,,ComponentId={B4A12A8F-56A3-4DD1-A0BA-B9C39EB305FD})
RemoveFiles: File: web.config, Directory: C:\Program Files (x86)\MyTestApp\WebApp\
MSI (s) (74:8C) [18:37:00:968]: Verifying accessibility of file: web.config
MSI (s) (74:8C) [18:37:00:969]: Note: 1: 2318 2:
MSI (s) (74:8C) [18:37:00:969]: Note: 1: 2318 2:
MSI (s) (74:8C) [18:37:00:969]: Executing op: FileRemove(,FileName=somefile.txt,,ComponentId={B835CEF5-1A84-4C37-8CB0-BE983BAF73F9})
RemoveFiles: File: somefile.txt, Directory: C:\Program Files (x86)\MyTestApp\WebApp\
MSI (s) (74:8C) [18:37:00:970]: Verifying accessibility of file: somefile.txt
MSI (s) (74:8C) [18:37:00:970]: Note: 1: 2318 2:
MSI (s) (74:8C) [18:37:00:970]: Note: 1: 2318 2:
MSI (s) (74:8C) [18:37:00:971]: Executing op: ActionStart(Name=PublishProduct,Description=Publishing product information,)
Action 18:37:00: PublishProduct. Publishing product information
...
Action 18:37:00: RollbackCleanup. Removing backup files
RollbackCleanup: File: C:\Config.Msi\7cd65c.rbf
RollbackCleanup: File: C:\Config.Msi\7cd65d.rbf
MSI (s) (74:8C) [18:37:00:980]: Note: 1: 2318 2:
MSI (s) (74:8C) [18:37:00:981]: Note: 1: 2318 2:
MSI (s) (74:8C) [18:37:00:981]: No System Restore sequence number for this installation.
MSI (s) (74:8C) [18:37:00:981]: Unlocking Server
MSI (s) (74:8C) [18:37:00:985]: PROPERTY CHANGE: Deleting UpdateStarted property. Its current value is '1'.
Action ended 18:37:00: InstallFinalize. Return value 1.
Action ended 18:37:00: INSTALL. Return value 1.
As you can see it removes the web.config file after InstallInitialize
When I try to change the wxs file, adding:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallFinalize"/>
</InstallExecuteSequence>
I get:
error LGHT0091: Duplicate symbol 'WixAction:InstallExecuteSequence/RemoveExistingProducts' found. This typically means that an Id is duplicated. Check to make sure all your identifiers of a given type (File, Component, Feature) are unique.
Here is the Product.wxs file I'm using:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product Id="*" Name="MyTestInstaller" Language="1033" Version="1.0.9.0" Manufacturer="Acme, Inc" UpgradeCode="6ca3779c-e8ce-42e8-bf81-3166bd96e585">
<Package Id="*" InstallerVersion="301" Compressed="yes" InstallScope="perMachine" Platform="x64" InstallPrivileges="elevated" />
<Upgrade Id="6ca3779c-e8ce-42e8-bf81-3166bd96e585">
<UpgradeVersion Minimum="1.0.9.0" OnlyDetect="yes" Property="NEWERVERSIONDETECTED" />
<UpgradeVersion OnlyDetect="no" Minimum="0.0.0.0" IncludeMinimum="yes" Maximum="1.0.9.0" Property="OLDERVERSIONBEINGUPGRADED" IgnoreRemoveFailure="yes">
</UpgradeVersion>
</Upgrade>
<Condition Message="A later version of [ProductName] is already installed.">NOT NEWERVERSIONDETECTED</Condition>
<Media Id="1" Cabinet="myapp.cab" EmbedCab="yes" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Feature Id="ProductFeature" Title="MyTestInstaller" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<Feature Id="AdditionalFeature" Title="Additional Features" Level="10">
<ComponentGroupRef Id="AdditionalComponents"/>
</Feature>
<Property Id="ApplicationFolderName" Value="MyTestApp"/>
<!-- BEGIN: DISABLE THE Per User Install -->
<Property Id="WixAppFolder" Value="WixPerMachineFolder"/>
<WixVariable Id="WixUISupportPerUser" Value="0" />
<!-- END: DISABLE THE Per User Install -->
<UI>
<UIRef Id="WixUI_Advanced" />
</UI>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="APPLICATIONFOLDER" Name="ICS">
<Directory Id="WebApp" Name="WebApp">
<Component Id="WEB.CONFIG" Guid="B4A12A8F-56A3-4DD1-A0BA-B9C39EB305FD" DiskId="1" NeverOverwrite="yes">
<File Id="WEB.CONFIG" Name="web.config" Source="web.config" KeyPath="yes"/>
</Component>
<Component Id="SOMEFILE" DiskId="1" Guid="B835CEF5-1A84-4C37-8CB0-BE983BAF73F9">
<File Id="SOMEFILE" Name="somefile.txt" Source="somefile.txt" KeyPath="yes"/>
<util:XmlConfig Id="WEBCFG_1" File="[WebApp]Web.config" Action="create" Node="element" Name="module" ElementPath="/configuration/autofac/modules" VerifyPath="/configuration/autofac/modules/module[\[]#type='ICS.Automation.JDE.Base.JDEModule, ICS.Automation.JDE.Base'[\]]" Sequence="10" On ="install" />
<util:XmlConfig Id="WEBCFG_2" ElementId="WEBCFG_1" File="[WebApp]Web.config" Name="type" Value="MyDll, MyDll" Sequence="11" />
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents">
<ComponentRef Id="WEB.CONFIG"/>
</ComponentGroup>
<ComponentGroup Id="AdditionalComponents">
<ComponentRef Id="SOMEFILE"/>
</ComponentGroup>
</Fragment>
</Wix>
How can I change the RemoveExistingProducts to come after InstallFinalize?
Ultimately, I just need this file to never be overwritten.
Thanks!
The MajorUpgrade tag is the preferred way to do the upgrade, and that will sequence RemoveExistingProducts (REP) wherever you specify - that should simplify some of this. There's no reason for the UI to move REP around.
The default for scheduling REP is after InstallValidate, which is basically a uninstall of the old product followed by an install of the upgrade, so it's not so much an update/overwrite of the config file as an uninstall/remove followed by a fresh install.
If the REP is scheduled afterInstallExecute then overwrite rules apply during the upgrade (because the upgrade "overwrites" the existing installed product before it's uninstalled). The web.config file just needs to have the same component id in both the old and new products, and if it has indeed been changed after it was installed then the overwrite rules should mean it won't be overwritten.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa370531(v=vs.85).aspx
In other words just use the major upgrade element with afterInstallExecute, have the same component ids in both old and new resources (files etc) and the web.config file shouldn't be overwritten, and you don't need to set neveroverwrite.
In my opinion having REP afterInstallExecute is better than after InstallFinalize because the latter is outside the install transaction, so the upgrade install can succeed, then the REP after InstallFinalize can fail and roll back, leaving both products simultaneously installed. Having REP within the transaction results in a full rollback if the uninstall of the older product fails.
Even though I hide the WiX property that contains a password and the ExecXmlFile property...
<Property Id="MyApp_MyServer_constr" Hidden="yes" />
<Property Id="ExecXmlFile" Hidden="yes" />
<DirectoryRef Id='MYAPPDIR'>
<Component Id='UpdateMyAppMyServerConnectionString' Guid='MY-GUID' Win64="yes">
<CreateFolder />
<util:XmlFile Id='UpdateMyAppMyServerConnectionString'
Action="setValue"
ElementPath="[MyServer_elementpath]"
File="[MYAPPDIR]MyApp.exe.config"
Value="[MyApp_MyServer_constr]" />
</Component>
</DirectoryRef>
...password details are exposed in the MSI install log file.
MSI (s) (F0:7C) [20:27:56:613]: Executing op: ActionStart(Name=ExecXmlFile,,)
Action 20:27:56: ExecXmlFile.
MSI (s) (F0:7C) [20:27:56:613]: Executing op: CustomActionSchedule(Action=ExecXmlFile,ActionType=3073,Source=BinaryData,Target=ExecXmlFile,CustomActionData=20C:\Program Files\MyCompany\MyInstallerName\MyApp\MyApp.exe.config30//configuration/connectionStrings/add[#name='MyServer']/#connectionStringUser ID=sa;Password=wysiwyg;Initial Catalog=MyDatabase;Data Source=MACHINE-NAME;Application Name=MyShortAppName)
I've done a considerable amount of checking online, but there does seem to be a WiX way of hiding this information from an MSI log without doctoring things using Orca after creating an MSI.
I found this WiX bug http://wixtoolset.org/issues/3859/, but it seems that not allowing hiding of ExecXmlFile CustomAction calls was by design.
Alternately, is there another WiX way to accomplish what I need that doesn't expose password details in the log file?
Thanks
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.