18

我刚刚将一个项目从 VS2008 升级到 VS2010,但我仍然针对 3.5 框架。

在我的项目文件中,我有一个自定义任务来运行 SGEN 以生成我的 XmlSerializers.dll。然而,正在运行的 sgen 版本以 4.0 框架为目标。结果,当我运行我的应用程序时,我收到错误消息:

“无法加载文件或程序集'XXXX.XXXX.XmlSerializers'或其依赖项之一。此程序集由比当前加载的运行时更新的运行时构建,无法加载。”

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="$(SGenToolPath)">
      <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
    </SGen>
  </Target>

ToolPath="$(SGenToolPath)"。如何让它运行以 3.5 为目标的版本?

这里有一个类似的问题,但对我没有多大帮助。

4

5 回答 5

18

我通过手动将 ToolPath 配置为指向 sgen.exe 的旧(版本 2.0.50727.3038)版本解决了这个问题

在我的机器上,它位于:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin

我将 ToolPath 属性更改为:

ToolPath="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin"

这解决了这个问题。

默认情况下,它似乎在以下位置运行新的 4.0 框架版本:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools

希望这对其他人有帮助。

于 2010-05-02T10:26:04.453 回答
17

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 的注册表访问(事件类:Registry,进程名称:msbuild.exe,所有类型的结果)。

运行你的构建。

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

如果您查看注册表中的这个键,您会看到它为另一个注册表值设置别名,例如“$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx35Tools-x86@ InstallationFolder)" 之后不久,您可能会看到“未找到名称”结果。如果您查看预期的密钥应该在哪里,您会发现它们与请求的密钥不匹配(缺少连字符并且可能没有以“-86”结尾的密钥)。

应该清楚你需要纠正什么。我选择导出不正确的密钥,编辑 .reg 文件并运行它以创建正确的密钥。

无效注册表项的一个原因可能是 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-资源

于 2011-04-18T10:43:52.310 回答
7

问题$(SGenToolPath)不是由 MSBuild 设置的。如果您使用$(TargetFrameworkSDKToolsDirectory),那么它将尝试基于$(TargetFrameworkVersion).

使用标签进行 printf() 样式调试很有帮助。暂时添加以下内容。

<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
  <Message Text="SGenPath: $(SGenPath)" Importance="high"/>
  <Message Text="TargetFrameworkVersion: $(TargetFrameworkVersion)" Importance="high"/>
  <Message Text="TargetFrameworkSDKToolsDirectory : $(TargetFrameworkSDKToolsDirectory )" Importance="high"/>
于 2012-07-12T14:43:35.207 回答
7

我发现这是最简单的方法,它适用于:<GenerateSerializationAssemblies>On</GenerateSerializationAssemblies>

<SGenToolPath>C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin</SGenToolPath>
于 2010-12-14T21:19:52.950 回答
5

@Craig - 您是否在构建机器上手动安装了 7.0A 框架。如果是这样,您的问题可能是您的注册表设置,而不是 msbuild。查看 LocalMachine -> Software -> Microsoft -> MSBuild -> ToolsVersions -> 4.0 -> SDK35ToolsPath 并确保此处引用的 reg 密钥有效。(提示:确保 -x86 只有在 -x86 键存在时才存在。)

于 2010-06-30T19:14:18.413 回答