tlbimp.exe generated assembly fails to be registered using regasm.exe

0

I have a native COM dll that I want to build a C# interop assembly for. I'm attempting to do this using tlbimp.exe to generate the c# assembly, and I then regasm.exe to register the assembly for transparent use via COM in another program. I'm delay signing since I'm still in a development environment and wish to do some debugging still.

The TlbImp.exe command seems to work fine, the interop file is generated.

c:\>tlbimp MyNativeComDll.dll /out:MyInteropDll.dll /publickey:myPublicKey.snk /asmversion:1.6.0.0 /delaysign
TlbImp : Type library imported to C:\MyInteropDll.dll
Microsoft .NET Framework Assembly Registration Utility version 4.6.1055.0
for Microsoft .NET Framework version 4.6.1055.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Unfortunately, its the regasm call that results in an error that I have no idea how to fix.

C:\>regasm C:\MyInteropDll.dll
RegAsm : error RA0000 : Could not load file or assembly 'MyInteropDll.dll, Version=1.6.0.0, Culture=neutral, PublicKeyToken=****************' or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A)

The system I am build this all on is a x64 windows machine running Windows 7sp1. The MyNativeComDll.dll is a x86 library. All this is being done in a vcxproj post build command, the project being the one that builds the MyNativeComDll.dll. I use MSBuild from the command line to build the solution. I have both Visual Studio 2010, and Visual Studio 2015 installed, and the build fails when running the regasm command whether or not I am using VS2010's Win64 or Regular Developers command prompt. Similarly it fails in much the same fashion when using the VS2015 x64 Native Tools command prompt, or the Developer Command Prompt for VS2015.

The command I use to build the solution that contains the project causing the problem is:

C:\>msbuild MySolution.sln /p:Configuration=Release /v:n /t:Rebuild /p:Platform="Mixed Platforms"

The solution contains a number of x86 visual c++ projects and a few c# projects which are build as AnyCPU. The resultant main application is supposed to be a 32bit app. All c# projects are targeting .net 4.0.

Why would regasm report that it cannot load the file or assembly? I've looked at the MyInteropDll.dll file in DotPeak and see absolutely no dependencies beyond mscorelib 4.0 listed. Is it a signing problem, or is it a references issue?

c#
c++
com
asked on Stack Overflow Jul 14, 2016 by sbrett

1 Answer

0

After looking through the post suggested by @Mangist, I recognized that the issue was a combination of registry location, and misunderstanding tlbimp.exe 's delaysign flag. This also helped. https://msdn.microsoft.com/en-us/library/aa302324.aspx

First, as my app is a x86 application and most of the libraries are x86, using the x64 command prompts is a bad idea, as any tool that affects the registry will write to the HKLM\Software location. Since these are x86 assemblies, any registry entries regarding them need to be written to the HKLM\Software\Wow6432Node location. This mistake was triggered by what I found regarding tlbimp.exe, as when I was using the x86 command line tools, I was still getting the regasm error, prompting me to attempt the build using the x64 command line tools, which of course also didn't work.

Tlbimp.exe indeed does have an option to delay sign an assembly, and it will do exactly that, but delay signing an assembly DOES NOT AUTOMATICALLY REGISTER THE ASSEMBLY FOR VERIFICATION SKIPPING. Registering an assembly for verification skipping requires use of the sn.exe command with the -Vr option. This adds an entry to the HKLM\Software\Wow6432Node\Microsoft\StrongName\Verification registry key when using the 32 bit sn.exe, and the HKLM\Software\Microsoft\StrongName\Verification registry key when using the 64 bit sn.exe.

It turns out that you can register a single assembly signed with a particular public key for verification skipping, or any assembly that uses a particular public key for verification skipping. A registry entry will be created looking like

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\*,58845dcd9090cc91]

Here * is a wildcard, and the hex number is the public key.

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\StrongName\Verification\MyInteropDll.dll,58845dcd9090cc91]

This entry is an example of allowing only the MyInteropDll.dll assembly to be skipped from signing verification.

The solution for me then is to ensure that after I make the tlbimp /delaysign call to add a command that registers the assembly for verification skipping since that's not being done automatically.

C:\>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\sn.exe -Vr MyInteropDll.dll
answered on Stack Overflow Jul 14, 2016 by sbrett

User contributions licensed under CC BY-SA 3.0