3
votes

All I am trying to do is send a command that opens a model with the program.exe Supposed to be super simple!

Ex:

"C:\Program Files (x86)\River Logic\Enterprise Optimizer 7.4 Developer\EO74.exe" "C:\PauloXLS\Constraint Sets_1.cor"

The line above works well if pasted on the command prompt window. However, when trying to pass the same exact string on my code it gets stuck on C:\Program

string EXE = "\"" + @tbx_base_exe.Text.Trim() + "\"";
string Model = "\"" + @mdl_path.Trim()+ "\"";

string ExeModel = EXE + " " + Model;

MessageBox.Show(ExeModel);

ExecuteCommand(ExeModel);

ExeModel is showing te following line on Visual Studio:

"\"C:\\Program Files (x86)\\River Logic\\Enterprise Optimizer 7.4 Developer\\EO74.exe\" \"C:\\PauloXLS\\Constraint Sets_1.cor\""

To me looks like it is the string I need to send in to the following method:

public int ExecuteCommand(string Command)
{
   int ExitCode;
   ProcessStartInfo ProcessInfo;
   Process Process;

   ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + Command);
   ProcessInfo.CreateNoWindow = true;
   ProcessInfo.UseShellExecute = true;

   Process = Process.Start(ProcessInfo);
   Process.WaitForExit();
   ExitCode = Process.ExitCode;
   Process.Close();

   return ExitCode;
}

Things I've tried:

  1. Pass only one command at a time (works as expected), but not an option since the model file will open with another version of the software.
  2. Tried to Trim
  3. Tried with @ with \"

Can anyone see any obvious mistake? Thanks.

2
Why are you using cmd.exe /K ... instead of simply calling the program directly? That would allow you avoid the hassle of having to escape spaces... - Heinzi
Yes, use Process.Start to invoke the actual EXE you want. That will avoid any problem you may be having where you'd otherwise need to "double-escape" special characters. - KeithS
A hassel exists either way. You either have to escape the command string to pass as an argument to cmd.exe, or you have to parse the original command to separate the filename from the arguments in order to pass them to Process.Start, which requires them to be passed separately. If you start with them separated, it's easy. However, if you are given a single command string with both file name and arguments in it, it is arguable less-complicated to escape the string and pass it to cmd.exe, than it is to try to separate the file name from the arguments by checking for quoted names or spaces. - Triynko

2 Answers

6
votes

It's pretty straightforward. You just create a command line object then write to it, then to execute it you read back from it using SR.ReadToEnd():

private string GETCMD()
{
    string tempGETCMD = null;
    Process CMDprocess = new Process();
    System.Diagnostics.ProcessStartInfo StartInfo = new System.Diagnostics.ProcessStartInfo();
    StartInfo.FileName = "cmd"; //starts cmd window
    StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    StartInfo.CreateNoWindow = true;
    StartInfo.RedirectStandardInput = true;
    StartInfo.RedirectStandardOutput = true;
    StartInfo.UseShellExecute = false; //required to redirect
    CMDprocess.StartInfo = StartInfo;
    CMDprocess.Start();
    System.IO.StreamReader SR = CMDprocess.StandardOutput;
    System.IO.StreamWriter SW = CMDprocess.StandardInput;
    SW.WriteLine("@echo on");
    SW.WriteLine("cd\\"); //the command you wish to run.....
    SW.WriteLine("cd C:\\Program Files");
    //insert your other commands here
    SW.WriteLine("exit"); //exits command prompt window
    tempGETCMD = SR.ReadToEnd(); //returns results of the command window
    SW.Close();
    SR.Close();
    return tempGETCMD;
}
3
votes

Why are you opening a command prompt (cmd.exe)? Just pass the name of the executable.