问题
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:
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.
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:
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.
回答2:
I'll caveat my answer by stating that the correct way to do this is as Hans states - via heat.
An alternative however is to use the SelfRegCost attribute of the File element under a Component element.
Below is an example from one of our older setup kits that's thus far been working with no issues.
<File Source="..\..\External References\MSCAL.OCX" SelfRegCost="1"/>
As with any SO answer, best to check this works in your situation and test thoroughly.
来源:https://stackoverflow.com/questions/3901428/wix-register-assemblies-for-com-interop