我正在使用Process.Start()
方法通过我的C#代码运行C#控制台应用程序。控制台应用程序将文件名作为参数。文件路径是用户通过我的应用程序给出的,可能包含空格。
我这样做:
string arguments = "\""+ inputListFilePath + "\"";
Process.Start(executableFilePath, arguments);
我观察到的是传递给可执行文件的参数是\"inputListFilePath\"
,因为参数不正确导致exe没有运行。
我尝试使用@""""
代替"\""
。但是当我使用它时,字符串会转换为\"
。
我可能在这里做错了什么?
BTW exe手动运行正常。
答案 0 :(得分:1)
基于csharp
交互式命令行中的以下会话:
$ csharp
Mono C# Shell, type "help;" for help
Enter statements below.
csharp> string a = "FooBar";
csharp> "\""+ a + "\""
"\"FooBar\""
csharp> '\"'+ a + '\"'
"\"FooBar\""
csharp> Console.WriteLine('\"'+ a + '\"');
"FooBar"
csharp> using System.Diagnostics;
csharp> Process.Start("echo",'\"'+a+'\"');
System.Diagnostics.Process (echo)
csharp> FooBar
换句话说,echo
收到"FooBar"
作为参数,似乎对引号没有任何问题。它在最后一行返回FooBar
...因此它正确地解析了输入。
可能导致问题的原因如下:
C:\Documents\file.txt
。program "C:\Documents\file.txt"
\D
作为转义字符读取。问题的一个潜在解决方法是使用 single * 引号('
)以及双重转义反斜杠。
测试用例(概念证明):
$ csharp
Mono C# Shell, type "help;" for help
Enter statements below.
csharp> string a = @"C:\Documents\File.txt"
csharp> using System.Diagnostics;
csharp> Process.Start("echo",'"'+a+'"');
C:\Documents\File.txt
System.InvalidOperationException: Process has exited, so the requested information is not available.
at System.Diagnostics.Process.get_ProcessName () [0x00000] in <filename unknown>:0
at System.Diagnostics.Process.ToString () [0x00000] in <filename unknown>:0
at Mono.CSharpShell.PrettyPrint (System.IO.TextWriter output, System.Object result) [0x00000] in <filename unknown>:0
at Mono.CSharpShell.Evaluate (System.String input) [0x00000] in <filename unknown>:0
csharp> Process.Start("echo","'"+a+"'");
System.Diagnostics.Process (echo)
csharp> C:DocumentsFile.txt
csharp> Process.Start("echo",'"'+a.Replace("\\","\\\\")+'"');
System.Diagnostics.Process (echo)
csharp> C:\Documents\File.txt
作为结论,我建议你使用:
string arguments = "'" + inputListFilePath.Replace("\\","\\\\") + "'";
Process.Start(executableFilePath, arguments);
相反,因为单引号被解释为文字字符串(没有转义字符)。
注意:如果使用 Windows 路径,这只会导致问题,因为 Linux 使用斜杠(
/
)。注意:使用this算法更准确地转义字符串。
答案 1 :(得分:1)
不要引用整个 参数列表,只引用列表中包含空格的那些参数。因为该空间在参数列表中被视为分隔符。
(1)在Windows中,以下命令通过命令外壳(cmd.exe / c)打开写字板应用程序(write.exe),文件“c:\ program files \ temp.txt”应用程序将询问你:
Process.Start("cmd.exe", @"/c write.exe ""c:\program files\temp.txt""");
用于等效的命令行调用
cmd.exe /c write.exe "c:\program files\temp.txt"
(2)如果文件名没有附加引号,应用程序会询问您“c:\ program”文件,将后续空格作为参数列表分隔符并忽略其余部分:
Process.Start("cmd.exe", @"/c write.exe c:\program files\temp.txt");
使用等效的命令行调用
cmd.exe /c write.exe c:\program files\temp.txt
(3)如果引用整个参数列表(如原始示例中所示),则结果对于多个参数是不可预测的。在大多数情况下,您实际上将所有参数合并为一个参数(对于我们的用例,我们得到与(2)相同的消息,关于“c:\ program”文件的问题):
Process.Start("cmd.exe", @"""/c write.exe c:\program files\temp.txt""");
使用等效的命令行调用
cmd.exe "/c write.exe c:\program files\temp.txt"