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

时间:2020-03-06 14:43:47  来源:igfitidea点击:

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

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

这是例外:

mscorlib.dll中发生类型为'System.IO.FileNotFoundException'的第一次机会异常

添加信息:无法加载文件或者程序集'MyAssembly.XmlSerializers,版本= 1.4.3190.15950,区域性=中性,PublicKeyToken =空'或者其依赖项之一。该系统找不到指定的文件。

似乎该框架会自动生成序列化程序集(如果未找到)。我可以使用sgen.exe手动生成它,从而减轻了异常。

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

更新:生成序列化程序集:打开设置似乎没有执行任何操作。

解决方案

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

这是通过修改.CSPROJ文件中的MSBUILD脚本来设法做到的:

首先,将.CSPROJ文件作为文件而不是作为项目打开。滚动到文件底部,直到在Project标记关闭之前找到以下注释掉的代码:

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

这对我行得通。

该问题的其他答案已经提到了"项目属性"->"构建"->"生成序列化程序集"设置,但是默认情况下,仅当项目中存在" XML Web服务代理类型"时,才生成程序集。

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

我们可以从Visual Studio"输出"窗口中检查此生成任务的结果,然后从"显示输出自:"下拉框中选择"生成"。我们应该看到类似的内容

C:\ Program Files \ Microsoft Visual Studio 8 \ SDK \ v2.0 \ bin \ sgen.exe /assembly:D:\Temp\LibraryA\obj\Debug\LibraryA.dll / proxytypes /reference:../compiler:/延迟签收
库A-> D:\ Temp \ LibraryA \ bin \ Debug \ LibraryA.dll

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

如果我们熟悉MSBuild,则可以自定义GenerateSerializationAssemblies目标,以便SGen任务的属性为UseProxyTypes =" false"而不是true,但是
那么我们需要承担自定义Visual Studio / MSBuild系统的所有相关责任。另外,我们可以扩展构建过程以手动调用SGen,而无需使用/ proxytypes开关。

如果我们阅读了SGen的文档,则他们很清楚Microsoft希望限制此功能的使用。考虑到有关此主题的大量讨论,很明显,Microsoft在记录Visual Studio体验方面做得不好。甚至有一个针对此问题的"连接反馈"项目,响应不佳。

万一之前一切正常,在其他人突然遇到此问题的情况下:对我而言,这与在选项菜单(选项->调试)中未选中"启用仅我的代码(仅受管理)"复选框有关(安装.NET Reflector后自动关闭)。

编辑:
这就是说,当然,该异常是之前发生的,但是如果关闭"仅启用我的代码",则调试助手(如果启用)将在抛出时停止。