如何使用MSBuild在我的%PATH%中执行程序?

如何使用MSBuild在我的%PATH%中执行程序?,msbuild,msbuild-task,Msbuild,Msbuild Task,注意:我在这里使用Mercurial作为示例,因为这正是我现在尝试使用MSBuild的原因。 但问题并不局限于Mercurial,它发生在我的%PATH%变量中的每个外部程序上(例如,我在PowerShell中尝试过同样的方法)。 所以我不是故意在这个问题上加上Mercurial标签的,因为这不是关于Mercurial的 我真正想做的事: 我希望我的构建脚本从Mercurial存储库中获取当前版本号,并将其存储在文件中。 从命令行执行此操作的最简单方法是: hg id -i >rev.tx

注意:我在这里使用Mercurial作为示例,因为这正是我现在尝试使用MSBuild的原因。
但问题并不局限于Mercurial,它发生在我的
%PATH%
变量中的每个外部程序上(例如,我在PowerShell中尝试过同样的方法)。
所以我不是故意在这个问题上加上Mercurial标签的,因为这不是关于Mercurial的

我真正想做的事:
我希望我的构建脚本从Mercurial存储库中获取当前版本号,并将其存储在文件中。
从命令行执行此操作的最简单方法是:

hg id -i >rev.txt
Mercurial安装在我的计算机上,安装文件夹位于我的
%PATH%
变量中。
因此,我可以在我的机器上的任何地方运行这一行(直接从命令行或批处理文件),并且它可以正常工作

当我尝试从生成脚本运行此行时,会出现问题。
我将.csproj文件的
BeforeBuild
(或
AfterBuild
)部分更改如下:

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

当我用Visual Studio编译我的解决方案时,它工作了,并且在my.csproj所在的文件夹中创建了rev.txt文件

但是当我使用MSBuild从命令行编译完全相同的解决方案时,生成失败,并显示以下错误消息:

命令“hgid-i>rev.txt”退出,代码为9009

我在谷歌上搜索了“msbuild code 9009”并找到了,但他们都建议提供可执行文件的完整路径。
当我执行此操作时,MSBuild的生成也会成功。
但这对我来说不是一个可接受的解决方案,因为我不能确定使用我的项目(包括构建服务器)的每个人都已将Mercurial安装在完全相同的文件夹中。
这正是
%PATH%
的作用


当我放置
时也会发生同样的情况。您是否尝试过mercurial/msbuild的此扩展包?

似乎有一个返回修订id的任务,这是您试图实现的否

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

好的,我找到了解决方案。
我必须承认,这是一个典型的例子:-)

不管怎样,我都会解释,也许它会帮助犯同样错误的人:

基本上,我尝试过的一切(加上James Woolfenden在回答中提出的建议)都会成功…如果我用来运行构建脚本的批处理文件不是这样的话:

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

问题在于输出重定向,可能还有命令行参数。Exec任务不提供这些选项吗?在我问这个问题之前,我已经尝试了MSBuild Versioning(),它的行为是相同的:当从Visual Studio触发生成时,它工作,当从MSBuild触发生成时,它说找不到hg.exe。在您的建议后,我还尝试了MSBuild Mercurial任务(),但我根本无法让它工作……它总是说它找不到hg.exe,不管我是从Visual Studio还是直接从MSBuild运行它。