用多个TIMER分别定时取多个不同进程信息...
每个TIMER代码基本相同...但是却不能完全取打开进程..总会有一个或多个TIMER得不到信息...我把其中一个TIMER的代码贴出来...请大家帮我看看..问题出在哪
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) {
// 获取APPSERVER1进程信息 HMODULE hMods[1024];
// 模块结构体大小
DWORD cbNeeded;
HANDLE hProcess_One_Process;
HANDLE hProcess_All_Process; // 进程建立,退出,系统调用,用户调用时间
ULONGLONG createTime, exitTime, kernelTime, userTime;
BOOL bEmpt;
BOOL bGet_Fail;
DWORD dPid; // 进程内存结构
PROCESS_MEMORY_COUNTERS sTr_pMemory; // 进程结构
PROCESSENTRY32 sTr_Of_Process; // 系统内存结构
MEMORYSTATUSEX sTr_SysMemory;
sTr_SysMemory.dwLength = sizeof (sTr_SysMemory); String^ sFolder;
String^ sExeNameTemp;
String^ sExeName;
String^ sPath = label19->Text;
String^ sSlash = "\\";
String^ sFolderPath = "Program Files"; //进程所以文件夹及文件名
String^ sExeName2__ = "sqlservr.exe"; sTr_Of_Process.dwSize = sizeof(sTr_Of_Process); // 得到所有进程句柄
hProcess_All_Process = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
// 获取第一个进程结构
if (Process32First(hProcess_All_Process, &sTr_Of_Process)){
while ( Process32Next(hProcess_All_Process, &sTr_Of_Process))
{ // 获取进程PID
dPid = sTr_Of_Process.th32ProcessID;
// 打开进程
hProcess_One_Process = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE, dPid); // 进程路径
if (EnumProcessModules(hProcess_One_Process, hMods, sizeof(hMods), &cbNeeded))
{
WCHAR szModName[MAX_PATH]; // 句柄数
label17->Text = ((UInt32)sTr_Of_Process.cntUsage).ToString();
GetModuleFileNameEx( hProcess_One_Process, hMods[0], szModName, sizeof(szModName) ); // 路径
label19->Text = gcnew String(szModName);
}
else
{
label19->Text = "Unknow!";
}
// 取进程所在文件夹
sFolder = "";
sExeNameTemp = "";
sExeName = "";
sPath = label19->Text; // 斜杠字符数量
int iCountOfSlash = 0;
int i = 0;
for ( i; i < sPath->Length; i++){
if (String::Compare(sPath->Substring(i,1), sSlash) & (iCountOfSlash == 1) )
{
sFolder = sFolder + sPath->Substring(i,1);
}
else
{
if ( String::Compare(sPath->Substring(i,1), sSlash) == 0 )
iCountOfSlash++;
if ( iCountOfSlash >= 2 )
break;
}
}
// 程序名
int k = sPath->Length - 1;
int iCountOfSlash2 = 0;
for ( k; k > 0; k--){
if ( String::Compare(sPath->Substring(k,1), sSlash) )
{
sExeNameTemp = sExeNameTemp + sPath->Substring(k,1);
}
else
{
iCountOfSlash2 ++;
if ( iCountOfSlash >= 1 )
break;
}
}
k = sExeNameTemp->Length - 1;
for ( k; k >= 0; k--){
sExeName = sExeName + sExeNameTemp->Substring(k,1);
sExeName = sExeName->ToLower();
}
// 取APPSERVER1句柄,PID
if ( (String::Compare(sFolder, sFolderPath, true) == 0) & (String::Compare(sExeName, sExeName2__ ,true) ==0) ){ // 内存占用
bGet_Fail = GetProcessMemoryInfo(hProcess_One_Process, &sTr_pMemory, sizeof(sTr_pMemory));
label12->Text = ( (UInt32)sTr_pMemory.WorkingSetSize / 1024 ).ToString() + " K"; // 获取进程内存使用峰值
label13->Text = ( (UInt32)sTr_pMemory.PeakWorkingSetSize / 1024 ).ToString() + " K"; // 路径中文件夹名
label7->Text = sFolder;
// PID
label6->Text = ((UInt32)dPid).ToString(); // 进程名
label4->Text = gcnew String(sTr_Of_Process.szExeFile); // 线程数
label16->Text = ((UInt32)sTr_Of_Process.cntThreads).ToString(); // 句柄数
//label17->Text = ((UInt32)sTr_Of_Process.dwFlags).ToString();
// 获取进程CPU时间
::GetProcessTimes(hProcess_One_Process, (LPFILETIME)&createTime, (LPFILETIME)&exitTime, (LPFILETIME)&kernelTime, (LPFILETIME)&userTime);
UInt32 totalSeconds = UInt32(((kernelTime + userTime) / 10000000));
UInt32 seconds = totalSeconds % 60;
UInt32 minutes = totalSeconds / 60 % 60;
UInt32 hours = totalSeconds / 60 / 60 % 24;
UInt32 days = totalSeconds / 60 / 60 / 24;
String^ CpuTime = L"";
if (days != 0)
CpuTime += days.ToString() + "天";
if (hours != 0)
CpuTime += hours.ToString() + "小时";
if (minutes != 0)
CpuTime += minutes.ToString() + "分";
if (seconds != 0)
CpuTime += seconds.ToString() + "秒";
label15->Text = CpuTime;
// 关闭进程句柄
CloseHandle( hProcess_One_Process );
break;
} //关闭进程
CloseHandle( hProcess_One_Process );
Process32Next(hProcess_All_Process, &sTr_Of_Process); }
}
CloseHandle( hProcess_All_Process );
//GlobalMemoryStatusEx(&sTr_SysMemory);
//label32->Text = ((UInt32)sTr_SysMemory.ullTotalPhys/1024).ToString() ;
}
每个TIMER代码基本相同...但是却不能完全取打开进程..总会有一个或多个TIMER得不到信息...我把其中一个TIMER的代码贴出来...请大家帮我看看..问题出在哪
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) {
// 获取APPSERVER1进程信息 HMODULE hMods[1024];
// 模块结构体大小
DWORD cbNeeded;
HANDLE hProcess_One_Process;
HANDLE hProcess_All_Process; // 进程建立,退出,系统调用,用户调用时间
ULONGLONG createTime, exitTime, kernelTime, userTime;
BOOL bEmpt;
BOOL bGet_Fail;
DWORD dPid; // 进程内存结构
PROCESS_MEMORY_COUNTERS sTr_pMemory; // 进程结构
PROCESSENTRY32 sTr_Of_Process; // 系统内存结构
MEMORYSTATUSEX sTr_SysMemory;
sTr_SysMemory.dwLength = sizeof (sTr_SysMemory); String^ sFolder;
String^ sExeNameTemp;
String^ sExeName;
String^ sPath = label19->Text;
String^ sSlash = "\\";
String^ sFolderPath = "Program Files"; //进程所以文件夹及文件名
String^ sExeName2__ = "sqlservr.exe"; sTr_Of_Process.dwSize = sizeof(sTr_Of_Process); // 得到所有进程句柄
hProcess_All_Process = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
// 获取第一个进程结构
if (Process32First(hProcess_All_Process, &sTr_Of_Process)){
while ( Process32Next(hProcess_All_Process, &sTr_Of_Process))
{ // 获取进程PID
dPid = sTr_Of_Process.th32ProcessID;
// 打开进程
hProcess_One_Process = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE, dPid); // 进程路径
if (EnumProcessModules(hProcess_One_Process, hMods, sizeof(hMods), &cbNeeded))
{
WCHAR szModName[MAX_PATH]; // 句柄数
label17->Text = ((UInt32)sTr_Of_Process.cntUsage).ToString();
GetModuleFileNameEx( hProcess_One_Process, hMods[0], szModName, sizeof(szModName) ); // 路径
label19->Text = gcnew String(szModName);
}
else
{
label19->Text = "Unknow!";
}
// 取进程所在文件夹
sFolder = "";
sExeNameTemp = "";
sExeName = "";
sPath = label19->Text; // 斜杠字符数量
int iCountOfSlash = 0;
int i = 0;
for ( i; i < sPath->Length; i++){
if (String::Compare(sPath->Substring(i,1), sSlash) & (iCountOfSlash == 1) )
{
sFolder = sFolder + sPath->Substring(i,1);
}
else
{
if ( String::Compare(sPath->Substring(i,1), sSlash) == 0 )
iCountOfSlash++;
if ( iCountOfSlash >= 2 )
break;
}
}
// 程序名
int k = sPath->Length - 1;
int iCountOfSlash2 = 0;
for ( k; k > 0; k--){
if ( String::Compare(sPath->Substring(k,1), sSlash) )
{
sExeNameTemp = sExeNameTemp + sPath->Substring(k,1);
}
else
{
iCountOfSlash2 ++;
if ( iCountOfSlash >= 1 )
break;
}
}
k = sExeNameTemp->Length - 1;
for ( k; k >= 0; k--){
sExeName = sExeName + sExeNameTemp->Substring(k,1);
sExeName = sExeName->ToLower();
}
// 取APPSERVER1句柄,PID
if ( (String::Compare(sFolder, sFolderPath, true) == 0) & (String::Compare(sExeName, sExeName2__ ,true) ==0) ){ // 内存占用
bGet_Fail = GetProcessMemoryInfo(hProcess_One_Process, &sTr_pMemory, sizeof(sTr_pMemory));
label12->Text = ( (UInt32)sTr_pMemory.WorkingSetSize / 1024 ).ToString() + " K"; // 获取进程内存使用峰值
label13->Text = ( (UInt32)sTr_pMemory.PeakWorkingSetSize / 1024 ).ToString() + " K"; // 路径中文件夹名
label7->Text = sFolder;
// PID
label6->Text = ((UInt32)dPid).ToString(); // 进程名
label4->Text = gcnew String(sTr_Of_Process.szExeFile); // 线程数
label16->Text = ((UInt32)sTr_Of_Process.cntThreads).ToString(); // 句柄数
//label17->Text = ((UInt32)sTr_Of_Process.dwFlags).ToString();
// 获取进程CPU时间
::GetProcessTimes(hProcess_One_Process, (LPFILETIME)&createTime, (LPFILETIME)&exitTime, (LPFILETIME)&kernelTime, (LPFILETIME)&userTime);
UInt32 totalSeconds = UInt32(((kernelTime + userTime) / 10000000));
UInt32 seconds = totalSeconds % 60;
UInt32 minutes = totalSeconds / 60 % 60;
UInt32 hours = totalSeconds / 60 / 60 % 24;
UInt32 days = totalSeconds / 60 / 60 / 24;
String^ CpuTime = L"";
if (days != 0)
CpuTime += days.ToString() + "天";
if (hours != 0)
CpuTime += hours.ToString() + "小时";
if (minutes != 0)
CpuTime += minutes.ToString() + "分";
if (seconds != 0)
CpuTime += seconds.ToString() + "秒";
label15->Text = CpuTime;
// 关闭进程句柄
CloseHandle( hProcess_One_Process );
break;
} //关闭进程
CloseHandle( hProcess_One_Process );
Process32Next(hProcess_All_Process, &sTr_Of_Process); }
}
CloseHandle( hProcess_All_Process );
//GlobalMemoryStatusEx(&sTr_SysMemory);
//label32->Text = ((UInt32)sTr_SysMemory.ullTotalPhys/1024).ToString() ;
}
第1个问题,不知道你为何用多个Timer,是多线程吗?如果是多线程可能会有冲突,可以加同步对象试试。另外Process32First之后要用do...while循环,否则会丢失第1个;还有OpenProcess需要SeDebugPrivilege权限。
String^ sFolderPath = "Program Files"; //进程所以文件夹及文件名
String^ sExeName2__ = "sqlservr.exe";
这里定义的是进程所根目录的第一个文件名.和程序名.我刚学用VC.这个程序能写到这种程序..多谢你们的帮助!
hProcess_All_Process = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 这一句有没有问题..我调试的时候在任务管理器里面可以看到进程.比如QQ.但是用EnumProcessModules却得到
我建议你还是自己来找问题,从而提升自己的能力,当你遇到困难时大家可以给你一些提示和建议。
对于目前的问题,你应该在各个函数调用后(主要是OpenProcess),判断是否成功,如果失败则取出错误码,设断点查看或者把错误码显示出来,然后再根据错误码判断可能的原因。
{
HANDLE token;
TOKEN_PRIVILEGES tp;
LUID luid; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) return FALSE;
if (!LookupPrivilegeValue(NULL, _T("SeDebugPrivilege"), &luid)) return FALSE;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = luid;
return AdjustTokenPrivileges(token, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
}程序初始化的时候执行一次即可。
TOKEN_PRIVILEGES tp;
LUID luid;
LPCWSTR LTEMP1 = L"ntdll";
BOOL a,b,c;
a = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);
b = LookupPrivilegeValue(NULL, LTEMP1, &luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = luid;
c = AdjustTokenPrivileges(token, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);报错.fatal error LNK1120: 3 个无法解析的外部命令
在网上查了一下.
我把这段代码放在private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
比如我取的是WORD.EXCEL.POWERPOINT.等进程信息...界面只显示一个或两个进程信息.但是我关闭一个,比如WORD之后.另外的进程信息就会显示出来.
1.得到进程快照
2.取出进程所在文件夹和文件名后.用了4个IF来判断当前打开的进程是否是想取的进程;
但是问题依然没有解决.
要关闭一个进程.另一个进程才会显示出来更改以后的程序已经发到你邮箱里了..麻烦再帮我看看吧.如果OFFICE不在Program Files下.更改
String^ sFolderPath1 = "Program Files";
这个变量值就可以了....
{ //关闭进程
CloseHandle( hProcess_One_Process );
//Process32Next(hProcess_All_Process, &sTr_Of_Process);}// While 循环结束cnzdgs 你好..我找到问题根源了..很简单...我的代码出现了严重的逻辑错误.WHILE的时候就是运行了Process32Next.而在循环结束的时候我再次运行Process32Next,造成不能打开所有进程...太高兴了...马上结贴 ..再次感谢你..以后还有很多问题要请教你.呵呵...担搁你这么多时间 ...真不好意思啊...