4

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.

Community
  • 1
  • 1
Rob
  • 4,327
  • 6
  • 29
  • 55
  • I don't think there IS such a thing as a platform agnostic com reference, i suspect that the new CLR/jitter was able to detect the x86 dependency and specifically compile for x86 so it would work. Just a stab in the dark though. – Ben Robinson Feb 06 '12 at 12:08

2 Answers2

9

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.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • This is exactly what I ended up doing. I emphasised *seemed* as I'm not really sure how this works. But I can confirm that somehow VS2010 dotnet 4 test projects somehow got this to work – Rob Feb 07 '12 at 10:05
  • Actually - this is configurable in the test settings. We were executing our tests in 64 bit process, which is why we had a problem in the first place. – Rob Feb 07 '12 at 11:56
0

I was able to get MSBuild to generate a platform agnostic COMReference by explicitly setting the ProcessorArchitecture property to Agnostic in my csproj file:

<PropertyGroup>
  <ProcessorArchitecture>Agnostic</ProcessorArchitecture>
</PropertyGroup>

I figured it out by looking at the ResolveComReference MSBuild task in Microsoft.Common.CurrentVersion.targets which passes this value to tlbimp.exe /machine flag.

That being said, I chose to use Hans Passant's solution, i.e. manually generating the DLL and adding it to source control because it is build server friendly.

0xced
  • 25,219
  • 10
  • 103
  • 255