void ProcessList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
        {
            HookedProcessInfo info = m_processes[e.ItemIndex];

            e.Item = new ListViewItem(info.pid.ToString());
            e.Item.SubItems.Add(info.name.ToString());
            e.Item.SubItems.Add(info.hooked.ToString());
        }
        private void RefreshTimer_Tick(object sender, EventArgs e)
        {
            int needed = 0;
            while (!EnumProcesses(m_pidList, sizeof(int) * m_pidList.Length, out needed))
            {
                m_pidList = new int[needed / sizeof(int) + 64];
            }

            bool changed = false;
            int count = needed / sizeof(int);

            for (int i = 0; i < count; ++i)
            {
                int pid = m_pidList[i];
                if (m_pids.ContainsKey(pid))
                    continue;

                m_pids[pid] = null;

                IntPtr handle = IntPtr.Zero;
                try
                {
                    handle = OpenProcess(ProcessAccess.QueryInformation, false, pid);
                    if (handle != IntPtr.Zero)
                    {
                        int capacity = 256;
                        StringBuilder name = new StringBuilder(capacity);

                        if (0 != GetProcessImageFileName(handle, name, ref capacity))
                        {
                            string nameString = name.ToString();
                            if (-1 != nameString.IndexOf("devenv", StringComparison.InvariantCulture))
                            {
                                HookedProcessInfo info = new HookedProcessInfo();
                                info.pid = pid;
                                info.name = nameString;
                                info.hooked = true;
                                m_pids[pid] = info;
                                Hook(pid);
                                changed = true;
                            }
                        }
                    }
                }
                catch (Exception)
                {
                }
                finally
                {
                    if (handle != IntPtr.Zero)
                        CloseHandle(handle);
                }
            }

            foreach (int oldPid in new List<int>(m_pids.Keys))
            {
                bool found = false;
                for (int i = 0; i < count; ++i)
                {
                    int pid = m_pidList[i];
                    if (oldPid == pid)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    m_pids.Remove(oldPid);
                    changed = true;
                }
            }

            if (!changed)
                return;

            m_processes.Clear();
            foreach (KeyValuePair<int, HookedProcessInfo> kv in m_pids)
            {
                if (null != kv.Value)
                    m_processes.Add(kv.Value);
            }
            ProcessList.VirtualListSize = m_processes.Count;
            ProcessList.Refresh();
        }
        private void RefreshTimer_Tick(object sender, EventArgs e)
        {
            int needed = 0;

            while (!EnumProcesses(m_pidList, sizeof(int) * m_pidList.Length, out needed))
            {
                m_pidList = new int[needed / sizeof(int) + 64];
            }

            bool changed = false;
            int  count   = needed / sizeof(int);

            for (int i = 0; i < count; ++i)
            {
                int pid = m_pidList[i];
                if (m_pids.ContainsKey(pid))
                {
                    continue;
                }

                m_pids[pid] = null;

                IntPtr handle = IntPtr.Zero;
                try
                {
                    handle = OpenProcess(ProcessAccess.QueryInformation, false, pid);
                    if (handle != IntPtr.Zero)
                    {
                        int           capacity = 256;
                        StringBuilder name     = new StringBuilder(capacity);

                        if (0 != GetProcessImageFileName(handle, name, ref capacity))
                        {
                            string nameString = name.ToString();
                            if (-1 != nameString.IndexOf("devenv", StringComparison.InvariantCulture))
                            {
                                HookedProcessInfo info = new HookedProcessInfo();
                                info.pid    = pid;
                                info.name   = nameString;
                                info.hooked = true;
                                m_pids[pid] = info;
                                Hook(pid);
                                changed = true;
                            }
                        }
                    }
                }
                catch (Exception)
                {
                }
                finally
                {
                    if (handle != IntPtr.Zero)
                    {
                        CloseHandle(handle);
                    }
                }
            }

            foreach (int oldPid in new List <int>(m_pids.Keys))
            {
                bool found = false;
                for (int i = 0; i < count; ++i)
                {
                    int pid = m_pidList[i];
                    if (oldPid == pid)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    m_pids.Remove(oldPid);
                    changed = true;
                }
            }

            if (!changed)
            {
                return;
            }

            m_processes.Clear();
            foreach (KeyValuePair <int, HookedProcessInfo> kv in m_pids)
            {
                if (null != kv.Value)
                {
                    m_processes.Add(kv.Value);
                }
            }
            ProcessList.VirtualListSize = m_processes.Count;
            ProcessList.Refresh();
        }