Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
785 views
in Technique[技术] by (71.8m points)

batch file - Why does forfiles swallow the first argument of the command?

I'm trying to do something similar to Get Visual Studio to run a T4 Template on every build using cmd's forfiles to transform each template in VS2008.

If I execute

forfiles /m "*.tt" /s /c ""%CommonProgramFiles(x86)%Microsoft SharedTextTemplating1.2TextTransform.exe" @file"

then I get TextTransform.exe's error message (the screen of text explaining what to pass it as arguments).

If I instead execute

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

then it works perfectly.

In order to debug this, I created a simple command-line program called debugargs which simply prints the number of arguments it receives and their values. Then some experimentation shows that the first form of directly passing the command to forfiles causes the first argument to be swallowed. E.g.

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

gives output

2 arguments supplied
#1: 2
#2: 3

The documentation I've been able to find is quite sparse, and I don't see any mention of this as a possibility. Is it just an obscure bug, or am I missing something?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This appears to be a bug in the way forfiles invokes .exes. On a hunch I extended my debugargs program to print the full command line.

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"

So the most appropriate workaround would be to double the executable name:

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

The alternative workaround is to invoke with cmd /c. However, note here that if you need to quote the executable's path (e.g. because it contains a space), you'll need an extra workaround of prepending @:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...