DTF is copying custom action dll files - wix

I have msi setup that was created in installshield and I am executing the DTF custom action dll as a commit custom action. If I insert MessageBox.Show into the custom action, I can see that there is a temporary folder inside [PROGRAMFILESDIR] called "CustomActionProject.CA.dll-" and there is copied CustomActionProject.CA.dll with all its references.
Is there any way to tell the technology not to create this temp folder and extract+execute the CustomActionProject.CA.dll in the same folder where is .CA.dll located?
Edit:
I found out that I can not include the references in .CA.dll by configuring wix.ca.targets. Which prevents .CA.dll to contain 20MB of dlls in my case.
Now I would like to make sure that CustomActionProject.dll will be able to see the references that are installed with the product.
The files are:
<ProgramFilesFolder>
<MyApplicationFolder>
CustomActionProject.CA.dll
... About 30 dlls installed with the application that CustomActionProject.dll needs to call
<Place I Would Like to See CustomActionProject.dll extracted>

DTF automatically extracts it's files to a temp folder for execution and then cleans up on disposal. This is very good in that it eliminates certain race conditions. You can still author those files into your installer if you like. For example, at a previous company, our installer used several DLL's for license checking during the install and installed them for use by the application at runtime.
BTW, make sure you've seen this:
WiX DTF Behavior Alert

Your custom action was programmed in a managed .Net language (probably C# or VB.Net). As msi files may only contain dll custom actions comprised of native code the DTF tools, specifically the tool makesfxca.exe, packs / wraps the managed dll together with helper code resulting in a self extracting, native code dll. Following WIX´s naming convention the native custom action dll contains an .CA infix.
In order for this (i.e. having custom actions written in languages producing managed code) to work, self extraction has to take place. So the short answer to your question is "No".

Related

wix burn custom bootstrapper - custom compiler extension

I have a custom bootstrapper using burn, in which I have to detect the driver version of a specific printer on startup and store this value in a burn variable for later usage. Until now, I did this in the overriden Run method of BootstrapperApplication, but I would rather create a WixExtension, to be able to do something like this:
<customUtil:PrinterDriverVersion PrinterName="somePrinter"
Variable="variableToStoreVersionValue" />
This would be similar to the RegistrySearch element in wix's UtilExtension.
There is an example of a CompilerExtension in the book "WiX 3.6: A Developer's Guide To Windows Installer XML", but I don't get it. Why do I need a new msi table? I just want to use that in burn, not in an msi installer?
I looked at the source code of wix, trying to understand, how the RegistrySearch element works. So UtilCompiler just parses the xml attributes and then creates some rows in the WixRegistrySearch table. This table gets iterated by the binder, who writes all searches in the BurnManifest and then creates the resulting output file (.exe). But when and where do this searches get executed at runtime?
Is a CompilerExtension capable to get my task done, or am I on the wrong way?
WiX doesn't have this functionality today. This use case is also needed for the VSExtension to support installing VSIX packages into VS2017 with a bundle, since code needs to be executed to detect VS2017 instances. I created a feature request here.
The UtilExtension searches are special. As you said, they end up in the BurnManifest. The code that executes the searches is in the Burn engine.

Wix generate single component id for entire tree

I am someone with little to no experience with wix and I am trying to support Windows also for the component I am responsible for. I am trying to create merge module for a set of files that my product generates. These files exist in numerous sub directories. I was wondering how I can create a single component ID for all the files in the entire tree. I am not worried about minor upgrades as that is something I am not going to be doing. I am trying to avoid generating numerous GUIDs for each of the file.
Also is there any way I can change the name of the root directory I want the files to be installed. Currently, in our build system the files I want to install end up in a directory name "install". In the wxs file generated by heat it comes up as install. I was wondering if I could change it to the actual product name instead of "install".
Use one file per component - this avoids all sorts of problems (except .NET assemblies spanning multiple files). See the following thread: One file per component or several files per component?
Wix is a great framework for creating installers, but it has a steep learning curve. I strongly recommend you read a few sections of this great, online tutorial: https://www.firegiant.com/wix/tutorial/
If you are a "sample based tinkerer", you can find an even quicker, sample based tour in this article: http://www.codeproject.com/Tips/105638/A-quick-introduction-Create-an-MSI-installer-with
Wix is hands-on. Just focus on the samples, and focus on getting the components created and a major upgrade set up:
How to implement WiX installer upgrade? (modern, convenience way)
How to get WiX major upgrade working? (legacy way - more flexible, less convenient)
http://wixtoolset.org/documentation/manual/v3/howtos/updates/major_upgrade.html
Once you got that running the rest of the details fall into place by reading the documentation for whatever feature you need. Using Visual Studio / Votive with intellisense ensures that you can learn as you go with features such as shortcuts, ini files, xml files, dialogs, etc...
Another top tip is to use dark.exe (part of the Wix toolkit) to decompile existing MSI files. This yields Wix XML with code you can copy and paste into your own Wix files. I use other MSI tools to compile such MSI files, and then copy the sections I need into my Wix file - just to speed up the process of creating the Wix XML. Studying the decompiled XML is very educational - a real time saver.
UPDATE, May 2021: Some more links:
WiX Quick Start - Very long version
WiX Quick Start - Short version
If all the files are going to the same destination folder, then you can create one single COMPONENT with all the FILE within it. There is nothing stopping you to do that. You can then just create one GUID for that component. Also read these answers which talks about the advantages vs disadvantages of one component vs multiple components before you implement it: Answer1 Answer2. To Summarize:
You will have trouble with minor upgrades/repairs. If a component is
being updated, only the file designated as the KEYPATH is checked to see if
it is out of date: if it is up to date, all the others are ignored.
You'll also have difficulty if you want to add or remove files from each
component. Once released, a component is immutable (in terms of what files
are in it). The only way to update it without breaking component rules would
be to effectively remove and install the a new version of the MSI.
Understanding the component rules is key in Windows Installer and one file
per component makes the component rules easier to work with, which is why it
is the recommendation of many people here.
LINK
The root directory name can be changed by modifying the "Name" property for the DIRECTORY element.

run script of batch file from within WIX

I implement wix to generate some msi. I'd like to maintain .bat file (that is packed within this wix project) to contain some work to do (and to be activated with some custom action)
I added the .bet to my wix project in VS2010.
My question is
how do I actually wrap it within the msi that on target machine the script will be available to run?
How do I actually refer to that embedded batch file in the custom section element
This might not be the answer you're looking for, but I strongly recommend you NOT going this way. Running batch file from inside the MSI package has a number of disadvantages, which will shoot you one day:
antivirus might block the execution
as for any deferred custom action (the one which changes the target system state) you'll have to create a rollback action, and for a batch file which might include a number of steps of different nature it could be much more difficult
you don't have the progress (I doubt this is at all possible for batch script)
Instead, I encourage you to do the following:
analyze your batch script and make a list of exact things it does to the target system
take a look at the standard Windows Installer functionality and WiX extensions to see what's there out of the box
design your installation to use standard functionality as much as possible and custom actions as little as possible
if you still need a custom action, stick to the DLL ones and make sure rollback actions are present for deferred actions
You're looking for what I think is a type 18 custom action:
The executable is generated from a file installed with the application. The
Source field of the CustomAction table contains a key to the File table. The
location of the custom action code is determined by the resolution of the target
path for this file; therefore this custom action must be called after the file
has been installed and before it is removed.
The CustomAction element has the ExeCommand attribute for just this sort of occasion. It would look something like this:
<CustomAction Id="ExecuteMyBatchFile"
FileKey="[#FileKey]"
ExeCommand="Arguments passed to batch file"
Execute="deferred"/>
Of course, this is assuming the batch file is installed by the msi.

Accessing embedded resources in Wix DTF Custom Action

My DTF project contains some embedded resources and I would like to access the same in the CustomAction.
I tried the following code in the Custom Action method
// Gets the current assembly.
Assembly Asm = Assembly.GetExecutingAssembly();
// Resources are named using a fully qualified name.
Stream strm = Asm.GetManifestResourceStream(Asm.GetName().Name + "." + Name);
However this doesnt work as Asm always refers to the Wix Setup assembly and not the custom action dll which contains the resources
Why not use Assembly.GetAssembly(typeof(CustomAction));, to get the assembly that contains your custom action?
To be honest, I'm not sure this scenario is possible. I mean, there might be no option (or no easy option) to get the custom action executing assembly and extract the resources out of it.
Instead of this, I would try to re-design the solution and move resources to the Binary table in MSI package. Thus, you'll still have embedded resources, but not in CA DLL, but in the MSI package itself. The DTF.chm help file contains a sample how to extract files from Binary table - it's a matter of a couple of lines of code.

Installshield use a custom dll from another custom dll

I am refactoring an old installshield application and I need to perform a action that calls a function from a custom dll. Unfortunately the function that this action performs depends on another custom dll. So my question is:"Is it possible to have a custom dll depend on another custom dll and if so how?"
When I try to run the installer it crashes with the error "Setup was interrupted before being complete..." Then I copied the second custom dll to a folder that I added to PATH and everything went fine. Of course I can not expect my customer to do that by hand.
I am using Installshield 2008 but I believe the answer to my question will be the same for all versions.
EDIT: as maybe my question is not clear enough I will give example:
Let's say I have a.dll that has a function:
UINT __stdcall
PerformAction(MSIHANDLE hInstall) // IN
{
...
help();
...
}
help() is defined in b.dll. Now when I create a new action I set it's dll to be a.dll and it's function name to be PerformAction but there is no way to indicate this depends on b.dll
When I copy b.dll to a folder included to PATH the installer works ok but if I don't it fails.
The easiest InstallShield approach here is to use support files instead of or in addition to binary table entries. Windows Installer will only extract a single DLL for a custom action, but if you reference a file in SUPPORTDIR, it can use more than one.