Programing

프로세스가 시작될 때까지 Process.Start 대기 만들기

crosscheck 2020. 10. 26. 07:41
반응형

프로세스가 시작될 때까지 Process.Start 대기 만들기


메서드를 진행하기 전에 프로세스가 실행 중인지 확인해야합니다.

진술은 다음과 같습니다.

Process.Start("popup.exe");

WAIT 명령을 수행하거나이 값에 지연을 설정할 수 있습니까?


완료 될 때까지 기다리라는 뜻입니까? 그런 다음 사용하십시오 Process.WaitForExit.

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

또는 메시지 루프에 들어가기를 기다리는 UI가있는 애플리케이션 인 경우 다음과 같이 말할 수 있습니다.

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

마지막으로, 이들 중 어느 것도 적용되지 않는 경우 Thread.Sleep적절한 시간 동안 :

process.Start();
Thread.Sleep(1000); // sleep for one second

한 번도 필요했고 프로세스의 창 제목을 확인했습니다. 예상 한 것이라면 응용 프로그램이 실행 중인지 확인할 수 있습니다. 내가 확인한 응용 프로그램은 시작하는 데 약간의 시간이 필요했으며이 방법은 저에게 잘 작동했습니다.

var process = Process.Start("popup.exe");
while(process.MainWindowTitle != "Title")
{
    Thread.Sleep(10);
}

'ChrisG'의 대답은 정확하지만 MainWindowTitle을 매번 새로 고침해야하며 비어 있는지 확인하는 것이 좋습니다.

var proc = Process.Start("popup.exe");
while (string.IsNullOrEmpty(proc.MainWindowTitle))
{
    System.Threading.Thread.Sleep(100);
    proc.Refresh();
}

우선 : 이것이 다소 오래되었다는 것을 알고 있지만 여전히 받아 들여지는 대답이 없으므로 내 접근 방식이 다른 사람에게 도움이 될 것입니다. :)

이것을 해결하기 위해 내가 한 것은 다음과 같습니다.

process.Start();

while (true)
{
    try
    {
        var time = process.StartTime;
        break;
    }
    catch (Exception) {}
}

연결 var time = process.StartTime은 프로세스가 시작되지 않는 한 예외를 발생시킵니다. 따라서 일단 통과하면 프로세스가 실행 중이라고 가정하고 추가로 작업하는 것이 안전합니다. 시간이 좀 걸리기 때문에 Java 프로세스가 시작될 때까지 기다리는 데 이것을 사용하고 있습니다. 이렇게하면을 사용하는 대신 응용 프로그램이 실행중인 시스템에 독립적이어야합니다 Thread.Sleep().

나는 이것이 매우 깨끗한 솔루션은 아니지만 성능에 독립적이어야하는 유일한 솔루션이라는 것을 이해합니다.


다른 사람들이 이미 말했듯이, 당신이 무엇을 요구하는지 즉시 명확하지 않습니다. 프로세스를 시작한 다음 프로세스가 "준비"되었을 때 다른 작업을 수행하려고한다고 가정하겠습니다.

물론 "준비되었습니다"는 까다로운 부분입니다. 필요한 것이 무엇인지에 따라 단순히 기다리는 것으로 충분하다는 것을 알 수 있습니다. 그러나 더 강력한 솔루션이 필요한 경우 명명 된 Mutex사용 하여 두 프로세스 간의 제어 흐름을 제어 할 수 있습니다 .

예를 들어, 메인 프로세스에서 명명 된 뮤텍스를 생성하고 대기 할 스레드 또는 작업을 시작할 수 있습니다. 그런 다음 두 번째 프로세스를 시작할 수 있습니다. 해당 프로세스가 "준비 완료"를 결정하면 명명 된 뮤텍스를 열고 (물론 동일한 이름을 사용해야 함) 첫 번째 프로세스에 신호를 보낼 수 있습니다.


나는 Tom과 동의합니다. 또한 Thread.Sleep 수행 중에 프로세스를 확인하려면 실행중인 프로세스를 확인하십시오. 다음과 같은 것 :

bool found = 0;
while (!found)
{
    foreach (Process clsProcess in Process.GetProcesses())
        if (clsProcess.Name == Name)
            found = true;

    Thread.CurrentThread.Sleep(1000);
}

당신은 확실 Start자식 프로세스 시작되기 전에 메소드가 리턴을? 나는 항상 Start자식 프로세스를 동시에 시작 한다는 인상을 받았습니다 .

자식 프로세스가 일종의 초기화를 마칠 때까지 기다리려면 프로세스 간 통신이 필요합니다. C # (. NET 2.0)에서 Windows 용 프로세스 간 통신을 참조하세요 .


@ChrisG의 아이디어를 조금 확장하려면 process.MainWindowHandle을 사용하고 창 메시지 루프가 응답하는지 확인하십시오. 이 Win32 api : SendMessageTimeout을 p / invoke 사용하십시오 . 해당 링크에서 :

함수가 성공하면 반환 값은 0이 아닙니다. SendMessageTimeout은 HWND_BROADCAST를 사용하는 경우 개별 창 시간 초과에 대한 정보를 제공하지 않습니다.

함수가 실패하거나 시간이 초과되면 반환 값은 0입니다. 확장 된 오류 정보를 얻으려면 GetLastError를 호출합니다. GetLastError가 ERROR_TIMEOUT을 반환하면 함수가 시간 초과 된 것입니다.


여기에 System.Threading.Timer. 그 목적을 위해 조금 더.

    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();
    }

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;
    }

}

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 ...

참고 URL : https://stackoverflow.com/questions/6390030/c-sharp-making-a-process-start-wait-until-the-process-has-start-up

반응형