What’s the difference between Process and ProcessStartInfo in C#? - c#

What’s the difference between Process and ProcessStartInfo? I’ve used both to launch external programs but there has to be a reason there are two ways to do it. Here are two examples.
Process notePad = new Process();
notePad.StartInfo.FileName = "notepad.exe";
notePad.StartInfo.Arguments = "ProcessStart.cs";
notePad.Start();
and
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "notepad.exe";
startInfo.Arguments = "ProcessStart.cs";
Process.Start(startInfo);

They are pretty close to the same, both are from the Process class. And there are actually 4 other overloads to Process.Start other than what you mentioned, all static.
One is a static method way to do it. It returns the Process object representing the process that is started. You could for example start a process with a single line of code by using this way.
And the other is a member method way to do it which reuses the current object instead of returning a new one.

Heh.
If you look closely at your code, you will note that they are both using the same classes. The StartInfo property in your first example is, unsurprsingly, a ProcessStartInfo. In your second example, you call the static .Start method on the Process class.
So what are the differences? Significant. They're different classes. One is for launching processes, one is for saying which process to launch (and lots of other little things, like capturing output, etc). In the first case, you just use the default ProcessStartInfo property that the class has.

It seems that ProcessStartInfo is a subset of Process if you look at the members of notePad variable below
Process notePad = new Process();
You will notice that StartInfo has type (or of class) ProcessStartInfo
which is why the two initializations are the same
notePad.StartInfo.FileName = "notepad.exe"; Vs startInfo.FileName = "notepad.exe";
Since Process is the full class I would think it can do everything ProcessStartInfo can do plus extra But Don't take my word for it I only less than a year experience in .Net

Related

load and execute external program (many times)

I need to execute external program with arguments and get result from it (~1000 times with different arguments).
I found solution like this:
using System.Diagnostics;
...
Process process = new Process();
// Configure the process using the StartInfo properties.
process.StartInfo.FileName = "process.exe";
process.StartInfo.Arguments = "qwe 123";
process.Start();
process.WaitForExit();// Waits here for the process to exit.
// And check exit code for result
I need many repetitions with different arguments, but this code every time initiate new process. It is very expensive operation. I think, i can "load" ("save") process and repeat it without everytime initiating.
Or maybe exist other way to solve this problem?
If the started process is under your control it will be much more efficient to pass the input not via command line parameter for a new process instance every time, but re-program it so that the process reads its standard input line-wise in a loop, processes each line, and writes the result to its standard output. It's easy to hook up the calling program to the process' input and output:
// ...
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
// ...
process.Start();
StreamReader results = process.StandardOutput;
StreamWriter processInput = process.StandardInput;
foreach( var arg in args )
{
processInput.WriteLine(arg);
var oneResult = results.ReadLine();
// do something with this oneResult
}
This example assumes that each argument fits in one line (and each result fits in a line, too). Writing and reading a single line each time is our simple "protocol" for knowing when to start processing (on the process side) and when the result is complete (on the C# side).
I should perhaps add that a real program should add error handling and e.g. evaluate Process.Start()'s return value.

Get Process id that started using ProcessStartInfo in C#

I need to get process id of the newly created process with help of ProcessStartInfo class
here's my code
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "chrome.exe";
startInfo.Arguments = "--app=http://www.google.com/";
Process p = new Process();
p.StartInfo = startInfo;
p.Start();
Console.WriteLine(p.Id);
However it return an ID which is not the id of the process chrome.exe process. I have verified the presence of chrome.exe process in PowerShell with different Process ID
Thanks in Advance.
Chrome will run multiple processes with one parent process creating a number of child processes. When you run Chrome from the command line your new Chrome process will most likely communicate with an existing Chrome process (the parent I guess) and then exit which explains the behavior you see.

Start and manage external process from a WPF app

I have a WPF application and I need to spin up a separate MFC application and then communicate with it. I was going to use Process.Start, but I'm wondering if there is a better way to do this these days. I can research things myself, but I need to know where to start. Thanks.
Edits:
I found this suggesting there isn't. Is this true?
Alternatives to System.Diagnostics.Process.Start()
Thanks.
For your immediate question, there is nothing new in the recent versions of .NET that gives a better or more up-to-date way to start a local executable. Process.Start is (and has been) the way to go.
The simplest, and most convenient, is to select one of the five static methods on Process. Passing strings or a populated StartInfo instance. You would use the latter if you needed more control over how the process got raised. Or of interest in your case, if you wanted to pipe the program's stdio as a stream into your own application. Here's a sample of populating a Start Info instance from one of my utilities...
ProcessStartInfo start = new ProcessStartInfo(BaseIoConstantsProvider.CommandProcessor)
{
Arguments = BaseIoConstantsProvider.KeepAlive,
UseShellExecute = false,
CreateNoWindow = BaseIoConstantsProvider.NoDosWindow,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
WindowStyle = ProcessWindowStyle.Hidden,
};
For the second part of your question, the static method will not do if you need to interact with the process once it is started. From the same utility...
Process p = new Process { StartInfo = start, EnableRaisingEvents = true };
p.ErrorDataReceived += PErrorDataReceived;
p.Exited += PExited;
p.Start();
p.StandardInput.AutoFlush = true;
p.StandardInput.WriteLine(cmdLine);
p.BeginOutputReadLine();
This example shows a two events being hooked along with reading the stdio from the process. It's great for that purpose, but overkill if you just want to start another executable.
So the main determinate in selecting a start method is the question: does my app need to interact with the process once it's started?
And finally, sometimes you may want to invoke a canonical verb, or even create a verb of your own to start a given process. These appear in the context menu when you right click an item and give you lots of additional flexibility for starting a process. There's an excellent article here http://msdn.microsoft.com/en-us/library/windows/desktop/cc144101(v=vs.85).aspx#canonical on how to implement a verb.

C# equivalent to fork()/exec()

I'm developing a program that needs to call an outside program, but needs to wait for it to execute. This is being done in C# (to which I am brand new, but have lots of experience in C++, Qt, and C) and CreateProcess does not seem to be what I'm looking for (starts the process, then forgets it, which I don't need).
This is one of my first Windows projects (or at least, only Windows and definitely only .NET) and I'm much more used to doing this sort of thing for *nix where I would use fork and then exec in the child, then wait for the child to terminate. But I have no idea where to even start looking to do something like this.
Oh, and I'm pretty sure I'm stuck in .NET because I need read access to the registry to complete this project and .NET's registry access is absolutely amazing (in my opinion, I don't have anything to compare it to).
Thanks.
You can use the Process class. It lets you specify some options about how you want to execute it, and also provides a method which waits the process to exit before executing the next statement.
look at this link (the msdn reference):
http://msdn.microsoft.com/fr-fr/library/system.diagnostics.process.aspx
basically what you can do is:
Process p;
// some code to initialize it, like p = startProcessWithoutOutput(path, args, true);
p.WaitForExit();
an example of initializing the process (that's just some code I used once somewhere):
private Process startProcessWithOutput(string command, string args, bool showWindow)
{
Process p = new Process();
p.StartInfo = new ProcessStartInfo(command, args);
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = !showWindow;
p.ErrorDataReceived += (s, a) => addLogLine(a.Data);
p.Start();
p.BeginErrorReadLine();
return p;
}
as you can see in this code you can also do some output redirection, error redirection.... If you dig in the class I think you'll find quite quickly what you need.
var p = System.Diagnostics.Process.Start("notepad");
p.WaitForExit();
You can use the Process class to start external processes.
It will let you start arbitrary programs
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx

Window for a newly started process in C# is showing up behind my current open windows

I have some fairly straightforward code to open up files using a Process object:
var proc = new Process();
proc.StartInfo.FileName = attachmentPath;
proc.StartInfo.UseShellExecute = true;
proc.Start();
Every once in a while, the window that opens from this process starting open behind all my currently open windows. I don't see any pattern or consistency to why this happens. Does anybody have an idea why this happens, or how I can work around it? Thanks!
Windows has discouraged applications from stealing focus for a while; the rules around it aren't really documented, presumably to prevent applications from working around them.
However, you could give this a try:
var proc = new Process();
proc.StartInfo.FileName = attachmentPath;
proc.StartInfo.UseShellExecute = true;
proc.Start();
//Wait for window to spin up
proc.WaitForInputIdle();
BringWindowToTop(proc.MainWindowHandle);
Define BringWindowToTop with p/invoke.

Categories

Resources