1

是否可以在编译项目时更改Visual Studio 2008使用的msbuild版本?覆盖Visual Studio 2008 MSBuild版本

我想将它设置为使用msbuild 4.0。

这背后的原因是能够导入我们的VS2012项目用于nuget包恢复的相同.targets文件。项目无法升级到VS10 +,因为它们是智能设备项目。

我试着手动编辑原始目标文件,但msbuild 3.5中缺少太多的功能,我无法解决它们。

更新:

原来.targets文件还使用自动下载功能的nuget.exe文件,使用代码的任务,是在3.5的MSBuild不支持的,所以这一点是应该考虑到。

回答

1

从Visual Studio编译时,您使用的是devenv而不是msbuild。很高兴看到devenv如何调用msbuild(但是VS是一个非开源工具,我们不能)。所以,我认为这是不可能的。也许还有另一种方法来做你想做的事情。

MSbuild v3.5不支持将动态任务创建为MSbuild 4.0,但可以使用create customized tasksimport them

首先,创建一个简单的类库(我把它叫做DownloadNuget2008.dll)含有任务下载nuget.exe(从nuget.targets拍摄):

using System; 
using System.IO; 
using System.Net; 
using Microsoft.Build.Utilities; 

namespace DownloadNuget2008 
{ 
    public class DownloadNuget2008Task : Task 
    { 
     public string OutputFilename { get; set; } 

     public override bool Execute() 
     { 
      try 
      { 
       OutputFilename = Path.GetFullPath(OutputFilename); 

       Log.LogMessage("Downloading latest version of NuGet.exe..."); 
       var webClient = new WebClient(); 
       webClient.DownloadFile("https://nuget.org/nuget.exe", OutputFilename); 

       return true; 
      } 
      catch (Exception ex) 
      { 
       Log.LogErrorFromException(ex); 
       return false; 
      } 
     } 
    } 
} 

我曾经对我的恢复包的NuGet Visual Studio 2008中使用exec任务以下(编辑您的csproj/vbproj):

<UsingTask AssemblyFile="$(SolutionDir)DownloadNuget2008.dll" TaskName="DownloadNuget2008Task" /> 
    <!-- Download NuGet.exe if it does not already exist --> 
    <PropertyGroup> 
    <NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(SolutionDir)nuget.exe</NuGetExePath> 
    <DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe> 
    </PropertyGroup> 
    <Target Name="_DownloadNuGet"> 
    <Message Text="Downloading nuget..." /> 
    <DownloadNuget2008Task OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" /> 
    <Message Text="Downloading nuget - done." /> 
    </Target> 
    <!-- NuGet Packages Installation (Begin) --> 
    <Target Name="Install-Packages"> 
    <Exec Command="$(SolutionDir)nuget install $(ProjectDir)packages.config -o $(SolutionDir)packages" /> 
    </Target> 
    <!-- NuGet Packages Installation (End) --> 
    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 
    <Target Name="BeforeBuild"> 
    <CallTarget Targets="_DownloadNuGet" /> 
    <CallTarget Targets="Install-Packages" /> 
    </Target> 

然后你会看到在输出:

Target BeforeBuild: 
    Task "CallTarget" 
    Target "_CheckForInvalidConfigurationAndPlatform" skipped. Previously built successfully. 
    Target _DownloadNuGet: 
     Task "Message" 
     Downloading nuget... 
     Done executing task "Message". 
     Using "DownloadNuget2008Task" task from assembly "C:\marcos\Testes\NuGet2008\ConsoleApplication1\DownloadNuget2008.dll". 
     Task "DownloadNuget2008Task" 
     Downloading latest version of NuGet.exe... 
     Done executing task "DownloadNuget2008Task". 
     Task "Message" 
     Downloading nuget - done. 
     Done executing task "Message". 
    Done executing task "CallTarget". 
    Task "CallTarget" 
    Target "_CheckForInvalidConfigurationAndPlatform" skipped. Previously built successfully. 
    Target Install-Packages: 
     Task "Exec" 
     Command: 
     C:\marcos\Testes\NuGet2008\ConsoleApplication1\nuget install C:\marcos\Testes\NuGet2008\ConsoleApplication1\ConsoleApplication1\packages.config -o C:\marcos\Testes\NuGet2008\ConsoleApplication1\packages 
     Successfully installed 'elmah 1.2.2'. 
     Done executing task "Exec". 
    Done executing task "CallTarget". 

我知道你希望对VS2012和VS2008使用相同的.targets文件,但是(如你所说)MSBuild 3.5和4.0之间有很多不同之处,所以特定的方法更容易。

+0

这将工作,如果不是因为我们也自动从.targets文件下载nuget.exe的事实。你有什么建议吗?我将编辑该问题以正确反映这一点。 – julealgon

+0

我会考虑并更新我的答案。 –

+0

现在这看起来很合适,我想。我从来没有见过如何构建自定义任务,真棒的东西。有必要为此创建一个新项目有点麻烦,但我怀疑没有其他方法确实使用MSBuild 3.5。另外,我能否根据toolsversion或.targets文件中的某些内容制作一些开关,并将它们中的两个合并为一个?我认为这在我们的情况下是理想的。我会将你的帖子标记为答案,尽管我几天之内无法测试它。非常感谢您的帮助。 – julealgon