创建一个新的 sgen 任务定义打破了车轮上的苍蝇。只需设置所需的变量以使任务按预期工作。无论如何,微软文档缺少一些重要信息。
预生成序列化程序集的步骤
(部分来自http://msdn.microsoft.com/en-us/library/ff798449.aspx)
- 在 Visual Studio 2010 的解决方案资源管理器中,右键单击要为其生成序列化程序集的项目,然后单击“卸载项目”。
- 在解决方案资源管理器中,右键单击要为其生成序列化程序集的项目,然后单击“编辑 .csproj”。
在 .csproj 文件中,紧跟在该<TargetFrameworkVersion>v?.?</TargetFrameworkVersion>
元素之后,添加以下元素:
<SGenUseProxyTypes>false</SGenUseProxyTypes>
<SGenPlatformTarget>$(Platform)</SGenPlatformTarget>
在 .csproj 文件中,在每个平台配置中
例如<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
添加以下行:
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
保存并关闭 .csproj 文件。
- 在解决方案资源管理器中,右键单击刚刚编辑的项目,然后单击重新加载项目。
此过程在您的输出文件夹中生成一个名为 .xmlSerializers.dll 的附加程序集。您将需要使用您的解决方案部署此程序集。
解释
默认情况下,SGen 仅适用于为“任何 CPU”生成的代理类型。如果您没有在项目文件中设置相应的变量,就会发生这种情况。
需要 SGenPlatformTarget 才能匹配您的 PlatformTarget。我倾向于认为这是项目模板中的一个错误。为什么 sgen 目标平台与您的项目不同?如果是这样,您将获得运行时异常
0x80131040: 定位程序集的清单定义与程序集引用不匹配
您可以通过分析您的项目文件找到 msbuild 任务定义:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
其中 MSBuildToolsPath 取决于您的<TargetFrameworkVersion>
http://msdn.microsoft.com/en-us/library/bb397428.aspx
查看 TargetFrameworkVersion 4.0 的 SGen 任务定义
Windows安装路径\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.targets
要查看 $(SGenPlatformTarget) 等未记录的变量,您可以在项目文件中自由设置
<Target
Name="GenerateSerializationAssemblies"
Condition="'$(_SGenGenerateSerializationAssembliesConfig)' == 'On' or ('@(WebReferenceUrl)'!='' and '$(_SGenGenerateSerializationAssembliesConfig)' == 'Auto')"
DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource"
Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"
Outputs="$(IntermediateOutputPath)$(_SGenDllName)">
<SGen
BuildAssemblyName="$(TargetFileName)"
BuildAssemblyPath="$(IntermediateOutputPath)"
References="@(ReferencePath)"
ShouldGenerateSerializer="$(SGenShouldGenerateSerializer)"
UseProxyTypes="$(SGenUseProxyTypes)"
KeyContainer="$(KeyContainerName)"
KeyFile="$(KeyOriginatorFile)"
DelaySign="$(DelaySign)"
ToolPath="$(SGenToolPath)"
SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)"
EnvironmentVariables="$(SGenEnvironment)"
SerializationAssembly="$(IntermediateOutputPath)$(_SGenDllName)"
Platform="$(SGenPlatformTarget)"
Types="$(SGenSerializationTypes)">
<Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly"/>
</SGen>
</Target>