4

We have a Visual Studio 2012 project (C#) that uses multiple COM references. I am bringing it into Git and am having trouble figuring out how to handle the COM references. If I add the COM references in the typical way, (Add Reference -> COM tab -> Select my references), the following situation occurs:

Visual Studio adds a mention of the references in the *.csproj file which includes a GUID field and version field. From this, I take it that Visual Studio looks in the windows\system32 folder and finds the requisite DLLs at build time. On some development PCs, we have windows 8 and on others we have Windows 7 and it turns out that each version of Windows references different versions of COM DLLs. So, if I: 1) add the references on a Windows 8 PC; 2) commit the project to Git; 3) checkout the project on a Windows 7 pc; 4) attempt to build the project on the windows 7 pc -- the build fails. This is because the Windows 7 pc had different versions of the COM DLLs than are on the Windows 8 PC.

What is the best way to handle this situation? Should I manually copy the necessary COM DLLs into my project folder and version them in Git? If I do this, how would I handle updates that Microsoft makes to their DLLs? (Periodically check for difference in the windows\system32 folder?) And also -- which version would I copy into the project folder -- those that come with Windows 8 or Windows 7?

Adrian
  • 73
  • 3
elsevers
  • 532
  • 1
  • 4
  • 16

1 Answers1

8

I don't see any major differences, both type libraries are at version 1.0 and have not changed that I know of since Vista. Adding the references on a Win7 machine produces the exact same reference nodes:

<COMReference Include="CERTCLIENTLib">
  <Guid>{372FCE32-4324-11D0-8810-00A0C903B83C}</Guid>
  <VersionMajor>1</VersionMajor>
  <VersionMinor>0</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>tlbimp</WrapperTool>
  <Isolated>False</Isolated>
  <EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="CERTENROLLLib">
  <Guid>{728AB348-217D-11DA-B2A4-000E7BBB2B09}</Guid>
  <VersionMajor>1</VersionMajor>
  <VersionMinor>0</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>tlbimp</WrapperTool>
  <Isolated>False</Isolated>
  <EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>

But, as noted in the comment, the CERTCLIENTLib type library name was changed to CERTCLILib. The exact reason for these names changes are not that clear to me, it was possibly done to make it match the description attribute better. I've seen this happen once before.

This does not in any way affect the way the COM code works, it does however affect C# code since the type library importer picks the name of the type library as the namespace name for the declarations in the library. Which doesn't matter at all either, the Tlbimp.exe utility allows using the /namespace option to change the namespace name.

Unfortunately that option is not available when you add the reference directly and let the build system generate the interop library. You'll have to run Tlbimp.exe yourself to work around this. Do so from the Visual Studio Command Prompt:

cd \where\your\project\is\stored
tlbimp c:\windows\system32\certcli.dll

Add the generated DLL to source control and add a reference to it. Do make a note about this in your source code file, this may bite 10 years from now.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks! You are right -- the same Guids are used on both the Windows 7 and Windows 8 PCs. However, there is a difference in the COMReference name: on the Windows 7 pc, everything looks exactly as you have shown above; but on the windows 8 PC, `CERTCLIENTLib` is replaced with `CERTCLILib` and the same naming difference applies to the namespace (on the Windows 7 PC: `using CERTCLIENTLib;` and on Windows 8: `using CERTCLILib;`). Any ideas on what I can do about this? Do I need to run Tlbimp myself, as you suggest? – elsevers May 04 '14 at 17:02
  • Okay, I see that too. Yes, Tlbimp will solve this, copy the interop assembly it generates to your project directory and check it into source control. Use Browse to add the reference to it. Put a note about this in your source file, this may bite 10 years from now. – Hans Passant May 04 '14 at 17:23
  • Thank you. This works great! It seems like maybe an alternative would be to notice at compile time if the development pc has a namespace for CERTCLIENTLib or CERTCLILib and then using the corresponding `using` expression? Maybe this is not worth the effort? – elsevers May 04 '14 at 19:21