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

发布于 2024-11-28 22:07:03 字数 1799 浏览 6 评论 0原文

注意:我在这里使用 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 编译我的解决方案时,它可以工作并创建 rev.txt 文件在我的 .csproj 所在的文件夹中。

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

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

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

当我将

有什么技巧可以让 MSBuild 在我的 %PATH% 变量中执行程序而不指定完整的文件夹吗?


编辑:

@leppie:

输出重定向:
您的意思是我将命令的输出保存在命令内的文本文件中,而不是仅将 hg id -i 作为命令运行并使用输出参数或者类似的东西来获得输出?
没有任何区别...当我省略 >rev.txt 时,错误是相同的。

命令行参数:
不,即使我将命令缩短为 hg (不带任何参数),它也会引发相同的错误。

不要忘记:如果我在 Visual Studio 中的完全相同的 .csproj 文件中运行完全相同的 Exec 命令,或者如果我只是在命令中提供 .exe 文件的路径,则一切正常。
因此,IMO 输出重定向和命令行参数不可能是问题。

Note: I'm using Mercurial as an example here, because that's what I'm trying to get to work with MSBuild right now.
But the problem is not limited to Mercurial, it happens with every external program that is somewhere in my %PATH% variable (I tried the same with PowerShell, for example).
So I didn't put the Mercurial tag on this question on purpose, because this is not about Mercurial!

What I actually want to do:
I want my build script to get the current revision number from my Mercurial repository and store it in a file.
The simplest way to do this from the command line is:

hg id -i >rev.txt

Mercurial is installed on my machine and the installation folder is in my %PATH% variable.
So I can run this line from anywhere on my machine (directly from the command line, or from a batch file), and it just works.

The problem occurs when I try to run this line from my build script.
I change the BeforeBuild (or AfterBuild) section of my .csproj file as follows:

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

When I compile my solution with Visual Studio, it works and the rev.txt file is created in the folder where my .csproj is.

But when I compile the exact same solution from the command line with MSBuild, the build fails with the following error message:

The command "hg id -i >rev.txt" exited with code 9009.

I googled "msbuild code 9009" and found some solutions, but all of them propose to provide the full path to the executable.
When I do this, the build succeeds with MSBuild as well.
But this is not an acceptable solution for me, because I can't be sure that everyone using my project (including the build server) has installed Mercurial in the exact same folder.
That's exactly what %PATH% is for...

The same happens when I put the <Exec Command="... line directly into the build script.
If I specify the path to the executable, it works.
If I don't specify the path, it doesn't.

Is there any trick to make MSBuild execute programs in my %PATH% variable without specifying the complete folder?


EDIT:

@leppie:

Output redirection:
You mean the fact that I save the output of my command in a text file inside the command , instead of just running hg id -i as a command and using an output parameter or something like that to get the output?
Doesn't make any difference...the error is the same when I omit >rev.txt.

Command line args:
No, it throws the same error, even if I shorten the command to just hg (without any parameters).

Don't forget: if I run the exact same Exec command in the exact same .csproj file from Visual Studio, or if I just provide the path to the .exe file in the command, everything works.
So IMO output redirection and command line args can't be the problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷情 2024-12-05 22:07:03

好的,我找到了解决方案。
我不得不承认,这是 PEBKAC 的经典案例:-)

我会解释一下无论如何,也许它会对犯同样错误的人有所帮助:

基本上我尝试过的所有内容(加上 James Woolfenden 在他的回答中建议的内容)都会起作用......如果我用来运行构建脚本的批处理文件不会看起来不像这样:

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

msbuild build.proj

是的,完全正确。
我在此批处理文件的持续时间内编辑 %PATH% 变量,并使用 MSBuild 的路径覆盖它,而不是仅仅附加< /strong> 它。

因此,当我的构建脚本尝试调用 Mercurial 时,它无法再找到它,因为它的位置不再位于 %PATH% 变量中。
不知道为什么我以前没有看到这个。

正确的方法是附加 MSBuild 路径,保持其他路径不变:

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

Okay, I found the solution.
I have to admit, it was a classic case of PEBKAC :-)

I'll explain it anyway, maybe it will help someone who made the same mistake:

Basically everything I have tried (plus what James Woolfenden suggested in his answer) would have been worked...if only the batch file that I use to run the build script wouldn't have looked like this:

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

msbuild build.proj

Yes, exactly.
I'm editing the %PATH% variable for the duration of this batch file, and I'm overwriting it with the path to MSBuild instead of just appending it.

So when my build script tries to call Mercurial, it can't find it anymore because its location is not in the %PATH% variable anymore.
No idea why I didn't see this before.

The correct way would be to append the MSBuild path, leaving the other paths intact:

path=%path%;%windir%\Microsoft.net\Framework\v4.0.30319
李白 2024-12-05 22:07:03

您是否尝试过这个 Mercurial/msbuild 扩展包?
http://msbuildhg.codeplex.com/documentation

似乎有一个返回修订id的任务,这是你想达到什么目标?

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

Have you tried this extension pack for mercurial/msbuild?
http://msbuildhg.codeplex.com/documentation

Seems to have a task for returning revision id, which is what your trying to achieve no?

<HgVersion LocalPath="$(MSBuildProjectDirectory)" Timeout="5000">
     <Output TaskParameter="Revision" PropertyName="AssemblyRevision" />
</HgVersion>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文