创建新的 SGen 任务定义会像大材小用一样。只需设置所需的变量即可使任务按预期工作。不管怎样,Microsoft 文档缺少一些重要信息。
预生成序列化程序集的步骤
(引用自 http://msdn.microsoft.com/zh-cn/library/ff798449.aspx)
- 在 Visual Studio 2010 中,Solution Explorer 中右键单击要生成序列化程序集的项目,然后单击“卸载项目”。
- 在 Solution Explorer 中,右键单击要生成序列化程序集的项目,然后单击“编辑 .csproj”。
在 .csproj 文件中,在 <TargetFrameworkVersion>v?.?</TargetFrameworkVersion>
元素之后立即添加以下元素:
<SGenUseProxyTypes>false</SGenUseProxyTypes>
<SGenPlatformTarget>$(Platform)</SGenPlatformTarget>
在 .csproj 文件中的每个平台配置中(例如 <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
),添加以下行:
<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>
保存并关闭 .csproj 文件。
- 在 Solution Explorer 中,右键单击刚编辑的项目,然后单击“重新加载项目”。
此过程会在输出文件夹中生成一个名为 .xmlSerializers.dll 的附加程序集。您需要将该程序集与解决方案一起部署。
解释
默认情况下,SGen 仅为代理类型生成“Any CPU”的序列化程序集。如果您未在项目文件中设置相应的变量,则会发生这种情况。
SGenPlatformTarget 必须与您的 PlatformTarget 匹配。我倾向于认为这是项目模板中的错误。为什么 sgen 目标平台应与您的项目不同?如果不同,您将收到运行时异常:
0x80131040:找到的程序集清单定义与程序集引用不匹配
您可以通过分析项目文件来找到 msbuild 任务定义:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
根据你的<TargetFrameworkVersion>
,http://msdn.microsoft.com/en-us/library/bb397428.aspx,MSBuildToolsPath会有所不同。
查看位于
Windows安装路径\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.targets
中TargetFrameworkVersion 4.0的SGen任务定义,以查看像$(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>