Как я могу выполнять программы в моем% PATH% с MSBuild? - PullRequest
3 голосов
/ 10 августа 2011

Примечание: я использую 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 ]

1 голос
/ 02 сентября 2011

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

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

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

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

msbuild build.proj

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

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

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

path=%path%;%windir%\Microsoft.net\Framework\v4.0.30319
1 голос
/ 11 августа 2011

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

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

<HgVersion LocalPath="$(MSBuildProjectDirectory)" Timeout="5000">
     <Output TaskParameter="Revision" PropertyName="AssemblyRevision" />
</HgVersion>
...