生成一个Xml序列化程序集作为我的构build的一部分

这段代码产生一个FileNotFoundException,但最终运行没有问题:

void ReadXml() { XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); //... } 

这是一个例外:


在mscorlib.dll中发生第一次机会exceptiontypes“System.IO.FileNotFoundException”

其他信息:无法加载文件或程序集“MyAssembly.XmlSerializers,Version = 1.4.3190.15950,Culture = neutral,PublicKeyToken = null”或其依赖项之一。 该系统找不到指定的文件。


看来如果没有find框架,框架会自动生成序列化程序集。 我可以使用sgen.exe手动生成它,从而减轻exception。

如何让Visual Studio自动生成XML序列化程序集?


更新:生成序列化程序集:On设置不会显示任何内容。

这是我通过修改.CSPROJ文件中的MSBUILD脚本来实现的。

首先,将.CSPROJ文件作为文件而不是项目打开。 滚动到文件底部,直到您find此注释掉的代码,就在Project标签closures之前:

 <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> </Target> <Target Name="AfterBuild"> </Target> --> 

现在我们只需插入我们自己的AfterBuild目标来删除我们自己的任何现有的XmlSerializer和SGen,如下所示:

 <Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)"> <!-- Delete the file because I can't figure out how to force the SGen task. --> <Delete Files="$(TargetDir)$(TargetName).XmlSerializers.dll" ContinueOnError="true" /> <SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(TargetFrameworkSDKToolsDirectory)" Platform="$(Platform)"> <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" /> </SGen> </Target> 

这对我行得通。

正如Martin在他的回答中解释的那样,通过项目属性来启用序列化程序集的生成是不够的,因为SGen任务是将/proxytypes开关添加到sgen.exe命令行。

Microsoft有一个logging的MSBuild属性 ,允许您禁用/proxytypes开关,并导致SGen任务生成序列化程序集,即使程序集中没有代理types。

SGenUseProxyTypes

一个布尔值,指示代理types是否应由SGen.exe生成。 SGen目标使用此属性来设置UseProxyTypes标志。 这个属性默认为true,并且没有UI来改变它。 要为非webservicetypes生成序列化程序集,请将此属性添加到项目文件,并在导入Microsoft.Common.Targets或C#/ VB.targets之前将其设置为false

正如文档build议您必须手动修改您的项目文件,但您可以将SGenUseProxyTypes属性添加到您的configuration以启用生成。 您的项目文件configuration将最终看起来像这样:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> <!-- Snip... --> <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies> <SGenUseProxyTypes>false</SGenUseProxyTypes> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> <!-- Snip... --> <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies> <SGenUseProxyTypes>false</SGenUseProxyTypes> </PropertyGroup> 

这个问题的其他答案已经提到了Project Properties-> Build-> Generate Serialization Assemblies设置,但是默认情况下,如果项目中有“ XML Web服务代理types ”,则只会生成程序集。

了解Visual Studio确切行为的最佳方法是检查C:\ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 ** Microsoft.Common.targets **文件中的GenerateSerializationAssemblies目标。

您可以从“Visual Studio 输出”窗口中检查此构build任务的结果,然后从“ 显示输出来自 :”下拉框中select“ 构build ”。 你应该看到的东西沿线

C:\ Program Files \ Microsoft Visual Studio 8 \ SDK \ v2.0 \ bin \ sgen.exe /assembly:D:\Temp\LibraryA\obj\Debug\LibraryA.dll / proxytypes / reference:.. / compiler:/ delayedign-LibraryA – > D:\ Temp \ LibraryA \ bin \ Debug \ LibraryA.dll

这里的关键是/ proxytypes开关。 您可以阅读有关XML序列化程序生成器工具(Sgen.exe)的各种开关

如果您熟悉MSBuild,则可以自定义GenerateSerializationAssemblies目标,以便SGen任务的属性为UseProxyTypes =“false”而不是true,但是您需要承担所有定制Visual Studio / MSBuild系统的相关责任。 或者,您可以扩展您的构build过程,以便在不使用/ proxytypes开关的情况下手动调用SGen。

如果你阅读SGen的文档,他们很清楚,微软想限制使用这个工具。 鉴于这个话题有很多噪音,很明显,微软在loggingVisual Studio体验方面做得不是很好。 这个问题甚至有一个连接反馈项目,反应不是很好。

创造一个新的sgen任务定义在车轮上打破飞行。 只需设置所需的variables,使任务按预期工作。 无论如何,微软文档缺乏一些重要的信息。

预先生成序列化程序集的步骤

(部分来自http://msdn.microsoft.com/en-us/library/ff798449.aspx

  1. 在Visual Studio 2010的解决scheme资源pipe理器中,右键单击要为其生成序列化程序集的项目,然后单击卸载项目。
  2. 在解决scheme资源pipe理器中,右键单击要为其生成序列化程序集的项目,然后单击编辑.csproj。
  3. 在.csproj文件中紧接在<TargetFrameworkVersion>v?.?</TargetFrameworkVersion>元素之后,添加以下元素:

    <SGenUseProxyTypes>false</SGenUseProxyTypes> <SGenPlatformTarget>$(Platform)</SGenPlatformTarget>

  4. 在.csproj文件中,在每个平台configuration中

    例如<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">

    添加以下行:

    <GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>

  5. 保存并closures.csproj文件。

  6. 在解决scheme资源pipe理器中,右键单击刚刚编辑的项目,然后单击重新加载项目。

此过程会在输出文件夹中生成一个名为.xmlSerializers.dll的附加程序集。 您将需要使用您的解决scheme部署此程序集。


说明

SGen默认只为代理types生成“任何CPU”。 如果不在项目文件中设置相应的variables,就会发生这种情况。

SGenPlatformTarget必须与您的PlatformTarget匹配。 我倾向于认为这是项目模板中的一个错误。 为什么sgen目标平台与您的项目有所不同? 如果这样做,你会得到一个运行时exception

0x80131040:find的程序集清单定义与程序集引用不匹配

您可以通过分析您的项目文件来findmsbuild任务定义:

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

MSBuildToolsPath依赖于您的<TargetFrameworkVersion> http://msdn.microsoft.com/en-us/library/bb397428.aspx

从里面查看TargetFrameworkVersion 4.0的SGen任务定义

Windows安装path\ Microsoft.NET \ Framework \ v4.0.30319 \ Microsoft.CSharp.targets

看到像$(SGenPlatformTarget)这样的未公开的variables,您可以在您的项目文件中自由设置

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

万一有人遇到这个问题突然之前,一切工作正常之前:对我来说,它必须做的选项菜单(选项 – >debugging)(这是安装.NET Reflector后自动closures)。

编辑:当然,也就是说,这个exception是以前发生的,但是当“只启用我的代码”closures时,debugging助手(如果启用)将在此时停止。

我晚了一点,但是我发现以前的答案很难合作。 具体来说,Visual Studio会崩溃,每当我试图查看我的项目的属性。 我认为这是由于它不再理解如何读取csproj文件。 那说…

将以下内容添加到生成后事件命令行中:

 "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\sgen.exe" "$(TargetPath)" /force 

这将直接利用sgen.exe来重buildXml序列化程序集,每次为Debug或Release创build项目时。

查看解决scheme的属性。 在底部的构build选项卡上有一个名为“生成序列化程序集”的下拉列表,

与大脑备份提供的解决scheme略有不同的解决scheme可能是直接指定平台目标,您必须像这样使用它:

 <!-- Check the platform target value and if present use that for a correct *.XmlSerializer.dll platform setup (default is MSIL)--> <PropertyGroup Condition=" '$(PlatformTarget)'=='' "> <SGenPlatform>$(Platform)</SGenPlatform> </PropertyGroup> <PropertyGroup Condition=" '$(PlatformTarget)'!='' "> <SGenPlatform>$(PlatformTarget)</SGenPlatform> </PropertyGroup> <!-- Delete the file because I can't figure out how to force the SGen task. --> <Delete Files="$(TargetDir)$(TargetName).XmlSerializers.dll" ContinueOnError="true" /> <SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)" SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" EnvironmentVariables="$(SGenEnvironment)" Platform="$(SGenPlatform)"> <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" /> </SGen>