为什么forfiles吞下命令的第一个参数?

时间:2013-04-04 16:54:40

标签: batch-file cmd

我正在尝试使用cmd的forfiles执行与Get Visual Studio to run a T4 Template on every build类似的操作来转换VS2008中的每个模板。

如果我执行

forfiles /m "*.tt" /s /c "\"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"

然后我收到TextTransform.exe的错误消息(文本屏幕解释了将其作为参数传递的内容)。

如果我改为执行

forfiles /m "*.tt" /s /c "cmd /c echo Transforming @path && \"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"

然后它完美无缺。

为了调试这个,我创建了一个名为debugargs的简单命令行程序,它只打印它接收的参数数量及其值。然后一些实验表明直接将命令传递给forfiles的第一种形式导致第一个参数被吞下。 E.g。

forfiles /m "*.tt" /s /c "debugargs.exe 1 2 3"

给出输出

2 arguments supplied
#1: 2
#2: 3

我能找到的documentation非常稀疏,我没有看到任何提及这种可能性。这只是一个不起眼的错误,还是我错过了什么?

3 个答案:

答案 0 :(得分:3)

这似乎是forfiles调用.exe的方式中的错误。在预感中,我扩展了debugargs程序以打印完整的命令行。

X:\MyProject>forfiles /m "*.tt" /s /c "debugargs.exe 1 2 @file"

2 arguments supplied
#1: 2
#2: Urls.tt
Full command line: 1 2 "Urls.tt"

因此,最合适的解决方法是将可执行文件名加倍:

forfiles /m "*.tt" /s /c "debugargs.exe debugargs.exe 1 2 @file"

替代解决方法是使用cmd /c进行调用。但是,请注意,如果您需要引用可执行文件的路径(例如,因为它包含空格),您需要额外的解决方法来预先@

forfiles /m "*.tt" /s /c "cmd /c @\"debugargs.exe\" 1 2 @file"

答案 1 :(得分:0)

我也复制了forfiles中的行为。您可以在命令之前使用cmd / c进行解决,也可以转换到PowerShell,其中等效命令将是这样的(未经测试):

get-childitem . -filter "*.tt" -recurse | foreach-object {
  & "${ENV:CommonProgramFiles(x86)}\Microsoft Shared\TextTemplating\1.2\TextTransform.exe" "`"$($_.Name)`""
}

比尔

答案 2 :(得分:0)

我也一直在努力解决这个问题。我找到的解决方法是在命令和第一个参数之间添加额外的空格!所以我试图去做的地方:

FORFILES /s /m *.dll /c "python \"c:\path\to\script.py\" -t arg1 etc"

python试图找到要执行的文件“arg1”,但如果我只是将其更改为:

FORFILES /s /m *.dll /c "python  \"c:\path\to\script.py\" -t arg1 etc"

这实际上有效!