Msbuild 为.NET4和.NET4.5构建-引用的NuGet包呢?

Msbuild 为.NET4和.NET4.5构建-引用的NuGet包呢?,msbuild,nuget,Msbuild,Nuget,我有一个脚本,可以构建一个项目,输出.NET4.0程序集 该项目包括NuGet的NLog。因此,项目文件中的引用如下所示: <Reference Include="NLog"> <HintPath>..\packages\NLog.2.0.1.2\lib\NLog\net40\NLog.dll</HintPath> </Reference> <packages> <package id="NLog" version="2

我有一个脚本,可以构建一个项目,输出.NET4.0程序集

该项目包括NuGet的NLog。因此,项目文件中的引用如下所示:

<Reference Include="NLog">
  <HintPath>..\packages\NLog.2.0.1.2\lib\NLog\net40\NLog.dll</HintPath>
</Reference>
<packages>
  <package id="NLog" version="2.0.1.2" targetFramework="net40" />
</packages>

..\packages\NLog.2.0.1.2\lib\NLog\net40\NLog.dll
我的packages.config如下所示:

<Reference Include="NLog">
  <HintPath>..\packages\NLog.2.0.1.2\lib\NLog\net40\NLog.dll</HintPath>
</Reference>
<packages>
  <package id="NLog" version="2.0.1.2" targetFramework="net40" />
</packages>

这个项目将在NuGet上发布,现在我想更新构建脚本,以便它也构建.NET 4.5程序集

现在,我知道我可以将
/p:TargetFrameworkVersion=“4.5”
传递给
msbuild
,并将其作为.NET 4.5的目标-但这仍将基于.NET 4.0 NLog程序集进行构建


如何使用针对目标框架的正确版本的NuGet dependencies构建它?

不久前在这里有完全相同的要求,但没有找到“纯”NuGet解决方案。我怀疑有。唯一的选择似乎是维护不同的项目文件(或其中的一部分)——对于大量的代码库来说,这绝对是不可能的

我所做的只是在所有项目中以4.5为目标,并有一个相当简单的msbuild脚本,用于创建项目及其所有NuGet配置的副本,以针对其他版本的.Net。基本上,它只是枚举所有.csproj文件,从
net45
->
net40
字符串进行查找/替换,并以不同的名称保存它们。程序包配置/目标/解决方案文件的Idem

以下是几乎完整的MSBuild目标:

<Target Name="MakeNet40Projects">
  <ItemGroup>
    <SourceProjs Include="$(MyProjectDir)*\*\*.csproj" Exclude="$(MyProjectDir)\*\*\*.Net40.csproj"/>
      ...
    <SourceConfigs Include="$(MyProjectDir)*\*\packages.config"/>
      ...
    <DestProjs Include="%(SourceProjs.RootDir)%(SourceProjs.Directory)%(SourceProjs.FileName).Net40.csproj"/>
    <DestConfigs Include="%(SourceConfigs.RootDir)%(SourceConfigs.Directory)%(SourceConfigs.FileName).Net40.config"/>
  </ItemGroup>
  <PropertyGroup>
    <OldPackages>packages.config</OldPackages>
    <NewPackages>packages.Net40.config</NewPackages>
    <OldTargets>NuGet.targets</OldTargets>
    <NewTargets>NuGet.Net40.targets</NewTargets>
    <OldProj>\.csproj</OldProj>
    <NewProj>.Net40.csproj</NewProj>
  </PropertyGroup>

  <Copy SourceFiles="@(SourceProjs)" DestinationFiles="@(DestProjs)"/>
  <FileUpdate Files="@(DestProjs)" Regex="[Nn][Ee][Tt]45" ReplacementText="net40" Encoding="utf-8"/>
  <FileUpdate Files="@(DestProjs)" Regex="$(OldPackages)" ReplacementText="$(NewPackages)" Encoding="utf-8"/>
  <FileUpdate Files="@(DestProjs)" Regex="$(OldTargets)" ReplacementText="$(NewTargets)" Encoding="utf-8"/>
  <FileUpdate Files="@(DestProjs)" Regex="$(OldProj)" ReplacementText="$(NewProj)" Encoding="utf-8"/>

  <Copy SourceFiles="@(SourceConfigs)" DestinationFiles="@(DestConfigs)"/>
  <FileUpdate Files="@(DestConfigs)" Regex="[Nn][Ee][Tt]45" ReplacementText="net40" Encoding="utf-8"/>

  <Copy SourceFiles="$(MsBuildThisFileDirectory)\.nuget\$(OldTargets)" DestinationFiles="$(MsBuildThisFileDirectory)\.nuget\$(NewTargets)"/>
  <FileUpdate Files="$(MsBuildThisFileDirectory)\.nuget\$(NewTargets)" Regex="$(OldPackages)" ReplacementText="$(NewPackages)" Encoding="utf-8"/>

  <Copy SourceFiles="$(MsBuildThisFileDirectory)\my.sln" DestinationFiles="$(MsBuildThisFileDirectory)\my.Net40.sln"/>
  <FileUpdate Files="$(MsBuildThisFileDirectory)\my.Net40.sln" Regex="$(OldProj)" ReplacementText="$(NewProj)" Encoding="utf-8"/>
  <FileUpdate Files="$(MsBuildThisFileDirectory)\my.Net40.sln" Regex="NuGet\.targets" ReplacementText="$(NewTargets)" Encoding="utf-8"/>
</Target>

...
...
packages.config
packages.Net40.config
NuGet.targets
NuGet.Net40.targets
\csproj先生
.Net40.csproj
运行此程序后,每个项目都有一个.Net40.csproj,解决方案有一个.Net40.sln、一个Nuget.Net40.targets和packages.Net40.config文件,所有这些都可以构建。 到目前为止,一切顺利

不过有个小问题:
packages.config
在Nuget.exe中被硬编码为字符串,因此它不会在命令行上接受
packages.net40.config
。它的“算法”的一部分是决定传递给
-install
算法的路径是实际的包配置还是包Id.Lol.I但没有答案。无论如何,我不打算让它破坏乐趣,所以我在源代码中做了一行调整,让它接受以
.config
结尾的任何内容,构建它并立即使用该Nuget.exe