如何在Msbuild中设置SGEN工具路径以针对3.5框架
我刚刚将一个项目从 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 的版本?
这里有一个类似的问题,但它没有对我有很大帮助。
I've just upgraded a project from VS2008 to VS2010 but I'm still targeting the 3.5 framework.
In my project file I have a custom task to run SGEN to generate my XmlSerializers.dll. However the version of sgen being run targets the 4.0 framework. As a result, when I run my application I get the error message:
"Could not load file or assembly 'XXXX.XXXX.XmlSerializers' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded."
The Sgen task looks like this:
<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>
There's the ToolPath="$(SGenToolPath)". How do I make it run the version that targets 3.5?
There's a similar question here but it doesn't help me much.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我通过手动配置 ToolPath 以指向旧版本(版本 2.0.50727.3038)的 sgen.exe 解决了这个问题
在我的计算机上,它位于:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A \Bin
我将 ToolPath 属性更改为:
这解决了问题。
默认情况下,它似乎在以下位置运行新的 4.0 框架版本:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools
希望这对其他人有帮助。
I have solved this by manually configuring the ToolPath to point to the old (version 2.0.50727.3038) version of sgen.exe
On my machine, this is in: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin
I changed the ToolPath attribute to be:
and this solved the problem.
It seems, by default, it's running the new 4.0 framework version in: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools
Hope this helps somebody else.
MSBuild 使用注册表来获取 v3.5 工具的路径。如果无法识别 3.5 工具的路径,则需要 v3.5 SDK 工具的 MSBuild 任务将回退到 v4.0 路径 - 查看用于在 C:\Windows\Microsoft 中设置 TargetFrameworkSDKToolsDirectory 属性的逻辑。 NET\Framework\v4.0.30319\Microsoft.NETFramework.props 如果您真的感兴趣的话。
您可以按如下方式诊断并修复此问题:
安装进程监视器并设置建立一个过滤器来监视 msbuild 的注册表访问(事件类:注册表,进程名称: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@安装文件夹)”
此后不久,您可能会看到“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-生成错误的嵌入式资源
MSBuild uses the registry to get the path to the v3.5 tools. The MSBuild tasks that require v3.5 SDK tools will fall back to the v4.0 path if the path to the 3.5 tools can't be identified - look at the logic used to set the TargetFrameworkSDKToolsDirectory property in C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.NETFramework.props if you're really interested.
You can diagnose and fix this problem as follows:
Install Process Monitor and set up a filter to monitor registry access by msbuild (Event class: Registry, Process Name: msbuild.exe, all types of result).
Run your build.
Search Process Monitor for a RegQueryValue access matching "MSBuild\ToolsVersions\4.0\SDK35ToolsPath". Note that this could be be under either "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft" or "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft".
If you have a look at this key in the registry, you'll see that it aliases another registry value, e.g. "$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx35Tools-x86@InstallationFolder)"
Shortly after this, you'll probably see a "NAME NOT FOUND" result. If you look at where the expected key should be, you'll see that they don't match the key being requested (missing hyphens and possibly no key ending with "-86").
It should be clear what you need to correct. I chose to export the incorrect keys, edit the .reg file and run it to create the correct keys.
One cause of invalid registry entries could be a bug with the Microsoft SDK v7.1 installation:
http://connect.microsoft.com/VisualStudio/feedback/details/594338/tfs-2010-build-agent-and-windows-7-1-sdk-targeting-net-3-5-generates-wrong-embedded-resources
我发现这是最简单的方法,它适用于:On
I found this to be the easiest way and it works with: <GenerateSerializationAssemblies>On</ GenerateSerializationAssemblies>
问题是 MSBuild 未设置
$(SGenToolPath)
。如果您使用$(TargetFrameworkSDKToolsDirectory)
,那么它将尝试根据$(TargetFrameworkVersion)
解析路径。使用标签进行 printf() 风格的调试很有帮助。暂时添加以下内容。
The problem is
$(SGenToolPath)
isn't set by MSBuild. If you use$(TargetFrameworkSDKToolsDirectory)
then it will attempt to resolve the path based on$(TargetFrameworkVersion)
.Its helpful to make use of tags for printf() style debugging. Add the following temporally.
@Craig - 您是否在构建计算机上手动安装了 7.0A 框架。如果是这样,您的问题可能是您的注册表设置而不是 msbuild。看看 LocalMachine ->软件->微软-> MSBuild->工具版本 -> 4.0-> SDK35ToolsPath 并确保引用的 reg 密钥有效。 (提示:仅当 -x86 键存在时,确保 -x86 存在。)
@Craig - Did you manually install the 7.0A framework on your build machine. If so, your problem may be your registry settings and not msbuild. Take a look at LocalMachine -> Software -> Microsoft -> MSBuild -> ToolsVersions -> 4.0 -> SDK35ToolsPath and make sure the reg key that is referenced there is valid. (Hint: Make sure the -x86 is there only if the -x86 key exists.)