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.targets
该AssemblySearchPaths
属性的评论是:
<!--
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
常量?