Как запустить MSBuild из Powershell без запуска процесса msbuild.exe? - PullRequest
11 голосов
/ 23 января 2009

Я рассматриваю возможность запуска MSBuild из сценария Powershell путем прямого подключения к сборкам MSBuild (в отличие от поиска пути установки MSBuild и запуска msbuild.exe как дочернего процесса).

Кто-нибудь делал это? Какой самый простой и простой способ запустить сборку? Есть ли плюсы / минусы в любой технике, на которые вы хотели бы указать? (Меня особенно интересуют любые проблемы, которые могут возникнуть при запуске msbuild в том же процессе / домене приложения, что и остальная часть сценария).

В настоящее время мое мышление выглядит примерно так:

[void][System.Reflection.Assembly]::Load('Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][Microsoft.Build.BuildEngine.Engine]::GlobalEngine.BuildProjectFile("path/main.proj")

Ответы [ 5 ]

14 голосов
/ 23 января 2009

Простейшим вызовом встроенной сборки, который работал и создавал вывод, было:

[void][System.Reflection.Assembly]::Load('Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
$engine = New-Object Microsoft.Build.BuildEngine.Engine
$engine.RegisterLogger((New-Object Microsoft.Build.BuildEngine.ConsoleLogger))
$engine.BuildProjectFile('fullPath\some.proj')

Однако оказывается, что встраивание MSBuild непосредственно в Powershell (V1) проблематично:

'MSBUILD : warning MSB4056: The MSBuild engine must be called on
a single-threaded-apartment. Current threading model is "MTA".
Proceeding, but some tasks may not function correctly.'

Почему мы все еще платим налог на прибыль в 2009 году, работая в управляемой среде?

Мой вывод заключается в том, что встраивание MSBuild в Powershell (V1) не очень хорошая идея. Для справки, я также включаю подход, основанный на процессах, который я в итоге использовал:

[void][System.Reflection.Assembly]::Load('Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
$msbuild = [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFrameworkFile("msbuild.exe", "VersionLatest")
&$msbuild fullPath\some.proj
5 голосов
/ 23 января 2009

Я бы очень рекомендовал посмотреть на PSake .

Позвольте мне процитировать часть этой страницы:

Помните, что psake является синтаксическим сахаром для PowerShell. Так что все, что вы можете сделать в PowerShell, вы можете сделать в psake. Это означает, что вы можете запускать MSBuild, NAnt или другие сценарии. Нет необходимости полностью заменять вашу текущую систему сборки. Вы можете использовать psake для автоматизации и расширения!

psake автоматически добавляет соответствующую версию .NET Framework к своему пути. Таким образом, вы можете получить доступ к MSBuild, csc.exe, vbc.exe или любым другим инструментам, установленным в $ env: windir \ Microsoft.NET \ Framework \ $ version \ без полного пути.

3 голосов
/ 23 января 2009

Я искал то же самое. Следуя примеру ДжаредПара, я обнаружил следующее:

Это руководство по созданию командлета.

http://bartdesmet.net/blogs/bart/archive/2008/02/03/easy-windows-powershell-cmdlet-development-and-debugging.aspx

MSBuild API является частью этих пространств имен:

Microsoft.Build.Framework

Microsoft.Build.BuildEngine

А документацию по MSBuild можно найти здесь (это больше для полноты, чем в ответ на ваш вопрос):

http://msdn.microsoft.com/en-us/library/wea2sca5.aspx

3 голосов
/ 23 января 2009

Другой и потенциально более удобный подход заключается в создании командлета msbuild. MsBuild имеет хороший API, и есть много примеров того, как его использовать на скомпилированном языке, таком как C # / VB. Было бы очень легко создать командлет, который обеспечил бы гораздо более приятный синтаксис для ваших сценариев PowerShell.

0 голосов
/ 30 января 2013

Когда-то я играл с запущенными процессами сборки MSBuild (например, более агрессивно пропускал некоторые части сборки).

Было два варианта:

  1. Разместите MSBuild в своем собственном процессе, загрузив его DLL.
  2. Создайте MSBuild.exe обычным способом, а затем вставьте в него (например, логгеры обеспечивают приличный путь).

Я реализовал оба варианта, и мне пришлось отказаться от № 1, потому что он не был достаточно гибким.

Например, MSBuild загружает перенаправления привязки сборки в своем файле .config.

Процесс Visual Studio (devenv.exe), в котором также размещается MSBuild с его API, в итоге копирует их в devenv.exe.config. Мой .exe.config также должен был иметь их, но он привязан к конкретной версии MSBuild. И, конечно же, вы должны изменить конфиг. Что на самом деле не подходит для PS, поэтому я сомневаюсь, что вы могли бы получить действительно стабильное решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...