C# - Making a Process.Start wait until the process has start-up

前端 未结 12 2081
迷失自我
迷失自我 2020-11-27 17:12

I need to make sure that a process is running before moving on with a method.

The statement is:

Process.Start(\"popup.exe\");

Can y

相关标签:
12条回答
  • 2020-11-27 17:43

    Are you sure the Start method returns before the child process starts? I was always under the impression that Start starts the child process synchronously.

    If you want to wait until your child process finishes some sort of initialization then you need inter-process communication - see Interprocess communication for Windows in C# (.NET 2.0).

    0 讨论(0)
  • 2020-11-27 17:47

    You can also check if the started process is responsive or not by trying something like this: while(process.responding)

    0 讨论(0)
  • 2020-11-27 17:48

    I agree with Tom. In addition, to check the processes while performing Thread.Sleep, check the running processes. Something like:

    bool found = 0;
    while (!found)
    {
        foreach (Process clsProcess in Process.GetProcesses())
            if (clsProcess.Name == Name)
                found = true;
    
        Thread.CurrentThread.Sleep(1000);
    }
    
    0 讨论(0)
  • 2020-11-27 17:49
    public static class WinApi
    {
    
        [DllImport("user32.dll")]
        public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    
        public static class Windows
        {
            public const int NORMAL = 1;
            public const int HIDE = 0;
            public const int RESTORE = 9;
            public const int SHOW = 5;
            public const int MAXIMIXED = 3;
        }
    
    }
    

    App

    String process_name = "notepad"
    Process process;
    process = Process.Start( process_name );
    
    while (!WinApi.ShowWindow(process.MainWindowHandle, WinApi.Windows.NORMAL))
    {
        Thread.Sleep(100);
        process.Refresh();
    }
    
    // Done!
    // Continue your code here ...
    
    0 讨论(0)
  • 2020-11-27 17:50

    Do you mean wait until it's done? Then use Process.WaitForExit:

    var process = new Process {
        StartInfo = new ProcessStartInfo {
            FileName = "popup.exe"
        }
    };
    process.Start();
    process.WaitForExit();
    

    Alternatively, if it's an application with a UI that you are waiting to enter into a message loop, you can say:

    process.Start();
    process.WaitForInputIdle();
    

    Lastly, if neither of these apply, just Thread.Sleep for some reasonable amount of time:

    process.Start();
    Thread.Sleep(1000); // sleep for one second
    
    0 讨论(0)
  • 2020-11-27 17:57

    Here an implementation that uses a System.Threading.Timer. Maybe a bit much for its purpose.

        private static bool StartProcess(string filePath, string processName)
        {
            if (!File.Exists(filePath))
                throw new InvalidOperationException($"Unknown filepath: {(string.IsNullOrEmpty(filePath) ? "EMPTY PATH" : filePath)}");
    
            var isRunning = false;
    
            using (var resetEvent = new ManualResetEvent(false))
            {
    
                void Callback(object state)
                {
                    if (!IsProcessActive(processName)) return;
                    isRunning = true;
                    // ReSharper disable once AccessToDisposedClosure
                    resetEvent.Set();
                }
    
                using (new Timer(Callback, null, 0, TimeSpan.FromSeconds(0.5).Milliseconds))
                {
                    Process.Start(filePath);
                    WaitHandle.WaitAny(new WaitHandle[] { resetEvent }, TimeSpan.FromSeconds(9));
                }
            }
    
            return isRunning;
        }
    
        private static bool StopProcess(string processName)
        {
            if (!IsProcessActive(processName)) return true;
    
            var isRunning = true;
    
            using (var resetEvent = new ManualResetEvent(false))
            {
    
                void Callback(object state)
                {
                    if (IsProcessActive(processName)) return;
                    isRunning = false;
                    // ReSharper disable once AccessToDisposedClosure
                    resetEvent.Set();
                }
    
                using (new Timer(Callback, null, 0, TimeSpan.FromSeconds(0.5).Milliseconds))
                {
                    foreach (var process in Process.GetProcessesByName(processName))
                        process.Kill();
                    WaitHandle.WaitAny(new WaitHandle[] { resetEvent }, TimeSpan.FromSeconds(9));
                }
            }
    
            return isRunning;
        }
    
        private static bool IsProcessActive(string processName)
        {
            return Process.GetProcessesByName(processName).Any();
        }
    
    0 讨论(0)
提交回复
热议问题