做一个任务管理器程序,,程序上有一个列表框 显示系统所有进程,,定时更新进程,但是 更新列表框的算法有问题.void CProcessDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(nIDEvent==0)
{ UpdateProcess();
//添加 新创建的进程
for(VPROTYPE::iterator it=vProInfo.begin();it!=vProInfo.end();it++)
{
int nItem=m_list.GetItemCount();
bool bFind=false;
for(int i=0;i<nItem;i++)
{
if(m_list.GetItemData(i)==it->th32ProcessID)
{
bFind=true;
break;
}
}
if(!bFind)
{
int index=m_list.InsertItem(nItem,it->szExeFile); 
m_list.SetItemData(nItem,it->th32ProcessID);
CString str;
str.Format(L"%d,%d",index,it->th32ProcessID);
m_list.SetItemText(nItem, 1, str);
}
}
//移除已经销毁的进程 
for(int nItem=0;nItem<m_list.GetItemCount();nItem++)
{
bool bFind=false;
for(VPROTYPE::iterator it=vProInfo.begin();it!=vProInfo.end();it++)
{
if(m_list.GetItemData(nItem)==it->th32ProcessID)
{
bFind=true;
break;
}
}
if(!bFind)
{
//MessageBox(m_list.GetItemText(nItem,0));
//移除 已经销毁的进程 BUG就在这里,,是不是我的算法有问题?? 不能移除 已经销毁的进程了
}
}
//NtQuerySystemInformation(
/* int i=0;
for(int nItem=0;nItem<m_list.GetItemCount();nItem++)
{
CString str;
str.Format(L"%d",m_list.GetItemData(nItem));
MessageBox(str);
}*/
}
CDialog::OnTimer(nIDEvent);
}
void CProcessDlg::UpdateProcess(void)
{
try{         
        HANDLE hSnapshot ;
        //获得某一时刻系统的进程、堆(heap)、模块(module)或线程的快照信息
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (hSnapshot != NULL){
            PROCESSENTRY32 processList;            
  processList.dwSize = sizeof(PROCESSENTRY32);
  for(BOOL bReturnValue=Process32First(hSnapshot, &processList);
  bReturnValue;bReturnValue = Process32Next(hSnapshot,&processList)){
   vProInfo.push_back(processList);
  }
            CloseHandle(hSnapshot);
        }
    }
    catch (...){}
}

解决方案 »

  1.   

    void CCProcessDlgDlg::UpdateProcess()
    {
        try{  
    vProInfo.clear();//每次更新前要先把vector清空
            HANDLE hSnapshot ;
            //获得某一时刻系统的进程、堆(heap)、模块(module)或线程的快照信息
            hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
            if (hSnapshot != NULL){
                PROCESSENTRY32 processList;            
    processList.dwSize = sizeof(PROCESSENTRY32);
    for(BOOL bReturnValue=Process32First(hSnapshot, &processList);
    bReturnValue;bReturnValue = Process32Next(hSnapshot,&processList)){
    vProInfo.push_back(processList);
    }
                CloseHandle(hSnapshot);
            }
        }
        catch (...){}
    }
      

  2.   

    真是一言惊醒梦中人,,呵呵 找了1天 这么1个BUG就没找到
    不识庐山真面目 只缘身在此山中 啊
      

  3.   

      for(int nItem=0;nItem<m_list.GetItemCount();nItem++)
            {
    }不要在for循环里删除,因为删除一项后,m_list中的结构就变了,再使用nItem就可能导致
    访问越界
      

  4.   

    楼上说的没错,可以先保存要删除的item的索引,等循环结束后,再删除