Windows how to get the process group of a process that is already running?

前端 未结 2 1820
独厮守ぢ
独厮守ぢ 2020-12-21 08:24

I have a WPF application that starts a new process using Process.Start(ProcessStartInfo info).

How do I get the group process ID of the process so that

相关标签:
2条回答
  • 2020-12-21 08:47

    The documentation for GenerateConsoleCtrlEvent states (emphasis mine):

    The identifier of the process group to receive the signal. A process group is created when the CREATE_NEW_PROCESS_GROUP flag is specified in a call to the CreateProcess function. The process identifier of the new process is also the process group identifier of a new process group.

    So if your processes are in a group, the WPF application's PID should be the group ID.

    0 讨论(0)
  • 2020-12-21 09:11

    Rather than using GenerateConsoleCtrlEvent, here is how I have found to send CTRL-C to a process. FYI, in this case, I didn't ever need to find the group process ID.

    using System;
    using System.Diagnostics;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    public class ConsoleAppManager
    {
        private readonly string appName;
        private readonly Process process = new Process();
        private readonly object theLock = new object();
        private SynchronizationContext context;
        private string pendingWriteData;
    
        public ConsoleAppManager(string appName)
        {
            this.appName = appName;
    
            this.process.StartInfo.FileName = this.appName;
            this.process.StartInfo.RedirectStandardError = true;
            this.process.StartInfo.StandardErrorEncoding = Encoding.UTF8;
    
            this.process.StartInfo.RedirectStandardInput = true;
            this.process.StartInfo.RedirectStandardOutput = true;
            this.process.EnableRaisingEvents = true;
            this.process.StartInfo.CreateNoWindow = true;
    
            this.process.StartInfo.UseShellExecute = false;
    
            this.process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
    
            this.process.Exited += this.ProcessOnExited;
        }
    
        public event EventHandler<string> ErrorTextReceived;
        public event EventHandler ProcessExited;
        public event EventHandler<string> StandartTextReceived;
    
        public int ExitCode
        {
            get { return this.process.ExitCode; }
        }
    
        public bool Running
        {
            get; private set;
        }
    
        public void ExecuteAsync(params string[] args)
        {
            if (this.Running)
            {
                throw new InvalidOperationException(
                    "Process is still Running. Please wait for the process to complete.");
            }
    
            string arguments = string.Join(" ", args);
    
            this.process.StartInfo.Arguments = arguments;
    
            this.context = SynchronizationContext.Current;
    
            this.process.Start();
            this.Running = true;
    
            new Task(this.ReadOutputAsync).Start();
            new Task(this.WriteInputTask).Start();
            new Task(this.ReadOutputErrorAsync).Start();
        }
    
        public void Write(string data)
        {
            if (data == null)
            {
                return;
            }
    
            lock (this.theLock)
            {
                this.pendingWriteData = data;
            }
        }
    
        public void WriteLine(string data)
        {
            this.Write(data + Environment.NewLine);
        }
    
        protected virtual void OnErrorTextReceived(string e)
        {
            EventHandler<string> handler = this.ErrorTextReceived;
    
            if (handler != null)
            {
                if (this.context != null)
                {
                    this.context.Post(delegate { handler(this, e); }, null);
                }
                else
                {
                    handler(this, e);
                }
            }
        }
    
        protected virtual void OnProcessExited()
        {
            EventHandler handler = this.ProcessExited;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }
    
        protected virtual void OnStandartTextReceived(string e)
        {
            EventHandler<string> handler = this.StandartTextReceived;
    
            if (handler != null)
            {
                if (this.context != null)
                {
                    this.context.Post(delegate { handler(this, e); }, null);
                }
                else
                {
                    handler(this, e);
                }
            }
        }
    
        private void ProcessOnExited(object sender, EventArgs eventArgs)
        {
            this.OnProcessExited();
        }
    
        private async void ReadOutputAsync()
        {
            var standart = new StringBuilder();
            var buff = new char[1024];
            int length;
    
            while (this.process.HasExited == false)
            {
                standart.Clear();
    
                length = await this.process.StandardOutput.ReadAsync(buff, 0, buff.Length);
                standart.Append(buff.SubArray(0, length));
                this.OnStandartTextReceived(standart.ToString());
                Thread.Sleep(1);
            }
    
            this.Running = false;
        }
    
        private async void ReadOutputErrorAsync()
        {
            var sb = new StringBuilder();
    
            do
            {
                sb.Clear();
                var buff = new char[1024];
                int length = await this.process.StandardError.ReadAsync(buff, 0, buff.Length);
                sb.Append(buff.SubArray(0, length));
                this.OnErrorTextReceived(sb.ToString());
                Thread.Sleep(1);
            }
            while (this.process.HasExited == false);
        }
    
        private async void WriteInputTask()
        {
            while (this.process.HasExited == false)
            {
                Thread.Sleep(1);
    
                if (this.pendingWriteData != null)
                {
                    await this.process.StandardInput.WriteLineAsync(this.pendingWriteData);
                    await this.process.StandardInput.FlushAsync();
    
                    lock (this.theLock)
                    {
                        this.pendingWriteData = null;
                    }
                }
            }
        }
    }
    

    Then, in actually running the process and sending the CTRL-C in my main app:

                DateTime maxStartDateTime = //... some date time;
                DateTime maxEndDateTime = //... some later date time
                var duration = maxEndDateTime.Subtract(maxStartDateTime);
                ConsoleAppManager appManager = new ConsoleAppManager("myapp.exe");
                string[] args = new string[] { "args here" };
                appManager.ExecuteAsync(args);
                await Task.Delay(Convert.ToInt32(duration.TotalSeconds * 1000) + 20000);
    
                if (appManager.Running)
                {
                    // If stilll running, send CTRL-C
                    appManager.Write("\x3");
                }
    

    For details, please see Redirecting standard input of console application

    0 讨论(0)
提交回复
热议问题