我刚刚将包含 WinForms、通用库和 Web 应用程序的 VS 2008 解决方案升级到 VS 2010,但所有项目仍然以 .NET 3.5 SP 1 为目标。我用 这项技术 为我的通用库生成 XmlSerializers。WinForms 应用程序运行良好。当我的 Web 应用程序尝试使用引用相同 XmlSerializers 的这些库运行时,它会抛出以下内容:

服务器错误中的“/weblebscribers”应用程序中的错误。无法加载文件或汇编“ ceoimage.basecamp.xmlserializers”或其依赖项之一。该组件是由比当前加载的运行时更新的运行时构建的,无法加载。描述:在执行当前Web请求期间发生了一个未经治疗的例外。请查看堆栈跟踪,以获取有关该错误以及代码中何处的更多信息。

异常详细信息:系统.BadImageFormatException:无法加载文件或程序集“Ceoimage.Basecamp.XmlSerializers”或其依赖项之一。该程序集是由比当前加载的运行时更新的运行时构建的,无法加载。

我查看了 XmlSerializer 的参考文献 .NET反射器 并看到它引用了 2.0 和 4.0 版本 mscorlib 以及 3.5 和 4.0 版本 System.Data.Linq. 。奇怪的是,它只使用4.0版本 System.Xml. 。这可能就是我的问题所在。

如何使用这些 XmlSerializers 运行 Web 应用程序?当我简单地删除这些 XmlSerializers 时,Web 应用程序运行良好。这是一个选项,但如何强制 MSBUILD 为特定版本的 CLR 创建序列化程序?

以下是我添加到项目文件中的 MSBuild 任务,该任务强制创建 XmlSerializers:

<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
 <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)">
  <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
 </SGen>
</Target>
有帮助吗?

解决方案 3

我发现我可以明确指定使用3.5版本的SGEN任务的工具路径,例如:

<SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin">

其他提示

MSBuild 4 将(应该...)使用 3.5 工具来构建 3.5 项目。但是,它似乎无法确定 3.5 工具在哪里并且正在使用 4.0 工具。结果是,它正确构建了 3.5 项目(使用 CLR 2.0.50727 程序集),但 4.0 sgen.exe 工具正在生成 Ceoimage.Basecamp.XmlSerializers.dll 作为 CLR 4.0.30319 程序集。

MSBuild 使用注册表来获取 v3.5 工具的路径。如果无法识别 3.5 工具的路径,则需要 v3.5 SDK 工具的 MSBuild 任务将回退到 v4.0 路径 - 查看用于在 C:\Windows\Microsoft 中设置 TargetFrameworkSDKToolsDirectory 属性的逻辑。 NET\Framework\v4.0.30319\Microsoft.NETFramework.props 如果您真的感兴趣的话。

您可以按如下方式诊断并修复可能的注册表问题:

安装 Process Monitor 并设置一个过滤器来监视 msbuild 的注册表访问(事件类:注册表,进程名称:msbuild.exe,所有类型的结果)

运行你的构建

在进程监视器中搜索与“MSBuild oolsVersions\4.0\SDK35ToolsPath”匹配的 RegQueryValue 访问。请注意,这可能位于“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft”或“HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft”下

如果您查看注册表中的此键,您会发现它是另一个注册表值的别名,例如“ $(注册表:hkey_local_machine software Microsoft Microsoft Microsoft SDKS Windows Windows v7.1 winsdk-netfx35tools-x86@installationFolder)”此后不久,您可能会看到MSBuild的结果,因为MSBUILD的结果是“ MSBUILD”的结果指定的密钥的值。

从这里应该清楚您需要添加/修改哪些键。

注册表值错误的可能原因有多种。就我而言,Microsoft SDK v7.1 安装的问题意味着注册表项的命名不正确,这已在此处被识别为错误:

http://connect.microsoft.com/VisualStudio/feedback/details/594338/tfs-2010-build-agent-and-windows-7-1-sdk-targeting-net-3-5-generates-wrong-embedded-资源

您是否依赖于4.0的特定内容?

如果您调用MSBUILD 4.0,则将获得4.0工具。如果您调用MSBUILD 3.5,您将获得3.5个工具(这是您想要的,因为您在2.0 CLR中显然托管)。

另一个选项是将4.0 CLR放在您的Web服务器上。如果不打开,您不应该在流中有4.0个目标的东西。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top