Can WiX run custom actions from the installed binaries just like Visual Studio Setup project does? - wix

Since I migrated to WiX I only can run custom actions from binaries that are inserted in the Binary table
<Binary Id="SetupActions.CA.dll"
src="..\SetupActions\bin\Release\SetupActions.CA.dll" />
But Visual Studio Setup Project used to use the installed binaries as the container of custom actions.
Is there any way to use the old way in WiX?

You mean that you want to run a custom action that references a function within a dll that is installed with the package? In this case use the custom action type 17. Or in WiX:
<CustomAction Id="myCAfromInstalledDLL" FileKey="IdOfFile.dll" ExeCommand="EntryPointInDll" />

I suppose you could try the following:
Create a custom action binary that you embed in your installer.
Your custom action binary can act as a wrapper and determine the location of the installed binaries and call the appropriate methods \ custom actions. A benefit is that you can check for the existence of the files and take appropriate action if they are missing.

Something like this:
CustomAction Id='FooAction' BinaryKey='FooBinary' DllEntry='FooEntryPoint' Execute='immediate'
Return='check'/
Binary Id='FooBinary' SourceFile='foo.dll'
with the Xml angle brackets edited out for SO.
It's that binarykey that means it gets extracted from the Binary table to be called.

Related

WiX Burn: Create custom log file name for MsiPackage?

When Burn runs an MSI installer, using MsiPackage, I'd like the MSI's log file to have a custom name, like MyProductName.log. I'd also like to append to an existing log file (with same name).
In InstallShield's Basic MSI Project's Release view there is an entry "MSI Command-Line Arguments" where you can enter a custom log file name:
/l+* "%TEMP%\MyProductName.log"
The "+" will append the log to an existing file.
Burn can pass public properties to the MSI, but I don't see a way to do what I want.
It looks like I'll need to write code (custom Burn bootstrapper) to run after the MsiPackage is installed (or uninstalled) to copy the contents of the log file (in the Burn variable defined in LogPathVariable) to the file with the custom name.
You can use the LogPathVariable attribute of the MsiPackage element to provide a custom log file name ...
See: http://wixtoolset.org/documentation/manual/v3/xsd/wix/msipackage.html
Also: https://support.firegiant.com/hc/en-us/articles/230912207-Pass-Properties-to-MsiPackage-from-Bundle-
To do what I needed, I wrote a simple bootstrapper, which became more complicated as I addressed things like passing installer properties to the bootstrapper, giving warnings if installing an x86 installer on an x64 OS (we encourage customers to use and x64 installer), etc.

WiX: how to pack exe or dll to use only during installation

I need to include a dll/exe in the resulting MSI (created through a WiX project), but I do not want to deploy them during installation: I only want to use them in some CustomAction my purpose is to include an existing exe/dll and call it during installation from wxs code (not from a CustomAction dll).
Is it possible to include files which are not deployed during installation? I mean, only pack them inside the resulting MSI, and call them for some task while they are unpacked inside %temp% folder?
Also, it would be nice if somebody could show some sample code of how to include dll/exe through the Product.wxs XML code unit.
Thanks.
Yes, include them using the Binary element.
<Binary Id='MyCustomActionBinary'
SourceFile='$(var.CustomActionProject.TargetPath)' />
This will make them available to your CustomAction where you can use the BinaryKey attribute to reference the Binary:
<CustomAction Id='MyCustomAction'
BinaryKey='MyCustomActionBinary'
DllEntry='MyCustomFunction'
Execute='deferred' />
If you are using C#/DTF to write a custom action, you simply add the DLL's as references. For any other kind of file you add them to the project as Content | CopyAlways and the build will automatically include these files in the self extracting custom action. They will be available in the current directory ( a temp directory) when the CA runs and automatically cleaned up when the CA ends.

How do I detect my software is running in my Wix MSI?

I have an MSI which is going to install/update a driver. However I want to detect if the driver is running and shut it down before starting the install. I need to do this silently as the customers are using active directory to deploy to computers.
Using the WIX install scripts, how do I do this?
Not sure if I am missing something here but if you need to shut down a driver before installing, then a custom action would be the best approach, in my opinion.
You can write custom actions either by using VB scripts or calling into managed assemblies. I like the latter more (personal preference of C# instead of VB). The custom action in WiX source file would look like that:
Declare the binary element which represents the assembly to be called into:
<Binary Id="BIN_DriverManagement" SourceFile=".\DriverManagement.CA.dll />
Then define the custom action, calling the method of the assembly:
<CustomAction Id="CACT_ShutDownDriverAction" BinaryKey="BIN_DriverManagement" DllEntry="ShutDownDriver" />
The last step would be schedulling the custom action into the installation sequence:
<InstallExecuteSequence>
<Custom Action="CACT_ShutDownDriverAction" After="LaunchConditions" />
</InstallexecuteSequence>
Actually, I am not sure when such custom action should be scheduled, it depends on the requirements.
The custom action function, implemented in C# should be prepended with [CustomAction] attribute from the Microsoft.Deployment.WindowsInstaller namespace, so it might look like this:
[Microsoft.Deployment.WindowsInstaller.CustomAction]
public static ActionResult ShutDownDriver(Session session)
{
// Shut down the driver here.
}

Wix: Registering and then starting a Windows Service

I have a situation where I have been asked to re-implement and InstallShield installer in Wix. I am having difficulty with examples on the Internet trying to implement the exact behavior. What I need to do is the following:
When the user clicks the Install button on the VerifyReadyDlg (I am using Mondo) and the ProgressDlg comes up:
Call a .exe in the install location (if exists from a previous install)
Stop a service in the install location (if exists from a previous install)
Unregister the said service (if exists from a previous install)
Copy files from the MSI, including a copy of the service .exe to install location
Read data from some Edit controls on a previous dialog and write the data to some of the copied .xml configuration files that are now in the install location
Register the service again
On clicking the Finish button on the very final dialog (ExitDlg) I need to:
Start the service again
Call an .exe (different to the first one) in the install location
I can copy files and write data to some of the files after they have been copied...though Wix just does this...I don't tell it when to go and do it. The problem is I need to schedule the first .exe call, Service Stop and Unregister before the Copy action starts and I can only Register again AFTER the .xml config files have been updated.
I have been trying to use InstallExecuteSequence and ServiceInstall elements and tying them together with CustomActions, but it's not coming together and I think I am totally approaching this the wrong way...it's not worth posting what I have done.
How should I go about this? This is a common pattern that I have seen in InstallSheild scripts, yet I can't find any Wix examples doing this sequence.
Thanks a HUGE bunch for any help on this.
Michael.
You can control when your actions are scheduled using Before or After attributes of Custom element or the elements for standard actions.
Is the current installation made with MSI? If yes, you may want to do upgrade installation and schedule RemoveExistingProducts after you copy existing config but before other install actions are performed. This way the previous package will be removed with its own uninstall logic, and then you can install the updated package.
To save configuration from the previous version, you have to run an action before RemoveExistingProducts is executed.
You may wish to use a Custom Action that you define in C# from a project you create that outputs to a DLL file:
public static class CustomActions
{
[CustomAction]
public static ActionResult DoSomething(Session session) {
// Put C# code here that does what you describe, such as run an exe
// from the command prompt.
return ActionResult.Success;
}
}
Import this DLL into your Wix installer:
<!-- The custom action DLL itself.-->
<Binary Id="WebAppCA" SourceFile="$(var.SolutionDir)..\WebAppInstallCustomActions\bin\Debug\WebAppInstallCustomActions.CA.dll" />
<!-- The custom action that does something that you can use. -->
<CustomAction Id="DoSomething"
BinaryKey="WebAppCA"
DllEntry="DoSomething"
Execute="immediate"
Return="check" />
If you wanna check out a complete solution, see this thread on John Robbins' Blog (link)...he has a Wix installer that installs an IIS site but when you start it, it uses a Custom Action defined in C# to enumerate a list of web sites.

How to have a quiet execution of a file in binary table during the InstallUISequence?

I have a file which is not installed:
<Binary Id="LaunchMyExe" SourceFile="$(var.Project.DependenciesPath)/myProgram.exe" />
And I would like to run it quietly during the InstallUISequence but I can't..
How to link the BinaryKey of this file to the CAQuietExec custom action?
Any sample appreciated.. thanks!!
You'll have to author another custom action, which will extract that file from Binary and place to some folder known to your "LaunchMyExe" action, for instance, Temp folder.
Is your program a console application? If it's a regular GUI application, you, most probably, don't need CAQuietExec action because you can run it directly with CustomAction element.
Set these properties:
BinaryKey="LaunchMyExe" - this is the key into the Binary table where your exe is stored.
ExeCommand="" - this tells WiX and Windows Installer you want type 2 custom action.
set other properties as appropriate.
If your application is a console one, then you would need WiX Quiet Execution Custom Action to hide the console window while it runs.
These links would help you:
Quiet Execution Custom Action gives examples on how to use QtExec action.
How To: Run the Installed Application After Setup for an overview on using custom actions.