首页
社区
课程
招聘
查看进程运行时间
发表于: 2009-5-12 02:27 11937

查看进程运行时间

2009-5-12 02:27
11937
【文章标题】: 查看进程运行时间
【文章作者】: 未秋叶已落
【作者QQ号】: 307727654
【编写语言】: C++
【作者声明】: 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
--------------------------------------------------------------------------------
【详细过程】
  起源:天天帮女友挂QQ升级,两个小时后就关掉。每次都不知道到底挂了多长时间,于是打算写个查看进程运行多长时间的程序。
  代码简单,贴出来只是为了让大家复制粘贴用,代码写的乱,见谅。


  #include <windows.h>
  #include "resource.h"
  #include <commctrl.h>
  #pragma comment(lib,"comctl32.lib")
  #include <Tlhelp32.h>
  #include <Psapi.h>
  #pragma comment(lib,"Psapi.lib")
  
  HWND hList;
  
  //为本进程提升权限
  void EnablePrivilege()
  {
          HANDLE hToken;
          TOKEN_PRIVILEGES tkp;
          OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken);
          LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid);
          //一定要设置成SE_DEBUG_NAME,不然无法查看系统进程信息
          tkp.PrivilegeCount=1;
          tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
          AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0);
  }
  
  
  void InsertProcessInfo()
  {
          SendMessage(hList,LVM_DELETEALLITEMS,0,0);//先清除所有的列表项
          HANDLE hProcess=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
          PROCESSENTRY32 lppe;
          lppe.dwSize=sizeof(lppe);
          BOOL bProcess=Process32First(hProcess,&lppe);
          while(bProcess)
          {
                  //显示第一列内容
                  LV_ITEM lvi;
                  lvi.mask=LVIF_TEXT;
                  lvi.iItem=0;
                  lvi.iSubItem=0;
                  lvi.pszText=lppe.szExeFile;
                  SendMessage(hList,LVM_INSERTITEM,0,(LPARAM)&lvi);
  
                  //显示第二列内容
                  char PIDbuf[10]={0};
                  wsprintf(PIDbuf,"%d",lppe.th32ProcessID);
                  lvi.mask=LVIF_TEXT;
                  lvi.iSubItem=1;
                  lvi.pszText=PIDbuf;
                  SendMessage(hList,LVM_SETITEM,0,(LPARAM)&lvi);
  
                  //显示第三列内容
                  HANDLE hqq=OpenProcess(PROCESS_ALL_ACCESS,true,lppe.th32ProcessID);        //打开进程
                  FILETIME
                                  CreationTime,
                                  ExitTime,
                                  KernelTime,
                                  UserTime,
                                  LocalFileTime,
                                  Temp;
                  GetProcessTimes(hqq,&CreationTime,&ExitTime,&KernelTime,&UserTime);        //获取进程时间
                  SYSTEMTIME
                                          ProcCreatTime,
                                          LocalTime;
                  FileTimeToSystemTime(&CreationTime,&ProcCreatTime);//将FILETIME转换成SYSTEMTIME
                  char TimeBuf[512]={0};
                  if((ProcCreatTime.wHour+8)>=24)
                          ProcCreatTime.wDay+=1;       
                  wsprintf(TimeBuf,"%d-%02d-%02d %02d:%02d:%02d",ProcCreatTime.wYear,ProcCreatTime.wMonth,ProcCreatTime.wDay,(ProcCreatTime.wHour+8)%24,ProcCreatTime.wMinute,ProcCreatTime.wSecond);
                  //上面的功能是获取进行创建的时间
  
                  //如果进程名称是System或[System Process]则不显示时间
                  if(strcmp(lppe.szExeFile,"System")==0 || strcmp(lppe.szExeFile,"[System Process]")==0)
                          RtlZeroMemory(TimeBuf,sizeof(TimeBuf));
  
                  lvi.mask=LVIF_TEXT;
                  lvi.iSubItem=2;
                  lvi.pszText=TimeBuf;
                  SendMessage(hList,LVM_SETITEM,0,(LPARAM)&lvi);
  
                  //第四列内容开始
                  GetSystemTime(&LocalTime);                //获取系统时间
                  SystemTimeToFileTime(&LocalTime,&LocalFileTime);
                  Temp.dwLowDateTime=LocalFileTime.dwLowDateTime-CreationTime.dwLowDateTime;
                  Temp.dwHighDateTime=LocalFileTime.dwHighDateTime-CreationTime.dwHighDateTime;
                  FileTimeToSystemTime(&Temp,&ProcCreatTime);
                  wsprintf(TimeBuf,"%02d:%02d:%02d",ProcCreatTime.wHour,ProcCreatTime.wMinute,ProcCreatTime.wSecond);//abs(LocalTime.wSecond-ProcCreatTime.wSecond));时间不准
                  //上面的功能是获取进行运行了多长时间
  
                  //如果进程名称是System或[System Process]则不显示时间
                  if(strcmp(lppe.szExeFile,"System")==0 || strcmp(lppe.szExeFile,"[System Process]")==0)
                          RtlZeroMemory(TimeBuf,sizeof(TimeBuf));
  
                  lvi.mask=LVIF_TEXT;
                  lvi.iSubItem=3;
                  lvi.pszText=TimeBuf;
                  SendMessage(hList,LVM_SETITEM,0,(LPARAM)&lvi);
  
                  //第五列内容开始
                  EnablePrivilege();//为进程提权
                  HANDLE hP=OpenProcess(PROCESS_ALL_ACCESS,false,lppe.th32ProcessID);
                  char PathBuf[MAX_PATH]={0};
                  GetModuleFileNameEx(hP,NULL,PathBuf,sizeof(PathBuf));
                  //上面的功能是获取进程路径信息
                  lvi.mask=LVIF_TEXT;
                  lvi.iSubItem=4;
                  lvi.pszText=PathBuf;
                  SendMessage(hList,LVM_SETITEM,0,(LPARAM)&lvi);
  
                  //查找下一进程
                  bProcess=Process32Next(hProcess,&lppe);
          }
          CloseHandle(hProcess);//不要忘了关闭进程句柄
  }
  
  void InsertColumn(HWND hList)
  {
          LV_COLUMN lvc;
          lvc.mask=LVCF_TEXT | LVCF_WIDTH;
          lvc.pszText="进程名称";
          lvc.cx=120;
          SendMessage(hList,LVM_INSERTCOLUMN,0,(LPARAM)&lvc);
  
          lvc.pszText="PID";
          lvc.cx=40;
          SendMessage(hList,LVM_INSERTCOLUMN,1,(LPARAM)&lvc);
  
          lvc.pszText="创建时间";
          lvc.cx=130;
          SendMessage(hList,LVM_INSERTCOLUMN,2,(LPARAM)&lvc);
  
          lvc.pszText="已运行时间";
          lvc.cx=80;
          SendMessage(hList,LVM_INSERTCOLUMN,3,(LPARAM)&lvc);
  
          lvc.pszText="进程路径";
          lvc.cx=400;
          SendMessage(hList,LVM_INSERTCOLUMN,4,(LPARAM)&lvc);
  }
  
  void SetTileTime(HWND hwnd)
  {
          SYSTEMTIME LocalTime;
          char time[128]={0};       
          GetSystemTime(&LocalTime);
          if(LocalTime.wHour+8>=24)        //系统时间为格林威治时间,所以显示中国时间要加8小时(8个时区)
                  LocalTime.wDay+=1;        //但系统日期还是8小时之前的日期,如12日23:59后的00:00还会显示12日
                                          //所以通过加上8小时之后判断如果超过24小时,则为下一天的日期
          wsprintf(time,"进程信息查看器   %d-%02d-%02d %02d:%02d:%02d",LocalTime.wYear,LocalTime.wMonth,LocalTime.wDay,(LocalTime.wHour+8)%24,LocalTime.wMinute,LocalTime.wSecond);
          SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)time);
  }
  
  LRESULT CALLBACK WindowProc(
    HWND hwnd,      // handle to window
    UINT uMsg,      // message identifier
    WPARAM wParam,  // first message parameter
    LPARAM lParam   // second message parameter
  )
  {
          HINSTANCE hInst;
  
          switch(uMsg)
          {
          case WM_TIMER:
                  SetTileTime(hwnd);//为标题栏添加时间
                  InsertProcessInfo();//在列表中添加进程信息
                  break;
          case WM_CLOSE:
                  ExitProcess(NULL);
                  break;
          case WM_CREATE:
                  SetTileTime(hwnd);//为标题栏添加时间
                  SetTimer(hwnd,1,1000,NULL);        //设置一个Timer来动态显示时间和计算时间
                  InitCommonControls();
                  hInst=((LPCREATESTRUCT)lParam)->hInstance;
                  //加入列表控件窗口
                  hList=CreateWindowEx(NULL,TEXT("SysListView32"),NULL,LVS_REPORT | WS_CHILD | WS_VISIBLE,0,0,0,0,hwnd,NULL,hInst,NULL);
                  //必须加上LVS_REPORT
                  InsertColumn(hList);//添加列
                  InsertProcessInfo();//在列表中添加进程信息
  
                  //设置黑底白字
                  SendMessage(hList, LVM_SETTEXTCOLOR, 0, RGB(255, 255, 255));
                  SendMessage(hList, LVM_SETBKCOLOR, 0, RGB(0, 0, 0));
                  SendMessage(hList, LVM_SETTEXTBKCOLOR, 0, RGB(0, 0, 0));
                  break;
          case WM_SIZE:
                  MoveWindow(hList,0,0,LOWORD(lParam),HIWORD(lParam),TRUE);        //必须加上这句,不然列表不显示
                  break;
          default:
                  return DefWindowProc(hwnd,uMsg,wParam,lParam);
          }
          return 0;
  }
  
  int WINAPI WinMain(
    HINSTANCE hInstance,      // handle to current instance
    HINSTANCE hPrevInstance,  // handle to previous instance
    LPSTR lpCmdLine,          // command line
    int nCmdShow              // show state
  )
  {
          MSG msg;
          WNDCLASSEX wnd;
  
          wnd.cbClsExtra=0;
          wnd.cbSize=sizeof(WNDCLASSEX);
          wnd.cbWndExtra=0;
          wnd.hbrBackground=(HBRUSH)(COLOR_3DFACE+1);
          wnd.hCursor=LoadCursor(NULL,IDC_ARROW);
          wnd.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON));
          wnd.hIconSm=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON));
          wnd.hInstance=hInstance;
          wnd.lpfnWndProc=WindowProc;
          wnd.lpszClassName="aa";
          wnd.lpszMenuName=NULL;
          wnd.style=CS_VREDRAW | CS_HREDRAW;
  
          RegisterClassEx(&wnd);
          HWND hWindow=CreateWindowEx(NULL,"aa","进程信息查看器",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,850,550,NULL,NULL,hInstance,NULL);
          ShowWindow(hWindow,SW_SHOWNORMAL);
  
          while(GetMessage(&msg,NULL,0,0))
          {
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
          }
          return msg.wParam;
  }
  
--------------------------------------------------------------------------------
【经验总结】
  从图中可以看到,360进程地址没有获取成功,如何更正,待牛人给个正解。
  8楼11楼已给正解,
  8楼11楼任意一种方法都可以。但8楼更方便。向两楼学习了。
--------------------------------------------------------------------------------
进程信息查看.rar
                                                       2009年05月12日 2:25:09

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 442
活跃值: (43)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
沙发

我不学习,我只抄袭
2009-5-12 06:28
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
360问马甲
2009-5-12 07:34
0
雪    币: 10968
活跃值: (158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
偶是小菜,学习一下。
2009-5-12 12:35
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
5
HANDLE hP=OpenProcess(PROCESS_ALL_ACCESS,false,lppe.th32ProcessID);

这和360没什么关系,和楼主的编程素养有关系。
2009-5-12 14:21
0
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
用需要的最低权限打开。。。不要所有的都PROCESS_ALL_ACCESS
2009-5-12 14:36
0
雪    币: 122
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
似乎其它几种条件我都试过了,也都不行。。
2009-5-12 16:56
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
8
GetModuleFileNameEx仅需要PROCESS_VM_READ|PROCESS_QUERY_INFORMATION

看MSDN很重要
2009-5-12 17:07
0
雪    币: 122
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
2009-5-12 17:15
0
雪    币: 155
活跃值: (29)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
好长的代码

感觉有点累
2009-5-12 20:31
0
雪    币: 109
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
hProc := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
                                false,
                                pi^.dwProcessID);
if (hProc <> 0) then
begin
     EnumProcessModules(hProc, @hModule, sizeof(hModule), needed);
     GetModuleFileNameEx(hProc, hModule, @FilePath, sizeof(FilePath));
     ItemPath := String(FilePath);
end;
上传的附件:
2009-5-13 09:34
0
游客
登录 | 注册 方可回帖
返回
//