How to execute the custom action in silent mode in wix? - wix

I am trying to execute the custom action at the time of uninstall the installer in wix.It is working perfectly but it is showing the splash screen of cmd prompt at the time of custom action.Latter I tried with CAQuietExec but it is unable to uininstall the installer and giving error.
(CAQuietExec: Error 0x80070057: failed to get command line data).
The command that I am using is :
<Fragment>
<Property Id="ModifyOutlookRegInitSign_14" Value=""[SystemFolder]reg.exe" ADD "HKCU\SOFTWARE\Microsoft\Office\14.0\Outlook\Security" /v InitSign /t REG_DWORD /d 0 /f"/>
<CustomAction Id="ModifyOutlookRegInitSign_14" BinaryKey="WixCA" DllEntry="CAQuietExec"
Execute="deferred" Return="check" />
<InstallExecuteSequence>
<Custom Action="ModifyOutlookRegInitSign_14" Before="InstallFinalize"></Custom>
</InstallExecuteSequence>
</Fragment>

If it is an immediate custom action, the name of the property containing the command line as value must have an Id="QtExecCmdLine". For other types of custom actions read Quiet Execution Custom Action.

It seems to me that you are trying to update HKCU during the uninstall. This is probably because Windows Installer doesn't natively support the ability to do so.
But your proposed solution is lacking in several way. Mainly that it doesn't support rollback and doesn't support cleaning up other user profiles.
Did this registry entry had to be implemented in HKCU? Could it be implemented in HKLM?

I've created a custom action to kill a process silently like this:
<!-- WixQuietExecCmdLine specify the cmd to be executed -->
<Property Id="WixQuietExecCmdLine" Value='"[WindowsFolder]System32\TaskKill.exe" /F /T /IM MyApp.exe'/>
<!-- From WiX v3.10, use WixQuietExec -->
<CustomAction Id="MyAppTaskKill" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="immediate" Return="ignore"/>
<!-- trigger the custom action -->
<InstallExecuteSequence>
<Custom Action='MyAppTaskKill' Before='InstallValidate'></Custom>
</InstallExecuteSequence>
You have more info about the possible configuration combinations here:
http://wixtoolset.org/documentation/manual/v3/customactions/qtexec.html

Wrap your custom action around a Property with Id set to WixQuietExecCmd.
<Property Id="WixQuietExecCmdLine" Value="command line to run"/>
WiX Property Element
WiX Quiet Execution of Custom Action

Related

WiX Toolset - CustomAction for uninstall running after RemoveFiles

On install I add a configuration key to a DB using a command line tool. On uninstall, I'm now trying to remove that configuration key. On an upgrade, I need to remove then add the configuration key back.
Here's my CustomAction "redacted" code:
<CustomAction Id="Unset_AppName_Version_Cmd"
Property="Unset_AppName_Version"
Execute="immediate"
Value=""[SystemFolder]cmd.exe" /C ""[SOMEDIR]SomeClTool" "uninstall:appname""" />
<CustomAction Id="Unset_AppName_Version"
BinaryKey="WixCA"
DllEntry="CAQuietExec"
Execute="immediate"
Return="check"
Impersonate="yes" />
Note: I've tried several values for execute, including oncePerProcess, firstSequence, and immediate.
Here's my InstallExecuteSequence "redacted" code:
<Custom Action="Unset_AppName_Version_Cmd" Sequence="1215">
(!AppName = 3 AND (&AppName = 3 OR &AppName = 2))
</Custom>
<Custom Action="Unset_AppName_Version" Sequence="1216">
(!AppName = 3 AND (&AppName = 3 OR &AppName = 2))
</Custom>
Note: Again, I tried to move around the sequence used. In the above example before InstallValidate, but also before RemoveFiles, RemoveODBC, etc.
Nothing has worked for me. In all instances, the
Executing op: ActionStart(Name=Unset_AppName_Version,,)
line is being run after RemoveFiles, so my custom action fails with:
CAQuietExec: The system cannot find the path specified.
CAQuietExec: Error 0x80070001: Command line returned an error.
CAQuietExec: Error 0x80070001: CAQuietExec Failed
After this, my installation gets rolled back.
Also, is this condition correct for run on uninstall or reinstall?
(!AppName = 3 AND (&AppName = 3 OR &AppName = 2))
Thanks
Update 7/31/2015
While I still do not have a working solution, I have made enough changes that it makes sense to post my current code.
Here's my updated CustomAction "redacted" code:
<CustomAction Id="Unset_AppName_Version_Cmd"
Property="QtExecCmdLine"
Value=""[SystemFolder]cmd.exe" /C ""[SOMEDIR]SomeClTool" "uninstall:appname"""
Execute="immediate" />
<CustomAction Id="Unset_AppName_Version"
BinaryKey="WixCA"
DllEntry="CAQuietExec"
Execute="immediate"
Return="ignore" />
Note: These changes were made based on Kiran's much appreciated suggestions and to mimic some taskkill commands that are working for me.
Example of working code:
<CustomAction Id="TaskKill_erl_exe_Cmd"
Property="QtExecCmdLine"
Value='"[SystemFolder]taskkill.exe" /F /IM erl.exe /T'
Execute="immediate" />
<CustomAction Id="TaskKill_erl_exe"
BinaryKey="WixCA"
DllEntry="CAQuietExec"
Execute="immediate"
Return="ignore"/>
Thanks
Couple of things here.
-You are trying to execute the custom action in immediate mode using the Wix provided inbuilt Quiet Execution Custom Action.
http://wixtoolset.org/documentation/manual/v3/customactions/qtexec.html
If you want to make use of CAQuietExec in immediate mode, the documentation clearly suggests that you have to set the WixQuietExecCmdLine property.
I dont see that being done in your case.
In your case, i see that you are setting a property named Unset_AppName_Version in the immediate mode. This just wont work.
-If you are trying to use CAQuietExec in deferred mode, your authoring of the custom actions in the pasted code snippet will work, as that would lead to populating the value of the inbuilt special property "CustomActionData"
-If the command line tool that you are trying to launch is installed by the msi package, then the custom action with Id="Unset_AppName_Version" has to be sequenced after "InstallFiles" standard action for the case of Install/Upgrade/Re-install.
For the case of uninstall, i am assuming you will have a seperate custom action which invokes this command line tool with a different set of parameters and it should be sequenced before "RemoveFiles" standard action.
-Finally, yes your condition is correct and will invoke the action on re-install or uninstall of the feature.
-Also when you run your msi package, if you want to confirm if the command line tool was indeed launched, you can have a utility named "ProcessMonitor" running. ProcessMonitor is from the Sysinternals suite. Keep the tool running by setting the appropriate filters.
If your tool is ever launched, ProcessMonitor will indicate the same to you.
Hope this helps.
This ended up working for me:
<CustomAction Id="Unset_AppName_Version_Cmd"
Property="QtExecCmdLine"
Value=""[SystemFolder]cmd.exe" /C ""[SOMEDIR]SomeClTool" "uninstall:appname"""
Execute="immediate" />
<CustomAction Id="Unset_AppName_Version"
BinaryKey="WixCA"
DllEntry="CAQuietExec"
Execute="immediate"
Return="ignore" />
And in the InstallExecuteSequence:
<Custom Action="Unset_AppName_Version_Cmd" Sequence="1215">
(!AppName = 3 AND (&AppName = 3 OR &AppName = 2))
</Custom>
<Custom Action="Unset_AppName_Version" Sequence="1216">
(!AppName = 3 AND (&AppName = 3 OR &AppName = 2))
</Custom>
The issue seems to be that something got messed up in my VM with all the rollbacks.
The main problem that I had was that I initially tried to name the property in the "Unset_AppName_Version_Cmd" CustomAction.
Thanks again to Kiran for all his help.

Elevated custom action before removing files

I'm trying to write an Installer for my Windows Service using WiX. My executable can register/unregister itself as a Windows Service using the command line parameters --install and --uninstall. This is what I came up with:
<CustomAction Id='InstallAsService' FileKey='CCWirelessServer.exe' ExeCommand='--install' Return='check' Impersonate='no' Execute='deferred' />
<CustomAction Id='InstallAsServiceRollback' FileKey='CCWirelessServer.exe' ExeCommand='--uninstall' Return='check' Impersonate='no' Execute='rollback' />
<CustomAction Id='UninstallAsService' FileKey='CCWirelessServer.exe' ExeCommand='--uninstall' Return='check' Impersonate='no' Execute='deferred' />
<InstallExecuteSequence>
<Custom Action='InstallAsService' After='InstallFiles' >NOT Installed</Custom>
<Custom Action='InstallAsServiceRollback' Before='InstallAsService' >NOT Installed</Custom>
<Custom Action='UninstallAsService' Before='RemoveFiles' >Installed</Custom>
</InstallExecuteSequence>
Both install and uninstall basically work. But during uninstall I get the following message:
The setup must update files or services that cannot be updated while the system is running. If you choose to continue, a reboot will be required to complete the setup.
Despite this error message, the service gets unregistered and the files are deleted without a reboot. To me this looks like the installer is checking if CCWirelessServer.exe is opened before it executes my custom action.
So my question is: How do I need to modify my install execute sequence so that this error message does no longer appear?
If you are developing for Windows Installer > 3.1 you can take a look at the MSIRESTARTMANAGERCONTROL-property to see if it it set properly or if other values would would stop displaying the message.
I could suppress the message using the following values:
<Property Id="MSIRESTARTMANAGERCONTROL" Value="Disable" Secure="yes" />

Wix: how to forcefully kill a process/task?

I need to forcefully kill a process that is running in the background before attempting to delete any files, when running an Uninstall from an MSI created with Wix. The main application consist of a trayicon which reflects the status of the bg-process monitoring local windows services (made on C#, though this may not be so relevant going further).
I first tried the following:
<File Id='FooEXE' Name='Foo.exe' Source='..\Source\bin\Release\Foo.exe' Vital='yes' />
...
<InstallExecuteSequence>
<Custom Action="CloseTray" Before="InstallValidate" />
</InstallExecuteSequence>
...
<CustomAction Id="CloseTray" ExeCommand="-exit" FileKey="FooEXE" Execute="immediate" Return="asyncWait" />
The tray icon is immediately closed after confirming application-close dialog, but the Foo.Exe task still appears on the taskmgr after the uninstall completed. Also,the following error message was given:
Thats why, then I tried this:
<InstallExecuteSequence>
<Custom Action="Foo.TaskKill" Before="InstallValidate" />
</InstallExecuteSequence>
...
<CustomAction Id="Foo.TaskKill" Impersonate="yes" Return="asyncWait" Directory="WinDir" ExeCommand="\System32\taskkill.exe /F /IM Foo.exe /T" />
After obtaining the same result, tried:
<Property Id="QtExecCmdLine" Value='"[WinDir]\System32\taskkill.exe" /F /IM Foo.exe'/>
...
<InstallExecuteSequence>
<Custom Action="MyProcess.TaskKill" Before="InstallValidate" />
</InstallExecuteSequence>
...
<CustomAction Id="MyProcess.TaskKill" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="immediate" Return="ignore"/>
Sample which I took from here: How to kill a process from WiX
lately when all else failed, I also tried this without any success:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
...
<InstallExecuteSequence>
<Custom Action="WixCloseApplications" Before="InstallValidate" />
</InstallExecuteSequence>
...
<util:CloseApplication Id="CloseFoo" CloseMessage="yes" Description="Foo is still running!" ElevatedCloseMessage="yes" RebootPrompt="yes" Target="Foo.exe" />
This one gave me a different error:
I'm thinking on building a statue in honor to this process that just refuses to die!!! ... either that or think a problem on the application side exists, where I should add something like Application.Exit(); or Environment.Exit(0); at some line inside Program.cs.
Is there any other thing I could do at either Wix or my application to attempt closing it successfully at Uninstall?
Thanks!
Personally I think the best option for you to go with is the in-built CloseApplication method rather than your previous options.
The error you are getting for that (Error code 2762) is because you are trying to schedule the action in the immediate sequence but have the ElevatedCloseMessage="yes" set which triggers it as a deferred action. Either remove this attribute or schedule it in the deferred sequence.

Wix CustomAction to run only in basic mode

My wix 3.5 setup can be downloaded and run in normal installation situation. I also use the same msi for updates and call msiexec with /qb (basic quiet interface) from within the app itself.
All is ok up to here. In normal setups, I have an option to start app upon install (taken from tutorial) and works fine.
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Start $(var.AppName) $(var.ExeVersion) now..." />
<Property Id="WixShellExecTarget" Value="[#$(var.AppName).exe]" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
I want my update to be quiet and start the updated app after successfull install. In order to do this I have a custom action like this in my InstallExecuteSequence:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallFinalize"/>
<Custom Action="LaunchApplication"
After="RemoveExistingProducts"/>
</InstallExecuteSequence>
This is also ok too, however obviously, now my app is automatically started with normal (not /qb) setups. In order to overcome this, I suppose I need to detect in which UILevel I am and run the custom action only in INSTALLUILEVEL_BASIC.
So here is my question: How can I detect the UILevel in InstallExecuteSequence or CustomAction? Or is there a way to run CustomAction only in quiet basic mode in Wix.
You should condition condition the custom action by UILevel = 3

CAQuietExec Command string must begin with quoted application name

Ok I believe I'm following the online example in Wix3.5 for doing quiet commands yet I cannot seem to get my command to be executed quoted.
<Component Id="MapObjectsRuntime' Guid='*'>
<File Id = 'Mo23rtEXE' Name='Mo23rt.exe' Source='....' KeyPath="yes"/>
<Component>
<Property Id = "QtExecCmdLine" Value="Mo23rt.exe" />
// I've tried single & double quotes, and double double quotes around Mo23.
<CustomAction Id = "InstallMapObjects" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="immediate" Return="check" />
<InstallExecuteSequence>
<Custom Action="InstallMapObjects" After="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
I do get a warning building the wix project:
The file Mo23rtEXE is not a Font, and its version is not a companion file reference.
I also need to assign command line parameters to the mo23rt.exe command but I'm first just trying to get this to work.
Lots of folks appear to be struggling with this too, as revealed by Google.
Forgot to add that running setup.exe /l*v install.log had:
MSI Doing action: InstallMapObjects
.
.
Property Change: Deleting QtExeCmdLine property. Its current value is 'Mo23rt.exe'.
CAQuitExec: Command string must begin with quoted application name.
CAQuietExec: Error 0x80070057 invalid command line property value
You schedule your custom action as immediate, but you try to run a file which should be installed by your installer. Here comes the conflict: immediate CA run BEFORE the files are installed, 'cause this happens in deferred sequence.
I would recommend you to get acquainted with Installation Phases and In-Script Execution Options for Custom Actions in Windows Installer article first.
I had tried ""mo23rt.exe"" and "'mo23rt.exe'", shame on me for not trying '"mo23rt.exe"'. Something else is still wrong but it might be what's mentioned above, or it might be I'm trying to run something that is trying to put up a status bar dialog and is not really that quiet.
I changed it to a regular custom action vice CAQuiet.
<CustomAction Id="InstallMapObjects" FileKey="Mo23rtEXE" ExeCommand="/ACDJKLM" Execute="commit"/>
followed by
<InstallExecuteSequence>
<Custom Action="InstallMapObjects" Before="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>