views:

51

answers:

1

I'm really struggling with WiX. I have .NET assemblies to install that require registration for COM Interop, AND they must be registered with another framework that requires calling a Register() method in a .NET assembly that's in the GAC. This registration method is a 'black box' with a hidden storage mechanism so I can't perform this operation declaratively.

I get that the declaritive approach is best for COM registration, but I have two problems with using heat.exe:

  1. RegAsm works, but Heat.exe chokes on my assembly with the message:

    heat.exe : warning HEAT5151 : Could not harvest data from a file that was expected to be an assembly: C:[...].dll. If this file is not an assembly you can ignore this warning. Otherwise, this error detail may be helpful to diagnose the failure: Exception has been thrown by the t arget of an invocation.

  2. The secondary registration that I need to do relies on the [ComRegisterFunction] attribute, which normally triggers further actions at the time the assembly is registered for COM Interop. This normally happens when the assembly is registered by RegAsm.exe or by calling System.Runtime.InteropServices.RegistrationServices. So, I need that ComRegisterFunction in my assembly to execute during the installation.

I don't mind taking the declarative approach to COM registration (or I wouldn't mind if heat worked on my assembly) but I need to call that ComRegisterFunction as part of the install. Ideally, I'd like to look at all of the executables I'm installing, reflect on them for any methods with the [ComRegisterFunction] attribute and call those methods, this would be done after all files are installed.

How can I achieve this in WiX? Or, is there another approach? If it makes any difference, I am using the 'Votive' Visual Studio integration with project references.

+1  A: 

These are opposing goals. The point of using the declarative approach is to not use Regasm.exe or Regsvr32.exe to call the registration function. In other words, your [ComRegisterFunction] attributed method won't be called. You can't have both.

The exception that heat.exe dies on isn't healthy, it indicates that there's something wrong with your registration function or class contructor. Debug this by making your DLL the startup project. Project + Properties, Debug tab and make heat.exe the startup program. Set the command line to your DLL. Debug + Exceptions and tick the Thrown box for CLR exceptions, the debugger will stop when the exception is thrown.

Oh, and don't forget to call RegistrationServices.RegisterAssembly in your register function. Regasm.exe won't do it automatically anymore since you used the attribute.

Hans Passant
Thanks for the debugging tips, I'll try it now. The assembly does work OK though. I can load it from PowerShell for example. But let's see what turns up.
Tim Long
Can I explore the last statement, if I understand you correctly, you;re saying that if my code uses the ComRegisterFunction attribute, then RegAsm will no longer perform the COM registration, but will expect my code to do it manually? Just want to be sure I understood correctly.
Tim Long
That is correct. You can easily verify this with Regedit.exe
Hans Passant
OK, I have tried the experiment, and assemblies DO get registered correctly even if there is a [ComRegisterFunction] that does nothing but display a message box. So [ComRegisterFunction] is a hook that lets you do _additional registration_, it does not replace what RegAsm does.
Tim Long
The good news is, I found out why Heat is choking. There's an exception being thrown by a related component in the constructor - so spot on with that one.
Tim Long
I'm opening another (related) question because this one got sidetracked into the Heat issue. See http://stackoverflow.com/questions/3902677/how-can-i-get-wix-to-call-a-method-in-a-net-assembly-as-part-of-the-installation
Tim Long
Note, if you read the MSDN topic on RegAsm you'll see that RegAsm /Regfile doesn't process user code so sometimes heat won't harvest what you are looking for.
Christopher Painter
Good thing Heat choked on that constructor and not the installer on some users machine, heh? Trust me, Regasm / Regsvr is an evil antipattern that relies on injecting untrusted out of process code into the critical execution path of installing software.
Christopher Painter