Process ID of the process started by starting the process

I am trying to kill a process by the process id which I save when the process starts. But the process id I am collecting does not exist when I try to kill the process from code.

Below is the code to start a process and get the process ID.

private List<int> pids = new List<int>();
public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            pids.Clear();
            Process myprocess= new Process();

            myprocess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\cmdkey.exe");
            myprocess.StartInfo.Arguments = "C:\\rdp\\RemoteIn.rdp";
            myprocess.Start();
            pids.Add(myprocess.Id);          
        }

        private void terminateAll()
        {
            //foreach (var p in pids) p.Kill();

            foreach (var i in pids)
            {
                Process p = Process.GetProcessById(i);
                p.Kill();

            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            terminateAll();
        }

      

When I click the button to complete the process, the following error appears.

enter image description here

Is there any way to fix this.

After using Palani Kumar's code, I am getting below the exception. enter image description here

The form looks like this

enter image description here

+3


source to share


2 answers


I don't know why you declared the pids as List<int>

and cleared the list ( pids.Clear();

) on the button click event. Anyway, below will work for creating multiple processes too.

EDIT: As discussed previously with Amrit. Windows 8 create subprocesses for mstsc with a single domain connection. So I changed my code a bit.

    private void button1_Click(object sender, EventArgs e)
    {
        //pids.Clear();
        Process myprocess = new Process();

        myprocess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\syswow64\mstsc.exe");
        myprocess.StartInfo.Arguments = "C:\\rdp\\RemoteIn.rdp";
        myprocess.Start();
        Thread.Sleep(100);
        /* Edit */
        Process proc = Process.GetProcessesByName("mstsc").FirstOrDefault(x => !pids.Any(y => y == x.Id));
        if(proc != null)
        {
           pids.Add(proc.Id);
        }
    }

      



and

    private void terminateAll()
    {
        foreach (var i in pids)
        {
            try
            {
                Process p = Process.GetProcessById(i);
                p.Kill();
            }
            catch (Exception ex)
            {
                //throw exception if we close the mstsc manually
            }
        }
    }

      

+1


source


I'm not sure why you keep

private List<int> pids = new List<int>();

      

instead of just using the list Process

directly



private List<Process> processes = new List<Process>();

      

It is important to understand that the Process object has a security descriptor. Everyone can see the existence of the process, someone can open the process to read information or to wait for the process to complete. More rights are required to kill. The process handler returned CreateProcess

has full permissions. Therefore, keeping the object Process

used to create the process gives you such advantages.

I would recommend that you additionally check the HasExited

object property Process

before calling the method Kill()

. Can also be used OnExited

(see here ) to delete a process if it is closed by the user. You have to call the method of the Close()

object in Process

some way before removing from the list processes

and use CloseMainWindow()

instead of the method Kill()

. You just have to check both methods ( CloseMainWindow()

and Kill()

) and choose the best for your case.

0


source







All Articles