hg extdiff -p and %~dp0

3

myprogram.cmd已经在PATH路径中;

myprogram.cmd使用%~dp0确定所在文件夹;

我已将@echo %~dp0包含在myprogram.cmd中以进行调试;

当我从任何地方调用myprogram.cmd时,它都可以正常工作,并显示myprogram.cmd所在的文件夹;

当我调用hg extdiff -p myprogram.cmd时,它不起作用,显示类似于c:\Users\Username\AppData\Local\Temp\extdiff.3n8op2\的内容。

这是hgrc文件的相关部分:

[extensions]
hgext.extdiff = 

我做错了什么?%~dp0不应该返回批处理文件的驱动器和路径吗?我应该使用什么代替?我需要对Mercurial存储库应用特殊配置吗?将myprogram.cmd的完整路径传递给hg extdiff -p不是一个选项,除非它自动完成。

2个回答

2

%~dp0 技巧是 一个大谎言。它实际上不是一个神奇的变量,而只是对 %0(或者你在前面加了 ~dp 的任何变量)进行操作。它只是将该变量中的字符串解析并告诉你其驱动器和路径组件的位置。如果该字符串只是像“myprogram”这样的名称,则会说“好吧,没有驱动器和路径的文件名被认为在当前目录中”。

因此,%~dp0 技巧仅在以下情况下有效:

a) 你通过完整的名称启动了脚本或 b) 你碰巧在包含脚本的目录中

在这种情况下,你可以运行:

hg extdiff -p myprogram

转换为对Windows的以下调用:

CreateProcess(NULL, "cmd.exe /c myprogram some diff args", ..., "c:/some/temp/path", ...)

这与打开一个shell并运行命令在道德上等价。
C:\>cd c:\some\temp\path
C:\some\temp\path>myprogram some diff args
%0 is myprogram
%~dp0 is C:\some\temp\path

我建议您通过.hgrc文件以以下方式传递您的工具的完整程序名称:
[extdiff]
myprogram=c:/tools/myprogram.cmd

但是要注意,如果文件名中有空格,可能会导致混淆,您可能需要尝试使用引号。


可能您错过了原始帖子的这一部分内容: ‘当我从任何地方调用myprogram.cmd时,它能够完美地工作,并显示myprogram.cmd所在的文件夹’ - Andriy M
不,我只是选择忽略它,因为根据文档和测试,无论是否使用Mercurial,它都是虚假的。 - mpm
1
@mpm,你能否解释一下当我从另一个目录启动脚本时(假设它在PATH中),%dp0如何找到路径?这比你所解释的更为详细:即使%0只是myprogram.cmd,如果从cmd中启动了myprogram.cmd,%dp0仍然可以检测到它的路径。 - utapyngo
我猜有些Windows版本可能会针对扩展%0字符串的情况进行特殊处理...但由于在您上述问题中明显没有调用该特殊情况(并且也没有记录),我强烈建议您停止依赖这种魔法。 - mpm

1
你可以尝试使用%~dp$PATH:0,但需要始终指定扩展名。例如,对于以下的test.cmd
rem test.cmd
@echo dp0 == %~dp0
@echo dp$PATH:0 == %~dp$PATH:0

这是从 d:\hg 文件夹中的两个示例运行:

$ hg extdiff -p test.cmd
dp0 == c:\Users\estefan\AppData\Local\Temp\extdiff.pamj6n\
dp$PATH:0 == k:\home\Scripts\

$ hg extdiff -p test
dp0 == c:\Users\estefan\AppData\Local\Temp\extdiff.dgp0qz\
dp$PATH:0 ==

来自http://ss64.com/nt/syntax-args.html

%~$PATH:1 搜索 PATH 环境变量并将 %1 扩展为找到的第一个匹配项的完全限定名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接