如何在Msbuild中将SGEN工具路径设置为目标3.5框架

Cra*_*rer 18 sgen visual-studio-2010

我刚刚将一个项目从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>
Run Code Online (Sandbox Code Playgroud)

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

这里有一个类似的问题,但它对我没什么帮助.

Cra*_*rer 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"
Run Code Online (Sandbox Code Playgroud)

这解决了这个问题.

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

希望这有助于其他人.

  • 你在哪里设置ToolPath? (3认同)
  • 我将它设置在项目文件如下:<GenerateSerializationAssemblies>自动</ GenerateSerializationAssemblies> <SGenToolPath> C:\ Program Files文件\微软的SDK \的Windows\V7.0\BIN </ SGenToolPath> (2认同)
  • 如果找不到3.5工具,MSBuild将在"NETFX 4.0工具"中使用4.0工具进行3.5项目.我的回答可能有助于解决问题的根本原因,避免在单个项目文件中使用变通方法. (2认同)

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

运行你的构建.

搜索Process Monitor以获得与"MSBuild\ToolsVersions\4.0\SDK35ToolsPath"匹配的RegQueryValue访问.请注意,这可以在"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft"或"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft"下.

如果你在注册表中查看这个键,你会看到它别名另一个注册表值,例如"$(注册表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx35Tools-x86 @ InstallationFolder)"在此之后不久,您可能会看到"NAME NOT FOUND"结果.如果您查看预期密钥应该在哪里,您将看到它们与请求的密钥不匹配(缺少连字符,可能没有以"-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-资源


Mik*_*ard 7

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

<SGenToolPath>C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin</SGenToolPath>
Run Code Online (Sandbox Code Playgroud)


Jus*_*ing 6

该问题$(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"/>
Run Code Online (Sandbox Code Playgroud)


pat*_*onc 5

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