Переопределить версию Visual Studio 2008 MSBuild
Можно ли изменить версию msbuild, которая используется Visual Studio 2008 при компиляции проектов?
Я хотел бы настроить его на использование msbuild 4.0.
Причиной этого является возможность импортировать тот же файл.targets, который используется нашими проектами VS2012 для восстановления пакетов nuget. Проекты не могут быть обновлены до VS10+, потому что они являются проектами Smart Device.
Я попытался вручную отредактировать исходный файл целей, но в msbuild 3.5 отсутствуют слишком много функций, и я не мог обойти их.
Обновить:
Исходный файл.targets также использует функцию автоматической загрузки для файла nuget.exe, используя задачу кода, которая не поддерживается в MSBuild 3.5, поэтому это следует учитывать.
1 ответ
Когда вы компилируете из Visual Studio, вы используете devenv вместо msbuild. Было бы здорово увидеть, как devenv вызывает msbuild (но, будучи VS инструментом без открытого кода, мы просто не можем). Поэтому я не думаю, что это возможно. Может быть, есть другой подход, чтобы сделать то, что вы пытаетесь сделать.
MSbuild v3.5 не поддерживает создание динамических задач, как MSbuild 4.0, но вы можете создавать собственные задачи и импортировать их.
Сначала создайте простую библиотеку классов (я назвал ее 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".
Я понимаю, что вы хотите использовать один и тот же файл.targets как для VS2012, так и для VS2008, но (как вы сказали) существует много различий между MSBuild 3.5 и 4.0, поэтому конкретный подход проще сделать.