用于创建 XML 序列化程序程序集的 Sgen 和 x64 项目配置
Sgen and x64 project configuration to create XML Serializers assembly
貌似还有很多类似的问题没有很好的解释。
环境:
赢 7
VS2012 专业版
Windows SDK 7.0
在我们的环境中,我们生成了 2 个代码库 - x86 和 x64。对于这个特定项目,我们生成 *.XMlSerializers.dll
。 Generate Serialization Assemblies 的构建设置是 Auto
.
当我将项目编译为 x64 配置时,出现 SGEN 错误 "attempt load assembly in incorrect format... system.data.dll"。此错误完全具有误导性,因为进一步调查得出以下结果:
我使用 sysinternals
中的 procmon
来追踪 SGEN
- 当为 AnyCpu 和 x86 构建时,procmon 显示跟踪。使用的 sgen 来自
C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin
(32-bit sngen.exe)
- 为 x64 构建时没有跟踪,只有上述错误
我将项目配置设置为 OFF 以创建序列化程序并在 x64 中编译程序集。然后我尝试了命令行
- 成功来自于在
C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\x64
中使用 SGEN -(请注意 - 这是 64 位 sgen.exe)
- 运行 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 二进制文件时成功完成。
貌似还有很多类似的问题没有很好的解释。
环境:
赢 7
VS2012 专业版
Windows SDK 7.0
在我们的环境中,我们生成了 2 个代码库 - x86 和 x64。对于这个特定项目,我们生成 *.XMlSerializers.dll
。 Generate Serialization Assemblies 的构建设置是 Auto
.
当我将项目编译为 x64 配置时,出现 SGEN 错误 "attempt load assembly in incorrect format... system.data.dll"。此错误完全具有误导性,因为进一步调查得出以下结果:
我使用 sysinternals
中的 procmon
来追踪 SGEN
- 当为 AnyCpu 和 x86 构建时,procmon 显示跟踪。使用的 sgen 来自
C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin
(32-bit sngen.exe) - 为 x64 构建时没有跟踪,只有上述错误
我将项目配置设置为 OFF 以创建序列化程序并在 x64 中编译程序集。然后我尝试了命令行
- 成功来自于在
C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\x64
中使用 SGEN -(请注意 - 这是 64 位 sgen.exe) - 运行 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 二进制文件时成功完成。