Đợi cho đến khi một quá trình kết thúc


206

Tôi có một ứng dụng

Process.Start()

để bắt đầu một ứng dụng khác 'ABC'. Tôi muốn đợi cho đến khi ứng dụng đó kết thúc (quá trình chết) và tiếp tục thực hiện. Tôi làm nó như thế nào?

Có thể có nhiều phiên bản của ứng dụng 'ABC' chạy cùng một lúc.


Và nếu bạn muốn thực hiện nó không đồng bộ (nghĩa là nâng một sự kiện sau khi hoàn thành), bạn có thể xem tại đây tại SO.
Matt

Câu trả lời:


401

Tôi nghĩ bạn chỉ muốn điều này:

var process = Process.Start(...);
process.WaitForExit();

Xem trang MSDN để biết phương pháp. Nó cũng có tình trạng quá tải nơi bạn có thể chỉ định thời gian chờ, do đó bạn không có khả năng chờ đợi mãi mãi.


137

Sử dụng Process.WaitForExit? Hoặc đăng ký Process.Exitedsự kiện nếu bạn không muốn chặn? Nếu điều đó không làm những gì bạn muốn, xin vui lòng cung cấp cho chúng tôi thêm thông tin về các yêu cầu của bạn.


chắc chắn là thông tin tốt với Process.Exited, nhưng OP đã nói "chờ"
Mike M

8
@MikeM: Đó là lý do tại sao tôi đề cập đến WaitForExitđầu tiên ... trong một số trường hợp bạn có thể muốn thực thi nhiều mã hơn khi một cái gì đó kết thúc, nhưng điều đó không có nghĩa là bạn cần chặn chuỗi hiện tại.
Jon Skeet

7
Nếu bạn định sử dụng Process.Exitedsự kiện này, tôi tin rằng bạn phải định cấu hình quy trình trước bằng cách đặt Process.EnableRaisingEventsthành đúng. Mặc dù, xem xét rằng câu hỏi này đã hơn ba tuổi, nhưng có thể đó Process.EnableRaisingEventskhông phải là một điều tại thời điểm nó được hỏi.
Sẽ

Tôi lên trang này để tìm tên của Process.Exitedsự kiện. Cảm ơn! +1 cho sự hoàn chỉnh
Chad

36

Tôi làm như sau trong ứng dụng của mình:

Process process = new Process();
process.StartInfo.FileName = executable;
process.StartInfo.Arguments = arguments;
process.StartInfo.ErrorDialog = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
process.Start();
process.WaitForExit(1000 * 60 * 5);    // Wait up to five minutes.

Có một vài tính năng bổ sung trong đó bạn có thể thấy hữu ích ...


17

Bạn có thể sử dụng chờ thoát hoặc bạn có thể bắt thuộc tính HasExited và cập nhật giao diện người dùng của mình để giữ cho người dùng "được thông báo" (quản lý kỳ vọng):

System.Diagnostics.Process process = System.Diagnostics.Process.Start("cmd.exe");
while (!process.HasExited)
{
    //update UI
}
//done

9

Tôi đã có một trường hợp Process.HasExitedkhông thay đổi sau khi đóng cửa sổ theo quy trình. Vì vậy, Process.WaitForExit()cũng không làm việc. Tôi đã phải theo dõi Process.Respondingđiều đó thành sai sau khi đóng cửa sổ như thế:

while (!_process.HasExited && _process.Responding) {
  Thread.Sleep(100);
}
...

Có lẽ điều này giúp một ai đó.



1

Tham khảo ví dụ về Microsoft: [ https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics. Process.enableraisingevents?view=netframework-4.8 ]

Tốt nhất sẽ là thiết lập:

myProcess.EnableRaisingEvents = true;

Mặt khác, Mã sẽ bị chặn. Cũng không có thuộc tính bổ sung cần thiết.

// Start a process and raise an event when done.
myProcess.StartInfo.FileName = fileName;
// Allows to raise event when the process is finished
myProcess.EnableRaisingEvents = true;
// Eventhandler wich fires when exited
myProcess.Exited += new EventHandler(myProcess_Exited);
// Starts the process
myProcess.Start();

// Handle Exited event and display process information.
private void myProcess_Exited(object sender, System.EventArgs e)
{
Console.WriteLine(
                  $"Exit time    : {myProcess.ExitTime}\n" +
                  $"Exit code    : {myProcess.ExitCode}\n" +
                  $"Elapsed time : {elapsedTime}");
}

0

Giống như Jon Skeet nói, hãy sử dụng Process.Exited:

proc.StartInfo.FileName = exportPath + @"\" + fileExe;
proc.Exited += new EventHandler(myProcess_Exited);
proc.Start();
inProcess = true;

while (inProcess)
{
    proc.Refresh();
    System.Threading.Thread.Sleep(10);
    if (proc.HasExited)
    {
        inProcess = false;
    }
}

private void myProcess_Exited(object sender, System.EventArgs e)
{
    inProcess = false;
    Console.WriteLine("Exit time:    {0}\r\n" +
      "Exit code:    {1}\r\n", proc.ExitTime, proc.ExitCode);
}

Không thực sự trả lời câu hỏi. Vui lòng tinh chỉnh câu trả lời của bạn để giải quyết câu hỏi
Grantly

Và bây giờ? có thể mở vb và đưa ra giải pháp;)
David Lopes

-5

Thử cái này:

string command = "...";
var process = Process.Start(command);
process.WaitForExit();

5
Điểm nhận xét về câu trả lời cho câu hỏi đã được trả lời về câu hỏi đã được trả lời là gì? Bạn không chỉ lãng phí chu kỳ của riêng mình mà bạn còn buộc tôi phải lãng phí cả chu kỳ của mình nữa.
Jamie Ivanov

Những người khác có câu hỏi và câu trả lời @AdamBilinski sẽ có câu hỏi không chỉ người hỏi
L3n

4
@ L3n Tôi đồng ý, nhưng câu trả lời này hoàn toàn giống với câu trả lời được chấp nhận nên thật vô nghĩa!
Adam Bilinski 24/07/2015

@AdamBilinski Oh yea đã không đọc bình luận của bạn đúng cách tha thứ cho tôi xD
L3n 24/07/2015
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.