当命令包含空格时,cmd /C 在 Rust 中不起作用
cmd /C doesn't work in Rust when command includes spaces
我想从 Rust 程序运行这个命令:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "https://whosebug.com/"
在 cmd 中,这有效。
cmd /C ""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "https://whosebug.com/""
在 C# 中,这有效。
var comm = @"""""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"" ""https://whosebug.com/""""";
System.Diagnostics.Process.Start("cmd", "/C " + comm);
在 Rust 中,这不起作用。
let comm = r#"""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "https://whosebug.com/"""#;
let output = Command::new("cmd")
.args(&["/C", comm])
.output()
.expect("failed to execute process");
我收到以下错误。
The network path was not found.
但是,当 comm
为 echo hello
时有效。
我尝试了另外两种方法:
这个
let comm = r#"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe https://whosebug.com/"#;
是
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
这个
let comm = r#""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe https://whosebug.com/""#;
是
'\"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe\"' is not recognized as an internal or external command,
operable program or batch file.
这是a known issue。不幸的是,转义参数的 Windows 规则非常重要且难以正确执行。
此代码:
let comm = r#""C:\Program Files\Google\Chrome\Application\chrome.exe" https://whosebug.com/"#;
let mut cmd = Command::new("cmd");
cmd.arg("/c");
cmd.arg(comm);
执行这个:
"cmd" "/c" "\"C:\Program Files\Google\Chrome\Application\chrome.exe\" https://whosebug.com/"
不幸的是,内引号被转义了,尽管在这种情况下它们不应该被转义。
作为变通方法,在许多情况下,您实际上不需要使用 cmd
。在这些情况下,直接执行流程更为明智:
let output = Command::new(r#"C:\Program Files\Google\Chrome\Application\chrome.exe"#)
.args(&["https://whosebug.com/"])
.output()
.expect("failed to execute process");
我找到了类似情况的解决方案:
use std::process::Command;
use std::thread;
use std::time;
fn main() {
let child = Command::new("netsh")
.arg("advfirewall")
.arg("firewall")
.arg("add")
.arg("rule")
.arg(r#"name="something2""#)
.arg("dir=in")
.arg("action=allow")
.arg("protocol=TCP")
.arg("localport=12006")
.spawn()
.expect("failed");
thread::sleep(time::Duration::new(10, 0));
println!("done");
let output = child.stdout;
println!("{:?}", output);
}
这处理命令行提示
netsh advfirewall firewall add rule name="something2" dir=in action=allow protocol=TCP localport=12006
我想从 Rust 程序运行这个命令:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "https://whosebug.com/"
在 cmd 中,这有效。
cmd /C ""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "https://whosebug.com/""
在 C# 中,这有效。
var comm = @"""""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"" ""https://whosebug.com/""""";
System.Diagnostics.Process.Start("cmd", "/C " + comm);
在 Rust 中,这不起作用。
let comm = r#"""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "https://whosebug.com/"""#;
let output = Command::new("cmd")
.args(&["/C", comm])
.output()
.expect("failed to execute process");
我收到以下错误。
The network path was not found.
但是,当 comm
为 echo hello
时有效。
我尝试了另外两种方法:
这个
let comm = r#"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe https://whosebug.com/"#;
是
'C:\Program' is not recognized as an internal or external command, operable program or batch file.
这个
let comm = r#""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe https://whosebug.com/""#;
是
'\"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe\"' is not recognized as an internal or external command, operable program or batch file.
这是a known issue。不幸的是,转义参数的 Windows 规则非常重要且难以正确执行。
此代码:
let comm = r#""C:\Program Files\Google\Chrome\Application\chrome.exe" https://whosebug.com/"#;
let mut cmd = Command::new("cmd");
cmd.arg("/c");
cmd.arg(comm);
执行这个:
"cmd" "/c" "\"C:\Program Files\Google\Chrome\Application\chrome.exe\" https://whosebug.com/"
不幸的是,内引号被转义了,尽管在这种情况下它们不应该被转义。
作为变通方法,在许多情况下,您实际上不需要使用 cmd
。在这些情况下,直接执行流程更为明智:
let output = Command::new(r#"C:\Program Files\Google\Chrome\Application\chrome.exe"#)
.args(&["https://whosebug.com/"])
.output()
.expect("failed to execute process");
我找到了类似情况的解决方案:
use std::process::Command;
use std::thread;
use std::time;
fn main() {
let child = Command::new("netsh")
.arg("advfirewall")
.arg("firewall")
.arg("add")
.arg("rule")
.arg(r#"name="something2""#)
.arg("dir=in")
.arg("action=allow")
.arg("protocol=TCP")
.arg("localport=12006")
.spawn()
.expect("failed");
thread::sleep(time::Duration::new(10, 0));
println!("done");
let output = child.stdout;
println!("{:?}", output);
}
这处理命令行提示
netsh advfirewall firewall add rule name="something2" dir=in action=allow protocol=TCP localport=12006