用于创建 XML 序列化程序程序集的 Sgen 和 x64 项目配置

Sgen and x64 project configuration to create XML Serializers assembly

貌似还有很多类似的问题没有很好的解释。

环境:

赢 7

VS2012 专业版

Windows SDK 7.0

在我们的环境中,我们生成了 2 个代码库 - x86 和 x64。对于这个特定项目,我们生成 *.XMlSerializers.dllGenerate Serialization Assemblies 的构建设置是 Auto.

当我将项目编译为 x64 配置时,出现 SGEN 错误 "attempt load assembly in incorrect format... system.data.dll"。此错误完全具有误导性,因为进一步调查得出以下结果:

我使用 sysinternals 中的 procmon 来追踪 SGEN

  1. 当为 AnyCpux86 构建时,procmon 显示跟踪。使用的 sgen 来自 C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin (32-bit sngen.exe)
  2. x64 构建时没有跟踪,只有上述错误

我将项目配置设置为 OFF 以创建序列化程序并在 x64 中编译程序集。然后我尝试了命令行

  1. 成功来自于在 C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\x64 中使用 SGEN -(请注意 - 这是 64 位 sgen.exe)
  2. 运行 x64 程序集上的 32 位 SGEN 失败。

这些结果得出一个结论:当 VS2012 编译项目时 Generate Serialization Assemblies 设置为 ON ( auto 是一个特例),它试图找到 sgen.exe。但是当您的项目配置设置为为 x64 平台构建时,它无法找到合适的 sgen.exe,一个本身是为 x64 构建的。

问题:是否有 msbuild 配置或注册表设置,或其他可以设置为允许 Visual Studio找到合适的SGEN?

我知道解决方法,即 Post 构建事件并将其关闭,但这不是重点。

一般来说,可以把这个XML添加到项目文件的特定配置中,这将指向你想要的特定sgen.exe

<SGenToolPath>C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\x64</SGenToolPath>

但为了以更广泛的、特定于环境的方式解决我的问题,我必须将 Generate Serialization Assembly 设置为 OFF 并单独使用命令行操作 post-build

"path to your specific\sgen.exe" "path\yourFile.dll" /f

我不得不这样做,因为这里的许多开发人员使用不同版本的 VS studio 等。他们设置他们的机器,谁知道他们安装了什么以及安装在哪里。因此,我在构建过程中添加了一个特定的操作来单独执行此步骤,因为我确切地知道特定 sgen.exe 在构建服务器上的位置。

我们要求在编译时构建 xml 序列化程序,因此我们没有不使用创建序列化任务的选项。

但是这个问题与 Sgen.exe 的位置无关,而是与执行 msbuild 目标时构建的引用路径有关 GetReferenceAssemblyPaths

我们终于解决了在每个 .csproj 文件中导入 csharp 目标后追加新目标的问题

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

下一个 xml 片段解决了问题:

<Target Name="Prependx64FrameworkPath" Condition="'$(Platform)' == 'x64'" AfterTargets="GetReferenceAssemblyPaths">
    <Message Importance="normal" Text="Fixing target framework directory for x64 build before running SGen." />
    <PropertyGroup>
        <TargetFrameworkDirectory>C:\Windows\Microsoft.NET\Framework64\v2.0.50727;$(TargetFrameworkDirectory)</TargetFrameworkDirectory>
    </PropertyGroup>
   </Target>

此片段强制将 .net framework x64 路径放在任何其他路径之前,然后搜索引用的任务将在任何其他路径之前找到 x64 dll。

将此添加到每个 .vcproj 后,sgen 在构建 x64 二进制文件时成功完成。