Calling VBScript from WIX CustomActionTag and handling return - vbscript

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 ?

Related

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

Check for Terminal Server in WiX

Recently I had to "pre-select" an feature inside an WiX product. If the target machine is an Terminal-Server, the Feature should be selected for install.
To check, if the machine realy is used as Terminal-Server or not isn't required, since the installing user can still deselect the feature later.
One way to check for Terminal-Server (and not just an machine with RDP enabled) is to use GetVersionEx-API to check the wSuiteMask.
How to check that in WiX?
First we had to link WixUtilExtension.dll (Project-References->Add Reference)
Then use INSTALLLEVEL (as per mrnx's advice) to switch between different Features. We default it to "2" (All below 2 will be selected in feature-selection-screen, all above 2 will be de-selected):
<!--Default Features: All with levl 1-->
<Property Id="INSTALLLEVEL" Value="2" />
Use feature-selection-UI-template (Maybe you have to reference WixUiExtension.dll)
<UI>
<UIRef Id="WixUI_FeatureTree" />
</UI>
Now reference the properties, which we want to know:
<!--Terminal-Server?-->
<PropertyRef Id="WIX_SUITE_TERMINAL" />
<!--On Terminal-Server this property will be null, if multiple RDP-sessions are allowed-->
<PropertyRef Id="WIX_SUITE_SINGLEUSERTS" />
And finally in our Feature-list we have to use the properties inside a condition. The Feature should be de-selected per default, so we set it to one Level higher than the default "2" --> "3".
<Feature Id="TerminalServerServiceFeature" Level="3"
Title="(Feature-Title, i.E.)Terminal-Server-Service"
AllowAdvertise='no'
InstallDefault='local'
Absent='allow'
Description="Some description for the user, when he clicks on the feature" Display="expand"
ConfigurableDirectory='APPLICATIONFOLDER'
>
<!--Reference to the component (or componentgroup) we want to install-->
<ComponentRef Id="TerminalServerServiceComponent" />
<!--This sets this feature to installlevel 1, if the condition evals to true-->
<Condition Level="1">(WIX_SUITE_TERMINAL="1") AND NOT (WIX_SUITE_SINGLEUSERTS)</Condition>
</Feature>
Testing:
To check, why the condition fails, you have to check the installer log (msiexec /i YourMsi.msi /l*v "log.log").
Something along the lines
MSI (c) (8C!98) [11:18:27:663]: PROPERTY CHANGE: Adding
WIX_SUITE_SINGLEUSERTS property. Its value is '1'.
for a machine with RDP but without multi-rdp-session-support and
MSI (c) (4C!E0) [11:26:15:422]: PROPERTY CHANGE: Adding
WIX_SUITE_TERMINAL property. Its value is '1'.
for a machine with RDP and multi-rdp-session-support.

CMD window remain open after wix installation runs application

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>

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