【发布时间】:2012-10-28 14:48:17
【问题描述】:
Test.csproj 引用 System.XML 并指定 TargetFrameworkVersion v4.0。
System.Xml.XmlReaderSettings 获得了 DtdProcessing 属性,同时已弃用 ProhibitDtd。
要求是从一个项目构建,同时支持两个程序集。
使用 MSBuild 3.5 (c:\Windows\Microsoft.NET\Framework\v3.5\MSBuild) 构建最终会引用 C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll (运行时版本 v2.0.50727,版本 2.0.0.0)
使用 MSBuild 4.0 (c:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild) 构建最终会引用 C:\Program Files\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\System。 Xml.dll(运行时版本 v4.0.30319,版本 4.0.0.0)。
我尝试的解决方法是根据 TargetFrameworkVersion 在 .csproj 文件中定义一个常量。 但是,TargetFrameworkVersion 并不能指示将链接哪个程序集。
所以,这不起作用:
<PropertyGroup Condition=" '$(TargetFrameworkVersion)' != 'v2.0' And '$(TargetFrameworkVersion)' != 'v3.5' And '$(TargetFrameworkVersion)' != '' ">
<DefineConstants Condition=" '$(DefineConstants)' != '' ">$(DefineConstants);</DefineConstants>
<DefineConstants>$(DefineConstants)XMLDTDPROCESSING</DefineConstants>
</PropertyGroup>
使用此 CSharp 代码:
namespace TestVSMSBuild
{
class Program
{
static void Main(string[] args)
{
System.Xml.XmlReaderSettings readerSettings = new System.Xml.XmlReaderSettings();
#if XMLDTDPROCESSING
readerSettings.DtdProcessing = System.Xml.DtdProcessing.Ignore;
#else // !XMLDTDPROCESSING
readerSettings.ProhibitDtd = false;
#endif // XMLDTDPROCESSING
System.Console.WriteLine("Reader: '{0}'", readerSettings);
}
}
阅读C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.Common.targetsAssemblySearchPaths 属性的评论是:
<!--
The SearchPaths property is set to find assemblies in the following order:
(1) Files from current project - indicated by {CandidateAssemblyFiles}
(2) $(ReferencePath) - the reference path property, which comes from the .USER file.
(3) The hintpath from the referenced item itself, indicated by {HintPathFromItem}.
(4) The directory of MSBuild's "target" runtime from GetFrameworkPath.
The "target" runtime folder is the folder of the runtime that MSBuild is a part of.
(5) Registered assembly folders, indicated by {Registry:*,*,*}
(6) Legacy registered assembly folders, indicated by {AssemblyFolders}
(7) Look in the application's output folder (like bin\debug)
(8) Resolve to the GAC.
(9) Treat the reference's Include as if it were a real file name.
-->
<AssemblySearchPaths Condition=" '$(AssemblySearchPaths)' == '' ">
{CandidateAssemblyFiles};
$(ReferencePath);
{HintPathFromItem};
{TargetFrameworkDirectory};
{Registry:$(FrameworkRegistryBase),$(TargetFrameworkVersion),$(AssemblyFoldersSuffix)$(AssemblyFoldersExConditions)};
{AssemblyFolders};
{GAC};
{RawFileName};
$(OutDir)
</AssemblySearchPaths>
我的猜测是这与GetFrameworkPaths 有关,它被定义为:
<!--
============================================================
GetFrameworkPaths
Get the paths for the .NET Framework installation directory, and the .NET Framework
SDK installation directory.
These paths are not used directly by this .targets file but are available for pre and
post build steps.
============================================================
-->
<PropertyGroup>
<Framework35Dir>@(_TargetFramework35DirectoryItem)</Framework35Dir>
<Framework30Dir>@(_TargetFramework30DirectoryItem)</Framework30Dir>
<Framework20Dir>@(_TargetFramework20DirectoryItem)</Framework20Dir>
<FrameworkDir>@(_TargetFramework20DirectoryItem)</FrameworkDir>
<FrameworkSDKDir>@(_TargetFrameworkSDKDirectoryItem)</FrameworkSDKDir>
<GetFrameworkPathsDependsOn></GetFrameworkPathsDependsOn>
</PropertyGroup>
<Target
Name="GetFrameworkPaths"
DependsOnTargets="$(GetFrameworkPathsDependsOn)">
<!-- Get the paths to all of the target .NET framework directories. -->
<GetFrameworkPath>
<Output Condition=" '$(TargetFrameworkVersion)' == 'v3.5' " TaskParameter="FrameworkVersion35Path" ItemName="_CombinedTargetFrameworkDirectoriesItem" />
<Output Condition=" '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5' " TaskParameter="FrameworkVersion30Path" ItemName="_CombinedTargetFrameworkDirectoriesItem" />
<Output Condition=" '$(TargetFrameworkVersion)' == 'v2.0' or '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'" TaskParameter="FrameworkVersion20Path" ItemName="_CombinedTargetFrameworkDirectoriesItem" />
<Output TaskParameter="FrameworkVersion35Path" ItemName="_TargetFramework35DirectoryItem" />
<Output TaskParameter="FrameworkVersion30Path" ItemName="_TargetFramework30DirectoryItem" />
<Output TaskParameter="FrameworkVersion20Path" ItemName="_TargetFramework20DirectoryItem" />
</GetFrameworkPath>
<PropertyGroup>
<TargetFrameworkDirectory>@(_CombinedTargetFrameworkDirectoriesItem)</TargetFrameworkDirectory>
</PropertyGroup>
<!-- Get the path to the target .NET framework SDK directory. -->
<GetFrameworkSdkPath>
<Output TaskParameter="FrameworkSdkVersion35Path" PropertyName="TargetFrameworkSDKDirectory"/>
<Output TaskParameter="FrameworkSdkVersion35Path" ItemName="_TargetFrameworkSDKDirectoryItem"/>
</GetFrameworkSdkPath>
</Target>
那么,有没有更简单的方法可以根据正在使用的System.XML 程序集来更改 CSharp 代码?
如果这种方法是正确的,我应该使用什么条件定义我的XMLDTDPROCESSING 常量?
【问题讨论】:
标签: c# msbuild msbuild-4.0