流程启动时启动的流程ID

时间:2015-05-25 02:33:23

标签: c# winforms process system.diagnostics

我正在尝试按进程ID终止进程,我在进程启动时保存该进程ID。但是,当我尝试从后面的代码中删除进程时,我捕获的进程ID不存在。

这是以下代码,用于启动流程并捕获流程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();
        }

当我点击按钮终止该过程时,它会显示以下错误。

enter image description here

有没有办法解决这个问题。

在使用Palani Kumar代码后,我得到了以下异常。 enter image description here

表格看起来像这样

enter image description here

2 个答案:

答案 0 :(得分:1)

我不知道你为什么宣布pid为List<int>并清除按钮点击事件列表(pids.Clear();)。无论如何,下面的内容也适用于创建多个进程。

编辑:至今与Amrit讨论过。 Windows 8 为连接相同域的mstsc创建子流程。所以我稍微修改了我的代码。

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

    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 :(得分:0)

我不确定你为什么要举行

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

而不是直接使用Process列表

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

了解Process对象具有安全描述符非常重要。每个人都可以看到过程的存在,有人可以打开阅读信息的过程或等待过程的结束。开放杀人需要更多权利。 CreateProcess返回的进程句柄具有完全权限。因此,持有用于创建流程的Process对象可以为您提供这样的优势。

我建议您在调用HasExited方法之前另外测试Process对象的Kill()属性。如果用户将关闭该进程,可以考虑另外使用OnExited(请参阅here)来删除该进程。在从Close()列表中删除之前,您应该以任何方式调用Process对象的processes方法,并考虑使用CloseMainWindow()代替Kill()方法。您应该只测试两种方法(CloseMainWindow()Kill()),并根据您的情况选择最佳方法。