コード例 #1
0
ファイル: ProcessHelper.cs プロジェクト: asm2025/essentialMix
        public static RunOutput RunAndGetOutput([NotNull] string execName, string arguments, RunSettingsBase settings, WaitHandle awaitableHandle)
        {
            settings ??= RunSettingsBase.Default;
            settings.RedirectOutput = true;
            settings.RedirectError  = true;

            RunOutput output = new RunOutput();

            using (Process process = CreateForRun(execName, arguments, settings))
            {
                bool processReallyExited = false;

                process.Exited += (sender, _) =>
                {
                    Process p = (Process)sender;

                    if (p.IsAssociated())
                    {
                        try
                        {
                            output.ExitTime = p.ExitTime;
                            output.ExitCode = p.ExitCode;
                        }
                        catch
                        {
                            // ignored
                        }
                    }

                    processReallyExited = true;
                    settings.OnExit?.Invoke(execName, output.ExitTime, output.ExitCode);
                };

                try
                {
                    bool result = process.Start();
                    if (!result)
                    {
                        return(null);
                    }
                    if (!settings.JobHandle.IsInvalidHandle())
                    {
                        ProcessJob.AddProcess(settings.JobHandle, process);
                    }
                    output.StartTime = process.StartTime;
                    settings.OnStart?.Invoke(execName, output.StartTime);

                    AsyncStreamReader outputReader = new AsyncStreamReader(process, process.StandardOutput.BaseStream, data =>
                    {
                        if (data == null)
                        {
                            return;
                        }
                        output.Output.Append(data);
                        output.OutputBuilder.Append(data);
                    }, process.StandardOutput.CurrentEncoding);
                    outputReader.BeginRead();

                    AsyncStreamReader errorReader = new AsyncStreamReader(process, process.StandardError.BaseStream, data =>
                    {
                        if (data == null)
                        {
                            return;
                        }
                        output.Error.Append(data);
                        output.OutputBuilder.Append(data);
                    }, process.StandardOutput.CurrentEncoding);
                    errorReader.BeginRead();

                    if (!awaitableHandle.IsAwaitable())
                    {
                        process.WaitForExit();
                        return(output);
                    }

                    SafeWaitHandle   waitHandle           = null;
                    ManualResetEvent processFinishedEvent = null;

                    try
                    {
                        waitHandle = new SafeWaitHandle(process.Handle, false);
                        if (!waitHandle.IsAwaitable())
                        {
                            return(null);
                        }
                        processFinishedEvent = new ManualResetEvent(false)
                        {
                            SafeWaitHandle = waitHandle
                        };
                        if (!awaitableHandle.IsAwaitable())
                        {
                            return(null);
                        }

                        WaitHandle[] waitHandles =
                        {
                            processFinishedEvent,
                            awaitableHandle
                        };

                        int ndx = waitHandles.WaitAny();
                        if (ndx != 0)
                        {
                            return(null);
                        }

                        if (!processReallyExited && process.IsAwaitable())
                        {
                            if (!process.WaitForExit(TimeSpanHelper.HALF))
                            {
                                ndx = -1;
                            }
                        }

                        process.Die();
                        return(ndx != 0 ? null : output);
                    }
                    finally
                    {
                        processFinishedEvent?.Close();
                        ObjectHelper.Dispose(ref processFinishedEvent);
                        waitHandle?.Close();
                        ObjectHelper.Dispose(ref waitHandle);
                    }
                }
                catch (Win32Exception e)
                {
                    throw new InvalidOperationException(e.CollectMessages(), e);
                }
            }
        }
コード例 #2
0
ファイル: ProcessHelper.cs プロジェクト: asm2025/essentialMix
        public static Task <bool> WaitForProcessExitAsync(int pid, WaitHandle awaitableHandle)
        {
            if (pid == Win32.INVALID_HANDLE_VALUE.ToInt32())
            {
                return(Task.FromResult(false));
            }

            SafeWaitHandle   waitHandle           = null;
            ManualResetEvent processFinishedEvent = null;

            try
            {
                Process process = Process.GetProcessById(pid);
                if (!process.IsAwaitable())
                {
                    return(Task.FromResult(false));
                }

                if (!awaitableHandle.IsAwaitable())
                {
                    process.WaitForExit();
                    return(Task.FromResult(true));
                }

                waitHandle = new SafeWaitHandle(process.Handle, false);
                if (!waitHandle.IsAwaitable())
                {
                    return(Task.FromResult(false));
                }
                processFinishedEvent = new ManualResetEvent(false)
                {
                    SafeWaitHandle = waitHandle
                };
                if (!awaitableHandle.IsAwaitable())
                {
                    return(Task.FromResult(false));
                }

                WaitHandle[] waitHandles =
                {
                    processFinishedEvent,
                    awaitableHandle
                };

                bool processReallyExited = false;
                process.Exited += (_, _) => processReallyExited = true;

                int ndx = waitHandles.WaitAny();
                if (ndx != 0)
                {
                    return(Task.FromResult(false));
                }

                if (!processReallyExited && process.IsAwaitable())
                {
                    if (!process.WaitForExit(TimeSpanHelper.HALF))
                    {
                        ndx = -1;
                    }
                }

                return(Task.FromResult(ndx == 0));
            }
            finally
            {
                processFinishedEvent?.Close();
                ObjectHelper.Dispose(ref processFinishedEvent);
                waitHandle?.Close();
                ObjectHelper.Dispose(ref waitHandle);
            }
        }
コード例 #3
0
ファイル: ProcessHelper.cs プロジェクト: asm2025/essentialMix
        public static bool ShellExecAndWaitFor([NotNull] string fileName, string arguments, ShellSettings settings, WaitHandle awaitableHandle)
        {
            fileName = fileName.Trim();
            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException(nameof(fileName));
            }
            settings ??= ShellSettings.Default;

            SHELLEXECUTEINFO info = GetShellExecuteInfo(fileName, arguments, settings);

            using (Process process = InternalShellExec(info))
            {
                if (process == null)
                {
                    return(false);
                }
                if (!settings.JobHandle.IsInvalidHandle())
                {
                    ProcessJob.AddProcess(settings.JobHandle, process);
                }

                if (!awaitableHandle.IsAwaitable())
                {
                    process.WaitForExit();
                    return(true);
                }

                bool processReallyExited = false;
                process.Exited += (_, _) => processReallyExited = true;

                SafeWaitHandle   waitHandle           = null;
                ManualResetEvent processFinishedEvent = null;

                try
                {
                    waitHandle = new SafeWaitHandle(process.Handle, false);
                    if (!waitHandle.IsAwaitable())
                    {
                        return(false);
                    }
                    processFinishedEvent = new ManualResetEvent(false)
                    {
                        SafeWaitHandle = waitHandle
                    };
                    if (!awaitableHandle.IsAwaitable())
                    {
                        return(false);
                    }

                    WaitHandle[] waitHandles =
                    {
                        processFinishedEvent,
                        awaitableHandle
                    };

                    int ndx = waitHandles.WaitAny();
                    if (ndx != 0)
                    {
                        return(false);
                    }

                    if (!processReallyExited && process.IsAwaitable())
                    {
                        if (!process.WaitForExit(TimeSpanHelper.HALF))
                        {
                            ndx = -1;
                        }
                    }

                    process.Die();
                    return(ndx == 0);
                }
                finally
                {
                    processFinishedEvent?.Close();
                    ObjectHelper.Dispose(ref processFinishedEvent);
                    waitHandle?.Close();
                    ObjectHelper.Dispose(ref waitHandle);
                }
            }
        }