8

I'm calling Process.Start, but it blocks the current thread.

pInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe");

// Start process
mProcess = new Process();
mProcess.StartInfo = pInfo;
if (mProcess.Start() == false) {
    Trace.TraceError("Unable to run process {0}.");
}

Even when the process is closed, the code doesn't respond anymore.

But Process.Start is really supposed to block? What's going on?

(The process start correctly)


using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;

namespace Test
{
    class Test
    {
        [STAThread]
        public static void Main()
        {
            Thread ServerThread = new Thread(AccepterThread);
            ServerThread.Start();

            Console.WriteLine (" ---  Press ENTER to stop service ---");
            while (Console.Read() < 0) { Application.DoEvents(); }

            Console.WriteLine("Done.");
        }

        public static void AccepterThread(object data)
        {
            bool accepted = false;

            while (true) {
                if (accepted == false) {
                    Thread hThread = new Thread(HandlerThread);
                    accepted = true;
                    hThread.Start();
                } else
                    Thread.Sleep(100);
            }
        }

        public static void HandlerThread(object data)
        {
            ProcessStartInfo pInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe");

            Console.WriteLine("Starting process.");

            // Start process
            Process mProcess = new Process();
            mProcess.StartInfo = pInfo;
            if (mProcess.Start() == false) {
                Console.WriteLine("Unable to run process.");
            }
            Console.WriteLine("Still living...");
        }
    }
}

Console output is:

--- Press ENTER to stop service --- Starting process.


Found it:

[STAThread]

Makes the Process.Start blocking. I read STAThread and Multithreading, but I cannot link the concepts with Process.Start behavior.

AFAIK, STAThread is required by Windows.Form. How to workaround this problem when using Windows.Form?


News for the hell:

If I rebuild my application, the first time I run application work correctly, but if I stop debugging and restart iy again, the problem araise.

The problem is not raised when application is executed without the debugger.

Community
  • 1
  • 1
Luca
  • 11,646
  • 11
  • 70
  • 125
  • Set `UseShellExecute` and `ErrorDialog` to true and see if there are any errors being generated. – AMissico Jun 19 '10 at 19:34
  • Well given that we don't know what the "cDaemon" class does, it's kinda hard to tell what's going on. Please try to come up with a short but *complete* program which demonstrates the problem. – Jon Skeet Jun 19 '10 at 19:36
  • (That use of Application.DoEvents combined with Console.Read looks pretty suspicious though.) – Jon Skeet Jun 19 '10 at 19:40
  • @Jon Skeet Here is the working example. 'mProcess.Start' blocks, even if started process has been closed. – Luca Jun 19 '10 at 19:51
  • Found it: [STAThread] makes Process.Start blocking. Still workering why! – Luca Jun 19 '10 at 20:01
  • 1
    I have a WinForms application that calls `Process.Start` without blocking. – ChrisF Jun 19 '10 at 20:20
  • @Luca: No it doesn't. I've just applied it to my sample (see my answer) and it still doesn't block. Your example still isn't a *complete* example - it doesn't have a class declaration. I want something I can just cut and paste, and see it running. Ideally it should use Console.WriteLine instead of Trace for simplicity. – Jon Skeet Jun 19 '10 at 20:21
  • I've just fiddled around with your example to put all the using directives in etc, and it printed out "Still living" - i.e. it didn't block. Again, please create a short but *complete* example, and tell us what it does on your machine. – Jon Skeet Jun 19 '10 at 20:25
  • Actually Process.Start block on my box. But eliminating STAThread works perfectly. – Luca Jun 19 '10 at 20:32
  • @Luca: Weird. It prints "Still living" on my box. – Jon Skeet Jun 19 '10 at 20:34
  • See updates. Seems a timing problem... I can't believe in it. – Luca Jun 19 '10 at 20:37

6 Answers6

13

No, Process.Start doesn't wait for the child process to complete... otherwise you wouldn't be able to use features like redirected I/O.

Sample console app:

using System;
using System.Diagnostics;

public class Test
{
    static void Main()
    {
        Process p = new Process { 
            StartInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe")
        };
        p.Start();
        Console.WriteLine("See, I'm still running");
    }
}

This prints "See, I'm still running" with no problems on my box - what's it doing on your box?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @CurtisWhite: It really doesn't normally. I suggest you ask a new question with a short but complete example. – Jon Skeet Nov 01 '15 at 19:26
  • I posted a new question regarding. One unique aspect is I display a form before the App.Run http://stackoverflow.com/questions/33466758/process-start-block-application-run – Curtis White Nov 01 '15 at 20:31
  • Very strange behavior, I was able to resolve by launching the process start in its own thread. I had tried both using time delays on the start process and launch process, processing do events, etc. The launch process is run inside a C# scripting application NinjaTrader fyi. – Curtis White Nov 02 '15 at 14:25
  • You're right, I deleted my comment after a few minutes, but you must have seen it before my delete. – HerrimanCoder Aug 23 '16 at 12:41
  • @SweatCoder: Yup. Will delete mine now, and then delete *this* one in a few more minutes. – Jon Skeet Aug 23 '16 at 12:42
7

Create a ProcessStartInfo and set UseShellExecute to false (default value is true). Your code should read:

pInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe");
pInfo.UseShellExecute = false;

// Start process
mProcess = new Process();
mProcess.StartInfo = pInfo;
if (mProcess.Start() == false) {
    Trace.TraceError("Unable to run process {0}.");
}

I had the same issue and starting the executable creating the process directly from the executable file solved the issue.

Yves Tkaczyk
  • 521
  • 5
  • 9
  • +1 - Although for me an Excel workbook I was opening was blocking the thread. To open a particular workbook use ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = "EXCEL.EXE"; startInfo.Arguments = filePath – Adam Apr 22 '16 at 07:17
  • I've been trying to solve this issue for days, thank you – ScottishTapWater Jan 10 '17 at 10:24
1

I was experiencing the same blocking behavior as the original poster in a WinForms app, so I created the console app below to simplify testing this behavior.

Jon Skeet's example uses Notepad, which only takes a few milliseconds to load normally, so a thread block may go unnoticed. I was trying to launch Excel which usually takes a lot longer.

using System;
using System.Diagnostics;
using static System.Console;
using System.Threading;

class Program {

    static void Main(string[] args) {

        WriteLine("About to start process...");

        //Toggle which method is commented out:

        //StartWithPath();  //Blocking
        //StartWithInfo();  //Blocking
        StartInNewThread(); //Not blocking

        WriteLine("Process started!");
        Read();
    }

    static void StartWithPath() {
        Process.Start(TestPath);
    }

    static void StartWithInfo() {
        var p = new Process { StartInfo = new ProcessStartInfo(TestPath) };
        p.Start();
    }

    static void StartInNewThread() {
        var t = new Thread(() => StartWithPath());
        t.Start();
    }

    static string TestPath =
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop) +
        "\\test.xlsx";
}

Calls to both StartWithPath and StartWithInfo block my thread in a console app. My console does not display "Process Started" until after the Excel splash screen closes and the main window is open.

enter image description here

StartInNewThread will display both messages on the console immediately, while the splash screen for Excel is still open.

JamesFaix
  • 8,050
  • 9
  • 37
  • 73
0

We had this problem when launching a .bat script that was on a network drive on a different domain (we have dual trusted domains). I ran a remote C# debugger and sure enough Process.Start() was blocking indefinitely.

When repeating this task interactively in power shell, a security dialog was popping up:

enter image description here

As far as a solution, this was the direction we went. The person that did the work modified domain GPO to accomplish the trust.

crokusek
  • 5,345
  • 3
  • 43
  • 61
0

Start server via command prompt:

"C:\Program Files (x86)\IIS Express\iisexpress" /path:\Publish /port:8080

This take access to sub-threads of the tree process of OS.

Gaurav Jeswani
  • 4,410
  • 6
  • 26
  • 47
llyppi
  • 1
0

If you want to launch process and then make the process independent on the "launcher" / the originating call:

//Calling process
using (System.Diagnostics.Process ps = new System.Diagnostics.Process())
{
    try
    {
        ps.StartInfo.WorkingDirectory = @"C:\Apps"; 
        ps.StartInfo.FileName = @"C:\Program Files\Microsoft Office\Office14\MSACCESS.EXE"; //command
        ps.StartInfo.Arguments = @"C:\Apps\xyz.accdb"; //argument
        ps.StartInfo.UseShellExecute = false;
        ps.StartInfo.RedirectStandardOutput = false;
        ps.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized;
        ps.StartInfo.CreateNoWindow = false; //display a windows
        ps.Start();
    }
    catch (Exception ex)
    {
        MessageBox.Show(string.Format("==> Process error <=={0}" + ex.ToString(), Environment.NewLine));
    }
} 
Pepik
  • 111
  • 1
  • 6