I have enabled logging using below code :
<Property Id="MsiLogging" Value="voicewarmupx!"/>
and I want to copy log file from temp folder to custom Log location.
I have written a custom action as below
<CustomAction Id="CopyLogFile" Execute="immediate"
ExeCommand="cmd /c copy [MsiLogFileLocation] [LogsFolder]"
Directory="TARGETDIR"
Impersonate="no"
Return="asyncNoWait" />
<InstallExecuteSequence>
Custom Action="CopyLogFile" OnExit="success"></Custom>
After successful installation above code works fine but when I do Uninstall the code is not working.
Any one please help me to move file from Temp folder to specific folder after uninstall.?
The specify the condition for the Custom Action to be invoked on an uninstall: (REMOVE="ALL") AND NOT UPGRADINGPRODUCTCODE.
This should work:
<CustomAction Id="CopyLogFile" Execute="immediate"
ExeCommand="cmd /c copy [MsiLogFileLocation] [LogsFolder]"
Directory="TARGETDIR"
Impersonate="no"
Return="asyncNoWait" />
<InstallExecuteSequence>
<Custom Action="CopyLogFile" OnExit="success">(REMOVE="ALL") AND NOT UPGRADINGPRODUCTCODE</Custom>
...
See the full property references you can use in the Microsoft Docs.
Related
I have my own Managed Bootstrapper Application developed using WiX Toolset and written in c# using MVVM pattern. As this is a Managed Bootstrapper Application, i have a custom UI as well. My Bundle.wxs Code is as follows
<Bundle Name="NestleMESSetup"
Version="!(bind.packageVersion.NestleCustomLayerSetupPackage)"
Manufacturer="CT Infotech"
UpgradeCode="CCBB8D5B-8171-47FB-AD53-25C6E866C34E"
Copyright="Copyright© 2017 CT Infotech ALL RIGHTS RESERVED"
SplashScreenSourceFile="Resources\Splash.bmp"
IconSourceFile="Resources\menu.ico">
<Variable Name="KambanVersion" Type="version" Value="!(bind.packageVersion.KambanFASSetup)"/>
<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost">
<PayloadGroupRef Id="InstallerPayload"/>
</BootstrapperApplicationRef>
<util:RegistrySearchRef Id='SearchForKamban' />
<Chain>
<PackageGroupRef Id="InstallerPackages"/>
</Chain>
<Variable Name="DbName" bal:Overridable="yes" />
<Variable Name="SqlInstance" bal:Overridable="yes" />
<Variable Name="InstallPath" bal:Overridable="yes" />
<Variable Name="Roles" bal:Overridable="yes" />
<Variable Name="Modules" bal:Overridable="yes" />
<Variable Name="CustomInstall" bal:Overridable="yes"/>
<WixVariable Id="WixMbaPrereqPackageId" Value="Netfx4Full" />
<WixVariable Id="WixMbaPrereqLicenseUrl" Value="NetfxLicense.rtf" />
</Bundle>
<Fragment>
<PayloadGroup Id="InstallerPayload">
<Payload SourceFile="..\Nestle.MES.Bootstrapper.UI\BootstrapperCore.config"/>
<Payload SourceFile="..\Nestle.MES.Bootstrapper.UI\bin\$(var.Configuration)\Nestle.MES.Bootstrapper.UI.dll"/>
<Payload SourceFile="C:\Program Files (x86)\WiX Toolset v3.10\SDK\Microsoft.Deployment.WindowsInstaller.dll"/>
</PayloadGroup>
</Fragment>
<Fragment>
<PackageGroup Id="InstallerPackages">
<RollbackBoundary Id="StartingPoint" Vital="yes" />
<ExePackage Id="KambanFASSetup" Cache="no" Compressed="yes" Vital="yes" Permanent="no" Name="KambanCoreSetup"
SourceFile="..\..\Kamban.FAS.Setup_Source\$(var.Configuration)\KambanFASSetup.exe" >
<CommandLine InstallArgument="[SqlInstance]" Condition="1" />
<CommandLine InstallArgument="[DbName]" Condition="1"/>
<CommandLine InstallArgument="[InstallPath]" Condition="1"/>
<CommandLine InstallArgument="[Roles]" Condition="1"/>
<CommandLine InstallArgument="[Modules]" Condition="1" />
<CommandLine InstallArgument="[CustomInstall]" Condition="1"/>
</ExePackage>
<MsiPackage SourceFile="..\..\build_folder\$(var.Configuration)\Nestle.MES.CustomLayer\Nestle.MES.CustomLayerSetup.msi"
Id="NestleCustomLayerSetupPackage" Cache="yes" Visible="no" Compressed="yes" EnableFeatureSelection="yes" Vital="yes">
<MsiProperty Name="INSTALLFOLDER" Value="[INSTALLFOLDER]" />
<MsiProperty Name="VERSION" Value="[VERSION]"/>
<MsiProperty Name="ADDLOCAL" Value="[NestleFeatures]" />
</MsiPackage>
</PackageGroup>
</Fragment>
<Fragment>
<util:RegistrySearch
Id='SearchForKamban'
Variable="KambanInstalled"
Result="exists"
Root="HKLM"
Key="SOFTWARE\Wow6432Node\KambanFAS" />
<bal:Condition Message="Product already Exists">
KambanInstalled
</bal:Condition>
</Fragment>
In the above code, you can see that I have an MsiPackage and an ExePackage in my Bundle chain. The ExePackage with Id="KambanFASSetup" is also a Managed Bootstrapper Application with its very own custom UI. Once I install this Parent bundle exe, i get two entries in my Programs and Features. I believe this is because i have two managed bootstrapper exe. So now while uninstalling the NestleMESSetup only my MsiPackage is getting uninstaled and my ExePackage doesnt. But my requirement is as follows
The ExePackage should also be uninstalled if I uninstall the Parent Exe.
The Uninstallation of the Child ExePackage must happen silently. i.e
It's UI should NOT be shown prompting the user to click the Uninstall
button again.
Please let me know if more info is needed.Any help on this would be much appreciated.
Edit1:
Here is the Uninstall logs in %temp% folder
[2658:3330][2017-05-19T19:27:11]i001: Burn v3.10.2.2516, Windows v6.1 (Build 7601: Service Pack 1), path: C:\ProgramData\Package Cache\{a21ebf3e-08b2-4b64-b5bf-38dccfea21a2}\Nestle.MES.Setup.exe
[2658:3330][2017-05-19T19:27:11]i000: Initializing version variable 'KambanVersion' to value '1.0.647.0'
[2658:3330][2017-05-19T19:27:11]i009: Command Line: '/uninstall'
[2658:3330][2017-05-19T19:27:11]i000: Setting string variable 'WixBundleLog' to value 'C:\Users\RAJASA~1.000\AppData\Local\Temp\NestleMESSetup_20170519192711.log'
[2658:3330][2017-05-19T19:27:11]i000: Setting string variable 'WixBundleManufacturer' to value 'CT Infotech'
[2658:3330][2017-05-19T19:27:11]i000: Loading managed bootstrapper application.
[2658:3330][2017-05-19T19:27:11]i000: Creating BA thread to run asynchronously.
[2658:3330][2017-05-19T19:27:11]i100: Detect begin, 2 packages
[2658:3330][2017-05-19T19:27:11]i000: Setting numeric variable 'KambanInstalled' to value 1
[2658:3330][2017-05-19T19:27:11]i101: Detected package: KambanFASSetup, state: Absent, cached: None
[2658:3330][2017-05-19T19:27:11]i101: Detected package: NestleCustomLayerSetupPackage, state: Present, cached: Complete
[2658:3330][2017-05-19T19:27:11]i104: Detected package: NestleCustomLayerSetupPackage, feature: AppFeatures, state: Local
[2658:3330][2017-05-19T19:27:11]i104: Detected package: NestleCustomLayerSetupPackage, feature: WebFeatures, state: Local
[2658:3330][2017-05-19T19:27:11]i104: Detected package: NestleCustomLayerSetupPackage, feature: DbFeatures, state: Local
Edit2:
With the Detect Condition added to my Bundle chain Exe package I am not able to Uninstall the Parent exe as well. The WiX logs are as follows
[1450:1BBC][2017-05-20T07:33:59]i371: Updating session, registration key: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{c8fb8ef8-905f-4bd9-8675-91f62d83e5c8}, resume: Active, restart initiated: No, disable resume: No
[1644:0F04][2017-05-20T07:33:59]w341: Prompt for source of container: WixAttachedContainer, path: E:\TFS_Nestle\Nestle\build_folder\Debug\Nestle.MES.Setup\Nestle.MES.Setup.exe
[1644:0F04][2017-05-20T07:33:59]e054: Failed to resolve source for file: E:\TFS_Nestle\Nestle\build_folder\Debug\Nestle.MES.Setup\Nestle.MES.Setup.exe, error: 0x80070002.
[1644:0F04][2017-05-20T07:33:59]e000: Error 0x80070002: Failed while prompting for source (original path 'E:\TFS_Nestle\Nestle\build_folder\Debug\Nestle.MES.Setup\Nestle.MES.Setup.exe'). [1644:0F04][2017-05-20T07:33:59]e311: Failed to acquire container: WixAttachedContainer to working path: C:\Users\RAJASA~1.000\AppData\Local\Temp\{B5BE6652-F453-40B5-A2BF-6313B191EA7F}\9FD1B9E707102B3EB2E75EA87962C5C839E9588A, error: 0x80070002.
[1644:1B24][2017-05-20T07:33:59]e000: Error 0x80070002: Failed while caching, aborting execution.
[1450:1BBC][2017-05-20T07:33:59]i372: Session end, registration key: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{c8fb8ef8-905f-4bd9-8675-91f62d83e5c8}, resume: ARP, restart: None, disable resume: No
[1450:1BBC][2017-05-20T07:33:59]i371: Updating session, registration key: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{c8fb8ef8-905f-4bd9-8675-91f62d83e5c8}, resume: ARP, restart initiated: No, disable resume: No
[1644:1B24][2017-05-20T07:33:59]i399: Apply complete, result: 0x80070002, restart: None, ba requested restart: No
[1644:1B24][2017-05-20T07:33:59]i500: Shutting down, exit code: 0x0
Your ExePackage is missing the UninstallCommand attribute so burn does not know how to properly uninstall it. It should be something like
UninstallCommand="/uninstall /quiet"
and may be some additions if needed.
And for burn to be able to detect the ExePackage, it should define the attribute DetectCondition. Something like
DetectCondition="KambanInstalled"
I am running a custom action and getting the following error message:
Error 1723. There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. Action CheckLicenseFileExistsCA, entry: CheckLicenseFileExists, library: C:\Users\dafna\AppData\Local\Temp\MSI3395.tmp
MSI (c) (E8:04) [19:42:28:921]: Product: ReSecServer -- Error 1723. There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. Action CheckLicenseFileExistsCA, entry: CheckLicenseFileExists, library: C:\Users\dafna\AppData\Local\Temp\MSI3395.tmp
I tried to search google for the solution but nothing did the trick, I am probably missing something...
public class CutomActions
{
[CustomAction]
public static ActionResult CheckLicenseFileExists(Session session)
{
try
{
var filename = Path.Combine(session["LICENSEFILE_DIR_PATH"], "license.dat");
var exists = File.Exists(filename);
if (exists)
{
session["LICENSE_FILE_PATH_VALID"] = "1";
}
}
catch (Exception ex)
{
return ActionResult.Failure;
}
return ActionResult.Success;
}
Here are the relevant lines:
<CustomAction Id='CheckLicenseFileExistsCA' BinaryKey='ServerInstallerCustomActions.CA' DllEntry='CheckLicenseFileExists' Execute="immediate" Return="check" /> <Binary Id='ServerInstallerCustomActions.CA' SourceFile='$(var.ServerInstallerCustomActions.TargetDir)\ServerInstallerCustomActions.dll' />
<Control Type="PushButton" Id="BrowseLicense" Width="75" Height="17" X="251" Y="101" Text="{\VSI_MS_Sans_Serif13.0_0_0}Browse" TabSkip="no">
<Publish Property="_BrowseProperty" Value="LICENSEFILE_DIR_PATH" Order="1">1</Publish>
<Publish Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
<Publish Event="DoAction" Value="CheckLicenseFileExistsCA">1</Publish>
<Publish Property="TEMP_VERIFIED" Value="[LICENSE_FILE_PATH_VALID]">1</Publish>
<Publish Property="LICENSE_FILE_PATH_VALID" Value="[TEMP_VERIFIED]" />
</Control>
There also a config file (in the custom action project):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="false">
<supportedRuntime version="v4.0" />
</startup>
</configuration>
When you build your custom action project, there should be a post build event run that runs "MakeSfxCA.exe" which outputs <ProjectTargetName>.CA.dll <-- this is what you want to include with the binary tag, not the dll output from the Custom Action project
so you should be using:
<Binary Id='ServerInstallerCustomActions.CA' SourceFile='$(var.ServerInstallerCustomActions.TargetDir)\ServerInstallerCustomActions.CA.dll' />
To get the *CA.dll you'll have to create your custom action project using the appropriate Visual Studio template related to WiX Toolset, not just a generic Class Library.
I'm trying to create an installer using WiX. To includes DLLs into .msi package I tryied two different ways. One of these is:
<DirectoryRef Id="SETTINGSDIR">
<Component Id="CMP_CopySettings" Guid="AC7D1AA1-798B-48F5-AF8D-188B1050D47C" KeyPath="yes">
<CreateFolder />
<File Id="DBA.bat" Source="$(var.SolutionDir)\scr\A\A.WindowsService\bin\$(var.Configuration)\Settings\A_DB clear.bat" Checksum="yes"/>
<File Id="AConfiguration.xml" Source="$(var.SolutionDir)\scr\A\A.WindowsService\bin\$(var.Configuration)\Settings\AConfiguration.xml" Checksum="yes"/>
<File Id="ADB.CE.DEFAULT.sdf" Source="$(var.SolutionDir)\scr\A\A.WindowsService\bin\$(var.Configuration)\Settings\ADB.CE.DEFAULT.sdf" Checksum="yes"/>
<File Id="ADB.CE.sdf" Source="$(var.SolutionDir)\scr\A\A.WindowsService\bin\$(var.Configuration)\Settings\A.CE.sdf" Checksum="yes"/>
<RemoveFile Id="RemoveFileSettings" Name="*" On="uninstall"/>
</Component>
</DirectoryRef>
But as you can easily understand, it's very hard write an xml node for each DLL (6 projects with 200+ DLLs for each one).
The second one is faster, but WiX just creates a link to the folder instead of copy DLLs into msi package
<DirectoryRef Id="SETTINGSDIR">
<Component Id="CMP_CopySettings" Guid="AC7D1AA1-798B-48F5-AF8D-188B1050D47C" KeyPath="yes">
<CreateFolder />
<CopyFile Id="SettingsID" SourceProperty="SETTINGSSOURCEDIRECTORY" DestinationDirectory="SETTINGSDIR" SourceName="*" />
<RemoveFile Id="RemoveFileSettings" Name="*" On="uninstall"/>
</Component>
</DirectoryRef>
Is there a quick solution that can I add at my second way or I have to use heat.exe tool? In this case, can you explain me how to use it? The official documentation is very poor
Thanks
What you want is an harvest tool to do this for you. Luckily it already exists: Heat
In your specific case you might want to use the command heat dir ".\My Files" -gg -g1 -directoryid "YourDirectoryId" -sfrag -template:fragment -out directory.wxs but check what is exactly your need, which harvesting you want to skip etc...
Note the -t <xsl> switch which gives you the total control on how you want to tune the final output.
How to create a variable / property in Wix and pass to it the value of using C#?
I am writing project installer and encountered a problem related to the transfer of value from C # ([CustomAction] Wix and Bootstrapper) to Wix Toolset 3.10. Both solutions do not work.
Solution 1:
Using Wix Bootstrapper:
Bootstrapper.Engine.StringVariables["MyVariable"] = "test";
Solution 2:
Using the Custom Actions:
I create Bundle.wxs variable:
<Variable Name="MyVariable" Type="string" Value="" />
I set a property in the MSI Property, which should be the value of the variable "MyVariable":
<MsiProperty Name=" MYVARIABLE" Value="[MyVariable]" />
I create Product.wxs property:
<Property Id="MyVariable" Value="abcXYZ123" />
I create Product.wxs Custom Actions in which we set the property:
<CustomAction Id="MyVariable" Property="MyVariable" Value="[MyVariable]" />
I create a Custom Action in Product.wxs:
<CustomAction Id="Prefferences"
BinaryKey="MyCustomAction"
DllEntry="MySimpleAction"
Execute="immediate"
Return="ignore" />
Performing during the installation process:
<InstallExecuteSequence>
<Custom Action="Prefferences" After="InstallFiles">
<![CDATA[Not Installed and Not Reinstall]]>
</Custom>
</InstallExecuteSequence>
I create in class Custom Action.cs access to these properties:
[CustomAction]
public static ActionResult MySimpleAction(Session session)
{
session["MyVariable"] = "Test przesłania parametru!";
return ActionResult.Success;
}
Both solution does not convey the text of the C # code to Wix.
Let's say I have this directory structure.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="test" Name="test">
<Component Id="file" Guid="*">
<File Id="file" Source="file.dll"></File>
</Component>
</Directory>
</Directory>
This will install file.dll into C:\test. What I want to do is during the install overwrite where that file directory with C:\newpath\ and install the file there instead. I have tried this with a Custom Action with no luck. I do see the debug line written so I know it's being called, it's just the file is still installed in C:\test
<InstallExecuteSequence>
<Custom Action="OverwriteDir" After="CostFinalize" />
</InstallExecuteSequence>
[CustomAction]
public static ActionResult OverwriteDir(Session session)
{
System.Diagnostics.Debug.WriteLine(session["tester"]);
session["tester"] = "C:\\newpath";
return ActionResult.Success;
}
What can I do differently?
First you need to make sure that the folder which contains your file inside the MSI uses a public installer property (no lowercase letters in its name) as its ID. The best solution is TARGETDIR because its already configured.
After that, you can use one of these custom action to change the property value during install:
a custom action which changes the directory property value scheduled before CostFinalize
a type 35 custom action which changes the directory path (should be scheduled after CostFinalize)