Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get MSBuild to generate a platform agnostic COMReference?

I recently switched all our test projects from dotnet 4 to dotnet 3.5 (because I want to test code under CLR 2.0 (see here). Most things work fine, but one test project has a dependency on IWshRuntimeLibrary. This is specified by the following csproj snippet:

<COMReference Include="IWshRuntimeLibrary">
  <Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
  <VersionMajor>1</VersionMajor>
  <VersionMinor>0</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>tlbimp</WrapperTool>
  <Isolated>False</Isolated>
  <EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>

We build the test project as "AnyCPU". When the test project was .Net 4, this seemed to produce an ANYCPU interop dll. Now it's .Net 3.5, the interop dll is x86, which causes a System.BadImageFormatException at runtime on 64 bit platforms. This issue did not occur before downgrading the test projects.

like image 491
Rob Avatar asked Jan 18 '23 13:01

Rob


1 Answers

Seemed is correct, importing the type library in Visual Studio is always going to set the 32-bit flag in the interop assembly header. You can see this by running corflags.exe on the generated assembly.

Creating a platform agnostic interop library from VS isn't supported. You will have to run Tlbimp.exe yourself. Use the Visual Studio Command Prompt and navigate to your project directory. Then run this command:

Tlbimp /machine:Agnostic c:\windows\system32\wshom.ocx

And add a reference to the generated Interop.IWshRuntimeLibrary.dll with Project + Add Reference, Browse tab. It is okay to check-in the DLL in source control, the COM interfaces are cast in stone. Setting the Platform target on your main EXE project to x86 would be another workaround.

like image 157
Hans Passant Avatar answered Feb 12 '23 04:02

Hans Passant