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.
Is there any way to fix this.
After using Palani Kumar's code, I am getting below the exception.
The form looks like this
source to share
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
}
}
}
source to share
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.
source to share