fli*_*ubt 12 msbuild sgen visual-studio-2010 .net-reflector xmlserializer
我刚刚将包含WinForms,通用库和Web应用程序的VS 2008解决方案升级到VS 2010,但所有项目仍然针对.NET 3.5 SP 1.我使用此技术为我的常用库生成XmlSerializers.WinForms应用程序运行正常.当我的Web应用程序尝试使用引用相同XmlSerializers的这些库运行时,它会抛出以下内容:
'/ WebSubscribers'应用程序中的服务器错误.无法加载文件或程序集"Ceoimage.Basecamp.XmlSerializers"或其依赖项之一.此程序集由比当前加载的运行时更新的运行时构建,无法加载.描述:执行当前Web请求期间发生未处理的异常.请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息.
异常详细信息:System.BadImageFormatException:无法加载文件或程序集"Ceoimage.Basecamp.XmlSerializers"或其依赖项之一.此程序集由比当前加载的运行时更新的运行时构建,无法加载.
我已经使用.NET Reflector查看了XmlSerializer的引用,并看到它引用了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>
Run Code Online (Sandbox Code Playgroud)
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,所有类型的结果)
运行你的构建
搜索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"结果,因为msbuild尝试从指定的密钥加载值.
应该清楚从这里添加/修改哪些键.
注册表值错误有几个可能的原因.在我的情况下,Microsoft SDK v7.1安装的问题意味着注册表项名称不正确,这已被识别为错误:
我发现我可以显式指定 SGEN 任务的工具路径来使用 3.5 版本,如下所示:
<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">
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2864 次 |
最近记录: |