4

I have a basic MSI InstallShield installation with a managed EXE custom action running from the Binary table. I tried a simple test that just runs a console and that works fine. When I add a .DLL assembly reference to the EXE, it can't find the DLL. How do I make InstallShield aware of this referenced assembly so it can load it with the EXE?

RBT
  • 24,161
  • 21
  • 159
  • 240
tzerb
  • 1,433
  • 1
  • 16
  • 35

4 Answers4

4

Custom Actions only extract a single file to a temporary location under a temporary name. For the dependency on the .dll to work, they need to both be extracted, and at least the .dll must have the expected name. Typically this is easiest to do by adding both to "setup files" and referencing [SUPPORTDIR]\your.exe for the custom action.

Michael Urman
  • 15,737
  • 2
  • 28
  • 44
2

The details here are with respect to InstallShield 2014. Other answers can be equally correct w.r.t. other InstallShield versions. I can see that Michael Urman's answer is from year 2012 and lot has changed since then. Let's see.

There can be two types of dependencies for any .NET assembly:

  1. Managed (written in C# or VB.NET language. OP has this particular case)
  2. Unamanaged or Native (e.g. C++ DLLs called through p/invoke). You do not reference such assemblies in C# project but they are loaded at run-time using DllImport attribtue and a predefined assembly searching mechanism.

Let's understand OP's problem which is the case of dependency on managed assemblies:

InstallShield internally has a small database of its own. So, whenever you add a custom action (in your InstallShield basic MSI project) which calls a method present in a managed assembly then all the attributes of the custom action are put as rows in the ISClrWrap table of the internal database as shown below:

enter image description here

InstallShield doesn't provide any UI or direct mechanism where we can define the dependencies of managed assemblies (the ones you add as reference in any .NET project in Visual Studio). But you can update this database table directly to make InstallShield aware about those references. You need to add one new row for every dependency in this table. For Name column you should choose Dependency0 for the first dependency, Dependency1 for the second dependency and so on (Refer screenshot). A row can be added by pressing New button at the top:

enter image description here

After you have added all your managed dependency assemblies, the table starts looking like this:

enter image description here

That's it. Now, leave the rest to installshield. Now methods present in MyManagedAssembly.dll will be able to call methods present in MyManagedDependencyAssembly1.dll or MyManagedDependencyAssembly2.dll during the installation process.

Notes:

  1. You do not have to add the managed dependency assemblies into Support Files(whose path is represented by [SUPPORTDIR] property). How installshield manages the copying of managed dependency assemblies during the installation process is its internal implementation detail.
  2. The default .NET dependencies of C# project (used in custom action) which are part of Framework Class Library (FCL) e.g. System.dll, Systen.Core.dll, etc. need not be added into this table. They are loaded by default when InstallShield loads CLR to execute managed code.
RBT
  • 24,161
  • 21
  • 159
  • 240
  • Note that the original question was (I believe) launching an EXE that happened to be managed code, rather than explicitly invoking a function from a managed assembly that happens to be an EXE. The approach you describe only works for "Managed Code Custom Actions" -- the ones that invoke functions. (This hasn't changed significantly since [IS2009](https://community.flexerasoftware.com/showthread.php?p=420346#post420346)). – Michael Urman Jan 21 '17 at 14:29
0

I couldn't find a decent way to use .Net custom actions that allowed me to do what I was trying to do. I ended up using the DTF (Deployment Tools Foundation) section of WiX to create the assembly and it worked great.

tzerb
  • 1,433
  • 1
  • 16
  • 35
0

Please add your DLL as a dependency in 'isclrwrap' binary table. You can find that binary table from direct editor. This will solve your problem.

Manthan Shah
  • 130
  • 1
  • 2
  • 8
  • I can see the ISClrWrap table but not sure how to add an assembly into it. I've my .net assembly which loads a native C++ assembly at run time to call some methods through p/invoke. Can you please add some steps into your post on how to achieve it? – RBT Jan 17 '17 at 10:20