Deploying and Registering Com Interop interfaces - wix

I am attempting to deploy my new .net Com visible interfaces. After installation my new .dll could be loaded by my app. There is a requirement to cast one of the interfaces which is not working.
I am harvesting my wix xml with the use of Heat.
"C:\Program Files (x86)\WiX Toolset v3.10\bin\heat.exe" file "MYComConnect.dll" /out "dll_fragment_12_2015.wxs"
"C:\Program Files (x86)\WiX Toolset v3.10\bin\heat.exe" file "MYComConnect.tlb" -scom /out "tlb_fragment_12_2015.wxs"
To know that it is not a coding problem with my .dll I have registered my .dll and .tlb with regasm and everything works fine.
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "MYComConnect.dll" /tlb
I then did a registry comparison of what is added by regasm and what my wix installer adds.
I noticed that the following folders keys were added by regasm but were NOT added by my wix install (corresponding values were also added by regasm but I will not post it all)
HKLM\SOFTWARE\Classes\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}
HKLM\SOFTWARE\Classes\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}\TypeLib
HKLM\SOFTWARE\Classes\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}
HKLM\SOFTWARE\Classes\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}\TypeLib
HKLM\SOFTWARE\Classes\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}
HKLM\SOFTWARE\Classes\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}\TypeLib
HKLM\SOFTWARE\Classes\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}
HKLM\SOFTWARE\Classes\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}\TypeLib
It seems that my wix install only adds registry keys in Wow6432Node. Regasm adds keys to both.
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}\TypeLib
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}\TypeLib
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}\TypeLib
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}\TypeLib
The other difference I noted is that heat has the following entry for each class whereas Regasm does not have it
HKLM\SOFTWARE\Classes\Wow6432Node\CLSID\{FB1D6314-4409-46E9-BD92-DDD99D110CDE}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}\: ""
I have read that it does not matter where the interfaces are registered as they do not depend on bitness however after a comparison of what regasm does and what heat harvests it appears that if the interfaces are not added to both the x64 and x32 registry then it does not work.
Just the first RegistryValue element from my heat harvested interface fragment looks like this below. This adds the element to the Wow6432Node.
<Fragment>
<DirectoryRef Id="MYAPPCOMINTEROP">
<Component Id="Com_Interop_TLB" Guid="{F8F60B35-0270-4569-8F0F-9D09398C72D8}">
<File Id="fil460187E36ECD90A7A9A00591ADB1C5CB" Name="MYComConnect.tlb" KeyPath="yes" Source="..\..\MYComConnectReferencedDLL\MYComConnect.tlb" />
<RegistryValue Root="HKCR" Key="Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}" Value="_MYAppConnect" Type="string" Action="write" />
So in the absence of another solution I want to follow what regasm does with the registry entries, how can I achieve that with my Wix xml.
Edit - Further information
Target computer is Win 7 x64 with Office 2010 x86
My Main App has Target CPU x86
Com Visible .dll Target CPU is AnyCPU (the dll is used by Office and my App)
MSI is x64 (as I already have a context menu .dll which needs to write registry items to x64 so that Windows' x64 Explorer will read them.
I hope this does not complicate things but what my COM Visible dll does is allows me to call code in a VSTO addin. I dont think this code is necessary as I can get my custom object from Office and cast it to my custom interface with no problems if I use regasm to register my .dll and create the tlb file.
I actually unregistered everything on my development PC and installed my final MSI. My .dll works and I can cast my interface. What assumptions can I make from this? I am assuming that the problem lies with my Com .dll and building it and thus my problem has nothing to do with my heat harvesting and wix xml coding.
Update 2 of Problem
I obtained a second PC with Visual Studio on it. I Copied my Com .dll project on it and built it. I Created the .tlb file with Tlbexp.exe on this PC. I then installed this with my MSI and I can now cast the COM interface.
So I now have to work out why building it on one PC it works and on another it does not. The most major difference right now is that the PC that works has Win 7 on it, the one that does not work is Win 10.

It might help to know the bitness of your app and your MSI build(s).
A 32-bit app will have a 32-bit registry view, and will need CLSID references to 32-bit COM dlls. Interface entries may refer to a ProxyStub CLSID that will also need to be 32-bit and that means that the interface entries have bitness. That's my understanding anyway, so your COM Dll needs CLSID and Interface references in HKCR (HKL\Software\Classes) in both native and 32-bit WoW6432 if it has both 64 and 32-bit callers.
In WiX, you'd add Win64=yes to the component to make it 64-bit. If you have 32 and 64-bit callers to your COM, then in a 64-bit MSI you'd add both 32 and 64-bit components for your COM, and in a separate 32-bit MSI just the 32-bit components. Heat doesn't know the bitness of your final MSI, so it's up to you to use Win64 on components to target the required registry view.

Related

Verify that dll is registered - Installshield

I'm building a MSI that targets both 64 and 32 bit platforms, it contains a dll that is only being registered on 64 os. I'm using a custom action to register and unregister the dll :
when uninstalling the software and if the dll was manually unregistered, Uninstallation fails because the regsvr32 /u fails.
regsvr32 /u /s [InstallPath]filename.dll
how to check whether the dll is registered before launching the custom action.
You shouldn't be building one MSI package for both architectures:
http://blogs.msdn.com/b/heaths/archive/2008/01/15/different-packages-are-required-for-different-processor-architectures.aspx
and you shouldn't be running regsvr32. Most installer tools have mechanisms to extract registration info into registry entries so that no code is required to run at install time. Tools that don't do that will still let you add your Dll to the MSI file's SelfReg table, and both these alternatives are better than running regsvr32.
Note that if you are in a 32-bit install, some (if not all) attempts to access the 64-bit folders are going to be redirected to the 32-bit equivalents, another reason for not using regsvr32 and creating separate packages.

Registering DLLs and .TLBs

I am working for a company that registers a lot of COM DLLs in the System32 folder/SYSWOW64 folder. I recall a question some time ago where Hans Passent said that this is wrong as the folders specified are for Windows DLLs. I cannot find the post so I want to check that this is correct?
Also if I want to register a COM DLL or a TypeLibrary in a foreign folder then can I just use the following command (for COM):
regsvr32 app.dll
Finally I was reading about the CODEBASE flag of Regasm: http://www.vbforums.com/showthread.php?597928-RESOLVED-How-to-delete-a-VB6-Reference. Do you have to use this flag if you want to register a TypeLibrary (.TLB)? What happens if you .NET assembly uses a third party library that is not signed?
If you are talking about installing COM DLLs in the System folder, then you are correct. All applications, and their support libraries, should be installed under the Program Files folders, or the Common Program Files folders.
You are also correct that REGSVR32.EXE can be used to manually register DLLs and OCX. "Foreign folder" is not a Windows concept - you can register a component anywhere in the file system, including the Windows and Windows System folders. By the way, if you use an installer, then you shouldn't have to use REGSVR32.EXE.
However, TLB files cannot be registered with REGSVR32.EXE, because that application basically loads the DLL/OCX, and calls an exported function on the library, so effectively the library registers itself. Instead, you need another tool, e.g. REGTLIB.
You don't use /CODEBASE to register a raw type library, because REGASM is used for registering .NET DLLs as COM components, not TLB files.

Registering DLLs using .reg file in WiX

Background to Question
I am currently in the process of trying to put together a means of distributing a new project I am working on which requires that a COM exposed .NET DLL be registered on the user's system and as I am new to WiX and making the move to it for this I am trying to keep things as simple as possible.
The Problem
The big issue with my DLL registration is that regasm sets the default value of the InProcServer32 key to "mscoree.dll", but my DLL can only seem to be instantiated when the full path to it is used, e.g. "C:\Windows\SysWow64\mscoree.dll"
Currently I have a custom action in my setup project (which I want to abandon to use WiX) which will call the SearchPath API to find the full path to mscoree.dll and overwrite the default value with the full path, so that the DLL can be instantiated without any issues.
Proposed Solution / Question
As I am new to WiX I have had the idea of preparing a .reg file that will contain all the necessary information to go into the CLSID tree and then having WiX execute that some how.
My question is:
Are there any inherent flaws by registering a DLL this way?
As the main reason I am trying to find work arounds here is the mscoree.dll issue, is there any native means of doing this in WiX?
Take a look at the WiX program called "Heat". This can "harvest" your DLL including registry information related to the RegAsm / COMVisible parts. You can then snip this code and work it into your wxs file.
You can also use Regasm /regfile and then manually transform that information into RegistryValue elements.
With regard to your path problem, use the SystemFolder property.
[SystemFolder]mscoree.dll
If you mark your install as 32bit (x86) this will automatically resolve to the SysWow64 folder when run on a 64bit OS and the System32 folder when run on a 32bit OS.

COM registration with WIX in 32bit and 64bit Windows

I created an installer for my AnyCPU DLLs. I've marked my assemblies with teh Assembly=.net directive in my project as well. The installer seems to be able to register the COM servers successfully on my XP 32bit machine, but fails to do so in my Windows7 Machine. I did run the installer in admin mode. Also I looked up the Win764 registry and found those CLSIDs in the reigstry. So looks like the MSI did put some entries in the registry but somehow they are not being recognized as valid COM Server entries (OLE Viewer also didnt enumerate my server).
Any idea why this would happen? Any extra config do I need to add to my project?
thanks
Apparently you need to compile your msi as a 64-bit native binary to have the dlls registered in 64 bit mode.

windows installer for COM component

I have a C++ activex control that I need to make an installer for. It needs to drop the dll and make some registry keys.
I have about 6 .RGS files which I made for self-registration via regsvr32, which work.
To do an installer I am manually porting the RGS scripts into the visual studio 2008 windows installer registry GUI. I feel like its not possible to do an exact port (e.g. RGS keywords like ForceRemove).
Isn't there a way to generate these files from the IDL file? Am I doing this wrong?
SelfReg is not a best practice in an MSI install because it's out of process and fragile. Visual Studio 2008 Installers are limited but you should be able to set the Register property to vsdrfCOM instead of vsdrfCOMSelfReg. This will cause the COM meta data to be harvested from your DLL and authored natively in MSI.
After you build your MSI, you should notice the SelfReg table is empty and a serious of automatically authored rows in the Registry table for you COM data.
Note: VDPROJ is kind of flakey at extracting this COM so it may not work. You might have to consider a stronger tool such as InstallShield or Windows Installer XML.
You are doing it wrong. The .rgs files are there so that the component can install itself. Any installer supports letting a component install itself. A Visual Studio Setup project for example, set the Register property.