CMD window remain open after wix installation runs application - cmd

Using Wix installer (win 8), I have a custom action that runs the application after successful installation, using Wix:
<CustomAction Id='LaunchFile'
Directory='TARGETDIR'
Impersonate="no"
Execute="immediate"
ExeCommand='[SystemFolder]cmd.exe start CMD /c ""[TARGETDIR]ManagerAndControl.exe""'
Return="asyncNoWait" />
This works great, but for some reason, the CMD window remains open, and when the application is closed it is closed too.
I couldn't find anything similar in google, anyone encounterd a similar problem?
Thank you
EDIT:
I'm trying, as #Rolo suggested, the QtExecCmdLine:
<Property Id="QtExecCmdLine" Value='C:\Users\User\Desktop\tests.exe'/>
<CustomAction Id="QtExecExample" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="immediate" Return="check"/>
And also:
<Publish Event='DoAction' Value='QtExecExample'>(NOT Installed) AND (LAUNCHPRODUCT = 1)
</Publish>
But nothing happens, and the log says:
Action start 11:02:49: QtExecExample.
MSI (c) (E0:20) [11:02:49:911]: Invoking remote custom action. DLL: C:\Users\User\AppData\Local\Temp\MSIAD42.tmp, Entrypoint: CAQuietExec
MSI (c) (E0:EC) [11:02:49:913]: Cloaking enabled.
MSI (c) (E0:EC) [11:02:49:913]: Attempting to enable all disabled privileges before calling Install on Server
MSI (c) (E0:EC) [11:02:49:913]: Connected to service for CA interface.
MSI (c) (E0!00) [11:02:49:944]: PROPERTY CHANGE: Deleting QtExecCmdLine property. Its current value is 'C:\Users\User\Desktop\tests.exe'.
Action ended 11:02:49: QtExecExample. Return value 3.
DEBUG: Error 2896: Executing action QtExecExample failed.
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2896. The arguments are: QtExecExample, ,
Action ended 11:02:49: FinishedForm. Return value 3.
Action ended 11:02:49: INSTALL. Return value 1.
Filling lost here

Use the "Quiet Execution Custom Action" instead.
http://wixtoolset.org/documentation/manual/v3/customactions/qtexec.html
Update:
I'll have to update my answer. You should use the WixShellExec custom action. It works pretty similar to Quiet Execution CA, but it will allow you to launch the app without waiting for it to close.
However it can only be used as an immediate custom action.
There is a full example of the implementation you need here:
http://wixtoolset.org/documentation/manual/v3/howtos/ui_and_localization/run_program_after_install.html
http://wixtoolset.org/documentation/manual/v3/customactions/shellexec.html

Edit your execommand like this
> ExeCommand='[SystemFolder]cmd.exe start CMD /c ""[TARGETDIR]ManagerAndControl.exe"" & exit'
EDIT
> ExeCommand='"[TARGETDIR]ManagerAndControl.exe"'
I've just tried this for me and it's worked after I recreated your original problem. However, where you have [TARGETDIR] I use [INSTALLDIR] - I assumed that this was referencing your install directory. You need to be aware of your use of inverted commas.

Thanks for your help, finally I solved it:
<Property Id="WixShellExecTarget" Value='[TARGETDIR]ManagerAndControl.exe' />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
<!-- UI code here -->
<Publish Event='DoAction' Value='LaunchApplication'>(NOT Installed) AND (LAUNCHPRODUCT = 1)</Publish>

Related

WiX Installer - Environment Variable Removed with Reinstall/Repair

I’m creating a WiX installer for a Petrel plugin using WiX 3.11.1. The Product.wxs is essentially the following one with a couple modifications:
https://github.com/davidbcc/DeCompactPlugIn/blob/dev/FaciesDecompactorInstaller/Product.wxs
I added a page in the wizard where the user can specify a license server in an edit box. From this information, I create and/or update an environment variable:
<!-- Get the current environment variable if it exists -->
<SetProperty Id="LICENSE_SERVER_ENV_VAR" Value="[%LIC_HOST]" After="LaunchConditions" Sequence="first"></SetProperty>
<snip>
<!-- Validate that the license server name is not empty before proceeding. -->
<Control Type="PushButton" Id="Next" X="239" Y="243" Width="56" Height="17" Default="yes" Text="Next">
<Publish Event="SpawnDialog" Value="ServerNameErrorDlg"><![CDATA[LICENSE_SERVER_ENV_VAR = ""]]></Publish>
<Publish Event="NewDialog" Value="ngenDialog"><![CDATA[LICENSE_SERVER_ENV_VAR <> ""]]></Publish>
</Control>
<snip>
<!-- Install the plugin and set the environment variable -->
<Fragment>
<ComponentGroup Id="PluginComponents" Directory="INSTALLLOCATION">
<Component Id="PetrelPluginPip" Guid="120AF5B9-E751-43F4-AF4C-7DED33C8BEB4">
<Environment Id="LicenseServerEnVar" Action="set" Name="LIC_HOST" System="yes" Permanent="yes" Value="[LICENSE_SERVER_ENV_VAR]"/>
<File Id="PetrelPluginPippip" Source="../OceanPluginPip/bin/$(var.OceanPluginPip.Platform)/$(var.OceanPluginPip.Configuration)/PetrelPluginPip.pip" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
Everything seems to run fine on initial install and when operating through Add/Remove Programs. If I run repair through there, it runs silently and the environment variable remains.
However, after installation, if I right-click on the installer (the actual .msi file), select “Install”, and then select the “Repair” option in the Maintenance dialog, I go through the wizard again. The page correctly pulls the license server information just like on initial install but after completing the repair, the environment variable is removed from the system.
I have tried:
setting "Sequence” on SetProperty to “both”
putting the “Environment” tag into its own Component
creating a CustomAction for setting the license server that is then used in the InstallExecuteSequence
None of these have worked.
Does anyone know why repair through the MaintenanceDialog is resulting in the removal of the environment variable? Thanks.
EDIT:
After adding verbose logging, the repair output shows the following which seems relevant:
MSI (s) (60:78) [11:42:25:420]: PROPERTY CHANGE: Adding RestrictedUserControl property. Its value is '1'.
MSI (s) (60:78) [11:42:25:420]: PROPERTY CHANGE: Adding PETRELINSTALLLOCATION property. Its value is 'C:\Program Files\Schlumberger\Petrel 2022\'.
MSI (s) (60:78) [11:42:25:420]: Ignoring disallowed property INSTALLLOCATION
MSI (s) (60:78) [11:42:25:420]: Ignoring disallowed property LICENSE_SERVER_ENV_VAR
MSI (s) (60:78) [11:42:25:420]: Ignoring disallowed property TARGETDIR
Action start 11:42:25: LaunchConditions.
Action ended 11:42:25: LaunchConditions. Return value 1.
MSI (s) (60:78) [11:42:25:468]: Doing action: SetLICENSE_SERVER_ENV_VAR
MSI (s) (60:78) [11:42:25:468]: Note: 1: 2205 2: 3: ActionText
Action start 11:42:25: SetLICENSE_SERVER_ENV_VAR.
MSI (s) (60:78) [11:42:25:469]: Skipping action due to msidbCustomActionTypeFirstSequence option.
Action ended 11:42:25: SetLICENSE_SERVER_ENV_VAR. Return value 0.
Why is the property disallowed on repair? I'm not seeing that on initial installation. But I still don't see where the environment variable is getting removed.
After investigating what "Ignoring disallowed property" meant, I came across the following post indicating that likely the property is not propagating to the execute sequence:
https://stackoverflow.com/a/39227065/4460247
By adding a Property definition and marking it as "Secure" before populating it, the property is set and the environment variable no longer gets removed.
<Property Id="LICENSE_SERVER_ENV_VAR" Secure="yes"></Property>
<SetProperty Id="LICENSE_SERVER_ENV_VAR" Value="[%LIC_HOST]" After="LaunchConditions" Sequence="first"></SetProperty>

WIX property NETFRAMEWORK40FULLINSTALLROOTDIR is blank

I am trying to register my COM Add-in using the RegAsm command using the WIX Setup. But am unable to do it. It is showing blank against the WixNetFxExtension's NETFRAMEWORK40FULLINSTALLROOTDIR or even NETFRAMEWORK40CLIENTINSTALLROOTDIR.
Here is the code for the custom action:
<CustomAction Id="RegisterUsingRegAsm" Directory="PROOFIX_ADDIN" Execute="deferred" Impersonate="no" Return="check"
ExeCommand='"[NETFRAMEWORK40FULLINSTALLROOTDIR]regasm.exe" "[PROOFIX_ADDIN]Proofix.View.dll" /codebase' />
When I try to hardcode the path C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe. It works fine...
and Here is the Sequence information:
<InstallExecuteSequence>
<Custom Action="RegisterUsingRegAsm" Before="InstallFinalize" />
</InstallExecuteSequence>
Here is the log generated for the installer:
Action: RegisterUsingRegAsm, location:
C:\Users\naveed.butt\AppData\Local\Optimentor\Proofix\, command:
"regasm.exe"
"C:\Users\naveed.butt\AppData\Local\Optimentor\Proofix\Proofix.View.dll"
/codebase
First of all you are missing a PropertyRef
Like this:
<PropertyRef Id="NETFRAMEWORK40CLIENTINSTALLROOTDIR"/>
Second issue if you are on a 64 bit windows you should use the 64 bit variable:
NETFRAMEWORK40CLIENTINSTALLROOTDIR64
However you can handle 32/64 bit Windows OS with conditions. You can get inspiration from this answer: https://stackoverflow.com/a/12514596/600559

Calling VBScript from WIX CustomActionTag and handling return

I am new to WIX installer. i am trying to perform the following,
At the end of the InstallExecuteSequence i want to invoke a VBScript that does some blokcing of ports on windows firewall(i have written a script for that already).
Now if the operation is successful then installation continues else
A error is shown to the user on the installer and a option is given to the user to continue or abort.
Also before the script runs i want to give the user a option whether to do the "port related work"
i am currently doing ,
<CustomAction Id="DoSomething"
BinaryKey="MyCA"
VBScriptCall="Main"
Execute="deferred"
Return="check"
HideTarget="no"
Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="DoSomething" Before="InstallFinalize" />
</InstallExecuteSequence>
My question is how do i get the control back from the VBScript then display the message and option to the user ?

NTService looking for wrong config file

I'm working on moving a set of installers from VS2010 to WIX and have encountered an error with our NT Service applications.
After creating and installing the NT Service using the WIX installer, the service is not looking for the app.config named as you would expect (ApplicationName.exe.config). Our application name is akin to XXX.YYYYYYYY and when injecting the debugger into the service during start up, i can see that it is looking for XXX.config instead of XXX.YYYYYYY.exe.config.
I've tried running the application via the console and when I do, it looks for the correct app.config file name. Using the VS2010 installer also has the service looking for the correct app.config file name.
Is there some setting in wxi3.8 that I am missing, or putting the incorrect value into, that would cause this? Here is the segment of the wxs that controls the service:
<Component Id="Service" Guid="DCE18608-D25F-4DC0-9E1B-C2E3575D0BFE">
<File Id="ServiceComponentMain" Name="$(var.XXX.YYYYYYY.TargetName)" Source="$(var.HHG.SpecOrderLoadSync.TargetPath)"
DiskId="1" Vital="yes" KeyPath="yes"/>
<ServiceInstall Id="Service" Name="$(var.XXX.YYYYYYY.TargetName)" Type="ownProcess" DisplayName="$(var.XXX.YYYYYYY.TargetName)"
Description="$(var.XXX.YYYYYYY.TargetName)" Start="auto" Account="NT AUTHORITY\LocalService" ErrorControl="normal">
<util:PermissionEx User="Everyone" ServicePauseContinue="yes" ServiceQueryStatus="yes"
ServiceStart="no" ServiceStop="yes" ServiceUserDefinedControl="yes"/>
</ServiceInstall>
<ServiceControl Id="Service" Stop="both" Remove="both" Name="$(var.XXX.YYYYYYY.TargetName)" Wait="no"/>
Finally figured this out after digging around the registery. It appears that with my current wsx file it isn't registering the full path to the executable including ".exe" at the end. This is what is causing the config file name to be confused. Why in the world this makes a difference is beyond me, but just another thing to annoy me about windows i guess...
To fix, changing the Name on the File element in the segment above to be $(var.XXX.YYYYYYY.TargetName).exe instead of just $(var.XXX.YYYYYYY.TargetName) seems to work.

Wix CAQuietExec - Path gets prefixed with 'C:\Windows\SysWOW64\'

I provided a path like this as the Property Value: [INSTALLFOLDER]Program Scripts\Script1.rss
where INSTALLFOLDER is C:\Program Files (x86)\ABCCompany\DEFProductInstaller\
But it somehow gets interpreted like this:
C:\Windows\SysWOW64\C:\Program Files (x86)\ABCCompany\DEFProductInstaller\Program Scripts\Script1.rss
This is the Property and the associated CustomAction
<Property Id="CreateDataSources"
Value=""rs.exe" -i "[INSTALLFOLDER]Program Scripts\Script1.rss""/>
<CustomAction Id="CreateDataSources" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/>
This is the log:
Property(S): SystemFolder = C:\Windows\SysWOW64\
...
MSI (s) (8C:44) [14:41:41:202]: Executing op: CustomActionSchedule(Action=CreateDataSources,ActionType=3073,Source=BinaryData,Target=CAQuietExec,CustomActionData="rs.exe" -i "[INSTALLFOLDER]Program Scripts\Script1.rss" -s http://localhost/ReportServer -v DataSourcePath="" -v DBServer="." -v InitialCatalog="MyDB" -v UserId="" -v Password="" -v IntegratedSecurity="True")
MSI (s) (8C:78) [14:41:41:211]: Invoking remote custom action. DLL: C:\Windows\Installer\MSIFB.tmp, Entrypoint: CAQuietExec
MSI (s) (8C:90) [14:41:41:211]: Generating random cookie.
MSI (s) (8C:90) [14:41:41:213]: Created Custom Action Server with PID 16716 (0x414C).
MSI (s) (8C:C4) [14:41:41:237]: Running as a service.
MSI (s) (8C:C4) [14:41:41:238]: Hello, I'm your 32bit Impersonated custom action server.
CAQuietExec: Could not find a part of the path 'C:\Windows\SysWOW64\C:\Program Files (x86)\ABCCompany\DEFProductInstaller\Program Scripts\Script1.rss'.
CAQuietExec: Error 0x80070001: Command line returned an error.
CAQuietExec: Error 0x80070001: CAQuietExec Failed
Any idea as to what I'm doing wrong?
UPDATE Changing the <Property> value to an absolute path fixes this issue.
<Property Id="CreateDataSources"
Value='"rs.exe" -i "C:\Program Files (x86)\ABCCompany\DEFProductInstaller\Program Scripts\Script1.rss"/>
But I need it to work with INSTALLFOLDER
The log isn't failing the way I expect it to fail (perhaps there has been a recent WiX change) but in my experience the call to rs.exe has to not only be wrapped in quotes but it has to be an absolute path. "[SystemFolder]rs.exe"
BTW, it seems you are using RS.exe to deploy reporting services changes. I don't believe that file is legally redistributable. I was working for a company about 6 years ago where I wrote a table driven C#/DTF custom action that consumed the SSRS web service to publish directories, reports and datasources. I never implemented rollback though. Also this is one type where Impersonate=No may end poorly. This is due to the fact that in some situations the logged on user might have writes to the SSRS web service and the SYSTEM account may not.
You need to provide a full path to the .exe you want to run. CreateProcess does not use the system path: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx

Resources