From the registry, for a given file type, I get a string containing something like this:
"C:\Program Files\AppName\Executable.exe" /arg1 /arg2 /arg3
or sometimes:
"C:\Program Files\AppName\Executable.exe" /arg1 /arg2 /arg3 "%1"
In order for me to execute this program, and pass along a filename as a parameter (which I know it accepts), do I have to parse this string myself, or is there a runtime class that will do this for me? Note that I’m not asking about handling the difference between the two in regards to whether it has a “%1” or not, but rather I need to split off the name of the executable, get the command line arguments to it separately.
I tried just appending/injecting the full path to and name of the file to pass along into the string above and pass the whole shebang to Process.Start, but of course it expects just the filename as the single argument, so that doesn’t work.
Basically, the above would have to be done like this manually:
Process proc = new Process();
proc.StartInfo.FileName = @"C:\Program Files\AppName\Executable.exe";
proc.StartInfo.Arguments = "/arg1 /arg2 /arg3 \"" + fileName + "\"";
proc.Start();
I tried using UseShellExecute, but that didn’t help. Any other pointers?
To be clear, I want this:
String commandPath = ReadFromRegistry();
String fullCommand = commandPath + " " + fileName; // assuming not %1
Process.Start(fullCommand); // <-- magic happens here
The problem you are facing is that the executable name and some arguments are already together in your variable
commandPath(which is not only the path, but also some params). If the first part were only made up of characters (no spaces), it wouldn’t have been too hard to separate the executable from the params, but this is Windows, so you may have spaces, so you are stuck. So it seems.The solution is in not using
Process.Start, and not usingShellExecute.Process.Start, whether you ask it to useShellExecuteorCreateProcess, in both cases, it requires theFileNameparameter/member to be set, which is passed as-is to CreateProcess and ShellExecute.So what then? Rather simply put: use
CreateProcessyourself. A lesser known feature of that API function is that you can pass a full commandline to it, just as you can under WinKey+R (Windows Run). The “magic” that you ask for can be achieved by setting its first param tonulland its second param to the full path, including all parameters. Like the following, which will start the Windows Photo Gallery for you, while using the same string with the params withProcess.Startany which way would yield a “File Not Found” error:Note that I deliberately did not include quotes around the executable path. But if the executable path has quotes around it, as with your code above, it will still work, all the magic is there. Combine that with your code snippet, the following will start the process the way you want:
The declarations are something you can get from http://www.pinvoke.net, but for convenience, here’s the part that should be pasted inside the class section to get the above to work. Reference of these functions, how to check the result (success / fail) and the
STARTUPINFOandPROCESS_INFORMATIONstructures can be found at Microsoft’s MSDN here. for convenience, I recommend to place the call toCreateProcessin a utility function.Hope I understood your problem correctly. Let me know if you have trouble implementing the above code.