Run wix custom action before installing files - wix

I should need to run a C++ wix custom action before file installation starts. Is it possible?
My code is
<InstallUISequence>
<Custom Action ="_EE10247D_B1B7_42F9_8BC9_A973E5755689" Before ="InstallFiles"></Custom>
</InstallUISequence>
<CustomAction Id="_EE10247D_B1B7_42F9_8BC9_A973E5755689" Execute="deferred" Impersonate="no" FileKey="FileDllId" adx:VSName="GuidAutoGen" DllEntry="GuidAutoGen" />
but the error message is "error LGHT0094: Unresolved reference to symbol 'WixAction:InstallUISequence/InstallFiles' in section 'Product:{C095BA7A-0E1E-4679-AAC0-3C17C82BC5EA}"
What's wrong?

Linker tells you absolutely true. "InstallUISequence" has no step "InstallFiles". This step presented in another sequence, "InstallExecuteSequence". This sequence executes after InstallUISequence.
In your case, you should write instead of your code:
<InstallExecuteSequence>
<Custom Action ="_EE10247D_B1B7_42F9_8BC9_A973E5755689" Before ="InstallFiles"></Custom>
</InstallExecuteSequence>

Well yes, you just sequence it before the InstallFiles action, in deferred mode. You might need to expand your question if you need more detail.

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.

Cancel uninstallation when custom action fail wix

I need to Cancel uninstallation when my custom action is failed. However i am unable to cancel uninstallation, may i know what is my mistake?
<CustomAction Id="SetRemoveSettings" FileKey="RemoveSettings.exe" ExeCommand="" Execute="deferred" Return="check" HideTarget="no" Impersonate="yes" />
<InstallExecuteSequence>
<Custom Action='SetRemoveSettings' Before='InstallFinalize'>REMOVE="ALL"</Custom>
</InstallExecuteSequence>
It should rollback the uninstall if your EXE returns a non zero exit code.
Also, you should look into the Quiet Exec Custom Action pattern. It's a better way of calling EXE's for those times that you must call an EXE. Otherwise avoid EXE's in general.

How can I include a strong name assembly file in my installer

I have a custom action to execute a custom action DLL but it is failing and I believe it's because it does not know how to read the strong name assembly
so I have this:
<Binary Id="StrongName" SourceFile="$(var.MyProject.TargetDir)MyProject.CA.dll"/>
<CustomAction Id="CreateIt"
BinaryKey="StrongName"
DllEntry="Create"
Execute="deferred"
Return="check"
HideTarget="no"
Impersonate="no" />
<CustomAction Id="RemoveIt"
BinaryKey="StrongName"
DllEntry="Remove"
Execute="deferred"
Return="check"
HideTarget="no"
Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="CreateIt" Before="InstallFinalize">(NOT REMOVE = "ALL")</Custom>
<Custom Action="RemoveIt" Before='InstallFinalize'>(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
</InstallExecuteSequence>
So how do I reference the signature as I execute this DLL?
I assume from the *.CA.DLL nomenclature that you are using that this is a DTF custom action. This is a native encapsulated DLL that hosts your managed DLL. Being native, it can't be strong named.
Log the install and look through the log for the reason it is failing.
The solution to my problem was a security issue caused by an obsolete library which is not supported in .NET 4 and it is a different topic so I will not go into detail on it unless someone is curious.

When can I get the target directories in a WIX installer?

So I have a custom action
<CustomAction Id="GetTarget"
BinaryKey="CA"
DllEntry="GetTargetPath"
Execute="immediate"
Return="check"
HideTarget="no"
Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="GetTarget" After="CostFinalize">(NOT REMOVE = "ALL")</Custom>
</InstallExecuteSequence>
This is calling a DLL that calls the method session.GetTargetPath("TARGETPATH"); But I get an exception "The directory name is invalid. TARGETPATH". I have the custom action as After="CostFinalize" as this is what I read from a source (which I can provide) but I think there is a mistake and I think that I just have to to execute the action at the right time.
I think you meant TARGETDIR. Take a look at http://msdn.microsoft.com/en-us/library/windows/desktop/aa371685(v=vs.85).aspx

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>