1

I am running a C# console application in through my C# code using the Process.Start() method. The console application takes a file name as argument. The file path is user given though my application and may contain spaces.

I am doing it this way:

string arguments = "\"" + inputListFilePath + "\"";
Process.Start(executableFilePath, arguments);

What I have observed is the argument being passed to the executable is \"inputListFilePath\" because of which the EXE file is not running because of an incorrect parameter.

I have tried using @"""" instead of "\"". But the string gets converted to \" when I use this.

What wrong can I possibly be doing here?

BTW, the EXE file is running fine manually.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Abhishek
  • 2,925
  • 4
  • 34
  • 59
  • 3
    @GrantWinney: this can go badly wrong if the argument contains for instance a space, and it is still a single argument. – Willem Van Onsem Dec 24 '14 at 04:43
  • @Abhishek: I don't think the problem is caused by the quotes, but because you work on a Windows machine and Windows paths use backslashes that can be interpreted as escape chars by the shell. – Willem Van Onsem Dec 24 '14 at 04:52

2 Answers2

1

Based on the following session in the csharp interactive command line:

$ 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

In other words, echo receives "FooBar" as an argument and doesn't seem to have any problem with the quotes. It returns FooBar on the last line... It thus parses the input correctly.

What probably causes the problem is the following:

  • You enter a path, say C:\Documents\file.txt.
  • You pass it to your program as program "C:\Documents\file.txt"
  • The shell reads \D as an escape character.

A potential fix to the problem is using single* quotes (') as well as double escaping backslashes.

Testcase (proof of concept):

$ 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

As conclusion I would advice you to use:

string arguments = "'" + inputListFilePath.Replace("\\","\\\\") + "'";
Process.Start(executableFilePath, arguments);

Instead since single quotes are interpreted as literal strings (without escape chars).


Note: this only causes problems if one uses Windows paths since Linux uses slashes (/).

Note: a more precise way to escape the string is using this algorithm.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
1

Don't quote the whole list of arguments. Quote just those arguments in the list including spaces. Because the space is considered a separator in the arguments list.

(1) On Windows, the following opens the WordPad application (write.exe) through the command shell (cmd.exe /c), with a file, "C:\program files\temp.txt", the application will ask you about:

Process.Start("cmd.exe", @"/c write.exe ""c:\program files\temp.txt""");

for the equivalent command line call

cmd.exe /c write.exe "c:\program files\temp.txt"

(2) With no additional quotes for the file name, the application will ask you about the "C:\program" file, taking the subsequent space for an argument list separator and ignoring the rest:

Process.Start("cmd.exe", @"/c write.exe c:\program files\temp.txt");

with the equivalent command line call

cmd.exe /c write.exe c:\program files\temp.txt

(3) If you quote the whole argument list (as in your original example), the result is unpredictable for more than one argument. In most cases you actually combined all arguments into one single argument (for our use case, we get the same message as for (2), a question about the "C:\program" file):

Process.Start("cmd.exe", @"""/c write.exe c:\program files\temp.txt""");

with the equivalent command line call

cmd.exe "/c write.exe C:\program files\temp.txt"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Cristian Scutaru
  • 1,375
  • 19
  • 23
  • when I use a `"""`, it gets changed to `\"`. And The name of the file is in a string variable. – Abhishek Dec 24 '14 at 06:44
  • @Abhishek, please come up with a specific example, same way I did, with concrete values. I see you gave the same laconic answers to CommuSoft and you just confuse us, when we try to help. We cannot guess what exactly you actually pass as arguments. – Cristian Scutaru Dec 24 '14 at 08:33