Как мне построить решение программно в C#?

Как программно построить решение C#? Я должен быть в состоянии пройти путь решения и получить выходные сообщения (или просто построить решение), как мне добиться этого в C#?

7 ответов

Решение

Большинство из вас предоставляют способы сделать это, вызывая внешние команды, но есть API, Microsoft.Build.Framework, для сборки через C#


Код из блога:

using Microsoft.Build.BuildEngine;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

public class SolutionBuilder
{
    BasicFileLogger b;
    public SolutionBuilder() { }

    [STAThread]
    public string Compile(string solution_name,string logfile)
    {
        b = new BasicFileLogger();
        b.Parameters = logfile;
        b.register();
        Microsoft.Build.BuildEngine.Engine.GlobalEngine.BuildEnabled = true;
        Project p = new Project (Microsoft.Build.BuildEngine.Engine.GlobalEngine);
        p.BuildEnabled = true;
        p.Load(solution_name);
        p.Build();
        string output = b.getLogoutput();
        output += “nt” + b.Warningcount + ” Warnings. “;
        output += “nt” + b.Errorcount + ” Errors. “;
        b.Shutdown();
        return output;
    }
}
//The above class is used and compilation is initiated by the following code,
static void Main(string[] args)
{
    SolutionBuilder builder = new SolutionBuilder();
    string output = builder.Compile(@”G:CodesTestingTesting2web1.sln”, @”G:CodesTestingTesting2build_log.txt”);
    Console.WriteLine(output);
    Console.ReadKey();
}

Обратите внимание, что код в этом блоге работает, но немного устарел

Microsoft.Build.BuildEngine

был разбит на несколько частей

Microsoft.Build.Construction

Microsoft.Build.Evaluation

Microsoft.Build.Execution

Посмотрите эту ссылку для примера использования API.NET 4.0 MSBuild:

http://www.odewit.net/ArticleContent.aspx?id=MsBuildApi4&format=html

List<ILogger> loggers = new List<ILogger>();
loggers.Add(new ConsoleLogger());
var projectCollection = new ProjectCollection();
projectCollection.RegisterLoggers(loggers);
var project = projectCollection.LoadProject(buildFileUri); // Needs a reference to System.Xml
try
{
    project.Build();
}
finally
{
    projectCollection.UnregisterAllLoggers();
}

Более простой пример:

var project = new Project(buildFileUri, null, "4.0");
var ok = project.Build(); // or project.Build(targets, loggers)
return ok;

Не забудьте использовать профиль.NET 4 (не профиль клиента).

Добавьте следующие ссылки: System.XML, Microsoft.Build, Microsoft.Build.Framework и, необязательно, Microsoft.Build.Utilities.v4.0.

Также посмотрите здесь:

работает msbuild программно

Чтобы построить решение, сделайте следующее:

var props = new Dictionary<string, string>();
props["Configuration"] = "Release";
var request = new BuildRequestData(buildFileUri, props, null, new string[] { "Build" }, null);
var parms = new BuildParameters();
// parms.Loggers = ...;

var result = BuildManager.DefaultBuildManager.Build(parms, request);
return result.OverallResult == BuildResultCode.Success;
// Fix to the path of your msbuild
var pathToMsBuild = "C:\\Windows\\DotNet\\Framework\\msbuild.exe";

Process.Start(pathToMsBuild + " " + pathToSolution);

Вы можете создать файл.proj:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <!-- Common -->
    <Solution Include="Common\Util\Util.sln"/>
    <Solution Include="Common\EventScheduler\EventSchedulerSolution\EventSchedulerSolution.sln"/>
    <!-- Server -->
    <Solution Include="Server\DataLayer\DataTransferObjects\SharedModel\SharedModel.sln"/>
    <Solution Include="Server\DataLayer\DataTier\ESPDAL.sln"/>
    <!-- Internal Tools -->
    <Solution Include="InternalTools\ServerSchemaUtility\ServerSchemaUtility.sln"/>
  </ItemGroup>
  <Target Name="Rebuild">
    <MSBuild Projects="@(Solution)" Targets="Rebuild" Properties="Configuration=Release"/>
  </Target>
</Project>

а затем вызовите msbuild.exe, используя в качестве аргумента файл proj, ниже приведен пример пакетного файла. Из C# вы можете вызвать Process.Start, как указано другими авторами.

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" BuildSolutions.proj

pause

Если вам нужно перенести сборку из кода расширения Visual Studio, вы должны учитывать ограничения, налагаемые интерфейсом IVsBuildManagerAccessor - см. Общие замечания, включая новый файл IVsBuildManagerAccessor.docx из инфраструктуры управляемых пакетов для проектов. Эта вилка также доступна на github.

В Visual Studio 2010 с MSBuild 4.0 появились новые взаимодействия между Solution Build Manager и MSBuild, которые влияют на системы проектов, использующие эти сервисы. MSBuild 4.0 содержит новый компонент под названием Build Manager (его не следует путать с Solution Build Manager, который является компонентом VS), который контролирует отправку запросов на сборку. Это стало необходимым, поскольку Visual Studio 2010 теперь позволяет выполнять параллельные сборки (в частности, собственные проекты), а доступ к общим ресурсам, таким как ЦП, необходимо опосредовать. Чтобы системы проектов, которые ранее просто вызывали Project.Build(), вызывали сборку, необходимо внести несколько изменений. Система проектов теперь должна:

  1. Запросите службу SVsBuildManagerAccessor с помощью интерфейса IServiceProvider. Это должно быть сделано вскоре после загрузки системы проекта, задолго до того, как могут произойти какие-либо сборки.
  2. Уведомить систему, если вам нужен поток пользовательского интерфейса
  3. Сообщите системе, если вы делаете сборку во время разработки.
  4. Зарегистрируйте свои регистраторы, используя Build Manager Accessor.
  5. Отправляйте запросы на сборку непосредственно в диспетчер сборки MSBuild, а не вызывайте метод в проекте.

Конечно, вы можете использовать msbuild для создания любого файла решения Visual Studio.

Я верю, что вы можете использовать Process.Start вызвать msbuild с соответствующими параметрами.

Другие вопросы по тегам