Как я могу выполнять программы в моем%PATH% с MSBuild?

Примечание: я использую Mercurial в качестве примера здесь, потому что это то, что я пытаюсь заставить работать с MSBuild прямо сейчас.
Но проблема не ограничивается Mercurial, это происходит с каждой внешней программой, которая находится где-то в моем %PATH% переменная (я пробовал то же самое с PowerShell, например).
Поэтому я не ставил метку Mercurial на этот вопрос специально, потому что это не про Mercurial!

Что я на самом деле хочу сделать:
Я хочу, чтобы мой скрипт сборки получил текущий номер ревизии из моего репозитория Mercurial и сохранил его в файле.
Самый простой способ сделать это из командной строки:

hg id -i >rev.txt

Mercurial установлен на моей машине и папка установки находится в моем %PATH% переменная.
Таким образом, я могу запустить эту строку из любого места на моем компьютере (непосредственно из командной строки или из командного файла), и она просто работает.

Проблема возникает, когда я пытаюсь запустить эту строку из моего скрипта сборки.
Я меняю BeforeBuild (или же AfterBuild) раздел моего.csproj файла следующим образом:

<Target Name="AfterBuild">
     <Exec Command="hg id -i >rev.txt"/>
</Target>

Когда я компилирую свое решение с помощью Visual Studio, оно работает, и файл rev.txt создается в папке, где находится мой.csproj.

Но когда я компилирую точно такое же решение из командной строки с MSBuild, сборка завершается неудачно со следующим сообщением об ошибке:

Команда "hg id -i >rev.txt" завершена с кодом 9009.

Я погуглил "msbuild code 9009" и нашел несколько решений, но все они предлагают предоставить полный путь к исполняемому файлу.
Когда я делаю это, сборка также успешно выполняется с MSBuild.
Но это не приемлемое для меня решение, потому что я не могу быть уверен, что все, кто использует мой проект (включая сервер сборки), установили Mercurial в одну и ту же папку.
Это именно то, что %PATH% для...

То же самое происходит, когда я ставлю <Exec Command="... строка прямо в скрипт сборки.
Если я указываю путь к исполняемому файлу, он работает.
Если я не укажу путь, это не так.

Есть ли хитрость, чтобы заставить MSBuild выполнять программы в моем %PATH% переменная без указания полной папки?


РЕДАКТИРОВАТЬ:

@leppie:

Перенаправление вывода:
Вы имеете в виду тот факт, что я сохраняю вывод моей команды в текстовом файле внутри команды, а не просто запускаю hg id -i в качестве команды и используя выходной параметр или что-то подобное, чтобы получить вывод?
Не имеет значения... ошибка та же, когда я опускаю >rev.txt,

Аргументы командной строки:
Нет, он выдает ту же ошибку, даже если я сокращаю команду до hg (без каких-либо параметров).

Не забывайте: если я запускаю точно такую ​​же команду Exec в том же файле.csproj из Visual Studio, или если я просто указываю путь к файлу.exe в команде, все работает.
Так что перенаправление вывода IMO и аргументы командной строки не могут быть проблемой.

2 ответа

Решение

Хорошо, я нашел решение.
Я должен признать, что это был классический случай PEBKAC:-)

Я все равно объясню, может быть, это поможет тому, кто совершил ту же ошибку:

В основном все, что я пробовал (плюс то, что Джеймс Вулфенден предложил в своем ответе), сработало бы... если бы только командный файл, который я использую для запуска сценария сборки, не выглядел бы так:

path="%windir%\Microsoft.net\Framework\v4.0.30319"

msbuild build.proj

Да, точно.
Я редактирую %PATH% переменная для продолжительности этого пакетного файла, и я перезаписываю его путем к MSBuild, а не просто добавляю его.

Поэтому, когда мой скрипт сборки пытается вызвать Mercurial, он больше не может его найти, потому что его местоположение не находится в %PATH% Переменная больше.
Понятия не имею, почему я этого раньше не видел.

Правильный способ - добавить путь MSBuild, оставив другие пути без изменений:

path=%path%;%windir%\Microsoft.net\Framework\v4.0.30319

Вы пробовали этот пакет расширений для mercurial / msbuild? http://msbuildhg.codeplex.com/documentation

Кажется, есть задача для возврата идентификатора ревизии, чего нет у вас?

<HgVersion LocalPath="$(MSBuildProjectDirectory)" Timeout="5000">
     <Output TaskParameter="Revision" PropertyName="AssemblyRevision" />
</HgVersion>
Другие вопросы по тегам