【文章标题】: 查看进程运行时间
【文章作者】: 未秋叶已落
【作者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
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: