【问题标题】:How do I get MSBuild to generate a platform agnostic COMReference?如何让 MSBuild 生成与平台无关的 COMReference?
【发布时间】:2012-02-27 21:48:31
【问题描述】:

我最近将我们所有的测试项目从 dotnet 4 切换到了 dotnet 3.5(因为我想在 CLR 2.0 下测试代码(请参阅here)。大多数情况都可以正常工作,但是一个测试项目依赖于 IWshRuntimeLibrary。这是由以下 csproj sn -p 指定:

<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>

我们将测试项目构建为“AnyCPU”。当测试项目是 .Net 4 时,这似乎会生成一个 ANYCPU 互操作 dll。现在是 .Net 3.5,互操作 dll 是 x86,这会在 64 位平台上运行时导致 System.BadImageFormatException。在降级测试项目之前不会出现此问题。

【问题讨论】:

  • 我认为不存在平台无关的 com 引用之类的东西,我怀疑新的 CLR/jitter 能够检测 x86 依赖项并专门为 x86 编译,因此它可以工作。不过只是在黑暗中刺伤。

标签: c# com com-interop platform-independent


【解决方案1】:

似乎 是正确的,在 Visual Studio 中导入类型库总是会在互操作程序集标头中设置 32 位标志。您可以通过在生成的程序集上运行 corflags.exe 来查看这一点。

不支持从 VS 创建与平台无关的互操作库。您必须自己运行 Tlbimp.exe。使用 Visual Studio 命令提示符并导航到您的项目目录。然后运行这个命令:

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

然后使用 Project + Add Reference, Browse 选项卡添加对生成的 Interop.IWshRuntimeLibrary.dll 的引用。可以在源代码管理中签入 DLL,COM 接口是一成不变的。将主 EXE 项目的平台目标设置为 x86 是另一种解决方法。

【讨论】:

  • 这正是我最终要做的。我强调似乎,因为我不确定这是如何工作的。但我可以确认 VS2010 dotnet 4 测试项目以某种方式让它工作
  • 实际上 - 这可以在测试设置中进行配置。我们在 64 位进程中执行我们的测试,这就是我们首先遇到问题的原因。
【解决方案2】:

通过在我的 csproj 文件中将 ProcessorArchitecture 属性显式设置为 Agnostic,我能够让 MSBuild 生成与平台无关的 COMReference:

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

我通过查看 Microsoft.Common.CurrentVersion.targets 中的 ResolveComReference MSBuild task 发现了这一点,它将这个值传递给 tlbimp.exe /machine flag

话虽如此,我选择使用 Hans Passant 的解决方案,即手动生成 DLL 并将其添加到源代码管理,因为它是构建服务器友好的。

【讨论】:

    猜你喜欢
    • 2010-10-07
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    相关资源
    最近更新 更多