如何使用 argv 在 C# 中启动子进程? (或者将agrv转换为合法的arg字符串)
我有一个 C# 命令行应用程序,需要在 Windows 和 Unix 中的 Mono 下运行。在某些时候,我想启动一个子进程,给定一组通过命令行传入的任意参数。例如:
Usage: mycommandline [-args] -- [arbitrary program]
不幸的是,System.Diagnostics.ProcessStartInfo 仅采用字符串作为参数。对于以下命令来说这是一个问题:
./my_commandline myarg1 myarg2 -- grep "a b c" foo.txt
在这种情况下 argv 看起来像:
argv = {"my_commandline", "myarg1", "myarg2", "--", "grep", "a b c", "foo.txt"}
请注意,“ab c”周围的引号被 shell 删除,因此如果我只是连接参数以便为 ProcessStartInfo 创建 arg 字符串,我会得到
args = "my_commandline myarg1 myarg2 -- grep a b c foo.txt"
:这不是我想要的。
有没有一种简单的方法可以将 argv 传递到 C# 下的子进程启动,或者将任意 argv 转换为对 Windows 和 linux shell 合法的字符串?
任何帮助将不胜感激。
I have a C# command-line application that I need to run in windows and under mono in unix. At some point I want to launch a subprocess given a set of arbitrary paramaters passed in via the command line. For instance:
Usage: mycommandline [-args] -- [arbitrary program]
Unfortunately, System.Diagnostics.ProcessStartInfo only takes a string for args. This is a problem for commands such as:
./my_commandline myarg1 myarg2 -- grep "a b c" foo.txt
In this case argv looks like :
argv = {"my_commandline", "myarg1", "myarg2", "--", "grep", "a b c", "foo.txt"}
Note that the quotes around "a b c" are stripped by the shell so if I simply concatenate the arguments in order to create the arg string for ProcessStartInfo I get:
args = "my_commandline myarg1 myarg2 -- grep a b c foo.txt"
Which is not what I want.
Is there a simple way to either pass an argv to subprocess launch under C# OR to convert an arbitrary argv into a string which is legal for windows and linux shell?
Any help would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
MSDN 有一个关于 MS Visual C 运行时如何解析返回的字符串的描述
GetCommandLine()
到argv
数组。您可能还对
list2cmdline()
来自 Python 标准库的函数,Python 的subprocess
模块使用该函数来模拟 Win32 环境中的 Unixargv
行为。MSDN has a description of how the MS Visual C Runtime parses the string returned by
GetCommandLine()
into anargv
array.You might also be interested in the
list2cmdline()
function from the Python standard library that is used by Python'ssubprocess
module to emulate the Unixargv
behavior in a Win32 environment.在 windowsland 中,这真的很简单...在传递给 System.Diagnostics.ProcessStartInfo 对象的字符串中添加额外的引号。
例如“./my_commandline”“myarg1 myarg2 -- grep \“abc \”foo.txt”
In windowsland, it's simple really...add extra quotation marks in the string you pass to the System.Diagnostics.ProcessStartInfo object.
e.g. "./my_commandline" "myarg1 myarg2 -- grep \"a b c\" foo.txt"
感谢大家的建议。我最终使用了 shquote 中的算法(http://www.daemon-systems .org/man/shquote.3.html)。
我只在linux上测试过这个。对于 Windows,您只需连接参数即可。
Thanks to all for the suggestions. I ended up using the algorithm from shquote (http://www.daemon-systems.org/man/shquote.3.html).
I've only tested this on linux. For windows you can just concatenate the args.
您将需要使用
grep
以及grep
需要的所有参数来运行一个新的子进程。然后调用 runProcess("grep", "a", "b", "c", "foo.txt");
编辑:更新了参数处理。
You will need to run a new subprocess using
grep
and all arguments thatgrep
will be needing.then make a call to
runProcess("grep", "a", "b", "c", "foo.txt");
Edit: Updated args handling.
只需使用正则表达式检查字符串是否包含任何类型的空格,然后将原始字符串替换为带引号的新字符串:
Just use a Regex to check if a string has spaces of any kind, and replace the original string with a new one with quotes: