char* processInfo(char *process, int *len)
{
......
hprocess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hprocess == INVALID_HANDLE_VALUE)
{
return NULL;
}
memset(&pe, 0, sizeof(PROCESSENTRY32));
pe.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hprocess, &pe) != FALSE)
{
do
{
memset(sTemp, 0, sizeof(sTemp)); //初始化进程名
wcstombs(sTemp, pe.szExeFile, sizeof(sTemp)); //宽字符转char型字符
iLen = strlen(sTemp); //进程名长度
memcpy(p, &iLen, sizeof(short)); //进程名长度
p += sizeof(short); //p向后漂移
memcpy(p, sTemp, iLen); //进程名
p += iLen; //p向后漂移
memSize = 0; //每个进程占用内存大小
//创建堆列表快照
hlist = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pe.th32ProcessID);
if (hprocess == INVALID_HANDLE_VALUE)
{
return NULL;
}
hl.dwSize = sizeof(HEAPLIST32);
if(Heap32ListFirst(hlist, &hl))
{
do
{
//创建堆快照
hentry = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hentry == INVALID_HANDLE_VALUE)
{
return NULL;
}
he.dwSize = sizeof(HEAPENTRY32);
if (Heap32First(hentry, &he, hl.th32ProcessID, hl.th32HeapID))
{
do
{
if (he.dwFlags == LF32_FREE)
{
continue;
}
memSize += he.dwBlockSize; //只计算用了的内存
memset(&he, 0, sizeof(he));
he.dwSize = sizeof(HEAPENTRY32);
}while(Heap32Next(hentry, &he));
}
CloseToolhelp32Snapshot(hentry);
}while(Heap32ListNext(hlist, &hl));
}
CloseToolhelp32Snapshot(hlist);
memcpy(p, &memSize, sizeof(memSize)); //每个进程占用内存大小
p += sizeof(memSize); //p向后漂移4个字节
memset(&pe, 0, sizeof(PROCESSENTRY32)); //初始化PROCESSENTRY32
pe.dwSize = sizeof(PROCESSENTRY32); //设置pe的dwSize值
}while(Process32Next(hprocess, &pe)); //下一个进程
}
*length = p-processInfo; //字符长度
CloseToolhelp32Snapshot(hprocess);
return processInfo;
}
逻辑很简单,创建进程快照,在逐个扫描进程循环中嵌套堆列表快照创建和逐个扫描;在堆列表循环中
再嵌套堆快照。因为要得到WinCE进程的内存使用量是要得到堆HEAPENTRY32标志为非LF32_FREE
的dwBlockSize大小,而要得到其dwBlockSize大小,需要得到堆列表信息的堆ID和进程ID,而要得到
进程ID于是要得到进程快照。
代码等待测试---
上面代码有问题,一些细节上,新的代码如下:
hprocess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hprocess == INVALID_HANDLE_VALUE)
{
DiagnoseEntry(NULL, 0x006A, GetLastError());
}
memset(&pe, 0, sizeof(PROCESSENTRY32));
pe.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hprocess, &pe) != FALSE)
{
do
{
memSize = 0; //每个进程占用内存大小
//创建堆列表快照
hlist = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pe.th32ProcessID);
if (hprocess == INVALID_HANDLE_VALUE)
{
}
memset(&hl, 0, sizeof(hl));
hl.dwSize = sizeof(HEAPLIST32);
if(Heap32ListFirst(hlist, &hl))
{
do
{
//创建堆快照
hentry = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hentry == INVALID_HANDLE_VALUE)
{
}
memset(&he, 0, sizeof(he));
he.dwSize = sizeof(HEAPENTRY32);
if (Heap32First(hentry, &he, hl.th32ProcessID, hl.th32HeapID))
{
do
{
//if (he.dwFlags == LF32_FREE)
//{
// continue;
//}
memSize += he.dwBlockSize; //只计算用了的内存
totalSize += he.dwBlockSize;
}while(Heap32Next(hentry, &he));
}
CloseToolhelp32Snapshot(hentry);
hentry = INVALID_HANDLE_VALUE;
}while(Heap32ListNext(hlist, &hl));
}
CloseToolhelp32Snapshot(hlist);
hlist = INVALID_HANDLE_VALUE;
/*测试发现有些进程有多个,在HeapList32Next时会退出,最后多个进程名中只有一个
会参与到内存大小的相加中,这样进程名的有效要到close掉heaplist32后了*/
//数据结构:进程名长度(2字节)+进程名(strlen(process))+进程占字节数(4字节)
memset(sTemp, 0, sizeof(sTemp)); //初始化进程名
wcstombs(sTemp, pe.szExeFile, sizeof(sTemp)); //宽字符转char型字符
iLen = strlen(sTemp); //进程名长度
memcpy(p, &iLen, 2); //进程名长度(2字节)
p += 2; //p向后漂移
memcpy(p, sTemp, iLen); //进程名
p += iLen; //p向后漂移(iLen字节)
memcpy(p, &memSize, sizeof(memSize)); //每个进程占用内存大小
p += 4; //p向后漂移(4个字节)
if(!strncmp(sTemp, "NK.EXE", 6))
{
itemp = p-processInfo-4; //只是记录NK.exe的内存大小位置,因为向后飘了4字节,所以要再向前飘4字节,而非原来的 itemp = p-processInfo
}
}while(Process32Next(hprocess, &pe)); //下一个进程
}
/*计算总的长度要在p指针被改变之前*/
*length = p-processInfo; //字符长度
p = processInfo+itemp; //计算NK.EXE内存占用大小
memSize = memStatus.dwTotalPhys - memStatus.dwAvailPhys + memStatus.dwTotalVirtual - memStatus.dwAvailVirtual - totalSize;
memcpy(p, &memSize, 4);
CloseToolhelp32Snapshot(hprocess);
hprocess = INVALID_HANDLE_VALUE;
return processInfo;