// OutputPID.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream.h"
#include <fstream.h>
#include "windows.h"
#include "tlhelp32.h"
#include "psapi.h"
#include <stdlib.h>
#include <string.h>
typedef struct MemoryDumpOption_s {
int show_list;
int pid;
} MemoryDumpOption_t, * MemoryDumpOption_p;
typedef struct MemoryDumpInfo_s {
unsigned long total_size;
unsigned long free_count;
unsigned long free_size;
unsigned long free_max;
unsigned long used_size;
unsigned long map_count;
unsigned long map_size;
unsigned long reserve_count;
unsigned long reserve_size;
unsigned long commit_count;
unsigned long commit_size;
} MemoryDumpInfo_t, * MemoryDumpInfo_p;
bool getMemoryInfo(DWORD dwProcessID, float &dwVirtualSize, float &dwFreeVirtualSize, float &dwPrivateByte, float &dwWorkSet)
{
MemoryDumpInfo_t mdinf;
MEMORY_BASIC_INFORMATION mem_info;
DWORD size;
DWORD status;
char * ptr = 0;
HANDLE hprocess = 0;
int count = 0;
status = size = 0;
hprocess = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, dwProcessID );
if (!hprocess) {
return 0;
}
memset(&mdinf, 0, sizeof(MemoryDumpInfo_t));
while(status == size) {
size = sizeof(mem_info);
//
status = VirtualQueryEx(hprocess, ptr, &mem_info, size);
if (!status) break;
switch (mem_info.State) {
case MEM_FREE:
mdinf.free_count += 1;
if (mem_info.RegionSize > mdinf.free_max)
mdinf.free_max = mem_info.RegionSize;
mdinf.free_size += mem_info.RegionSize;
break;
case MEM_RESERVE:
mdinf.reserve_count += 1;
mdinf.reserve_size += mem_info.RegionSize;
mdinf.used_size += mem_info.RegionSize;
break;
case MEM_COMMIT:
mdinf.commit_count += 1;
mdinf.commit_size += mem_info.RegionSize;
mdinf.used_size += mem_info.RegionSize;
break;
}
if (mem_info.Type == MEM_MAPPED) {
mdinf.map_count += 1;
mdinf.map_size += mem_info.RegionSize;
}
ptr += mem_info.RegionSize;
count++;
}
dwFreeVirtualSize = mdinf.free_size/(1024.0f*1024.0f); //Free virtual size kilobyte
dwVirtualSize = mdinf.used_size/(1024.0f*1024.0f);
PROCESS_MEMORY_COUNTERS stEndMemInfo;
::GetProcessMemoryInfo( hprocess,
&stEndMemInfo, sizeof(stEndMemInfo));
dwPrivateByte = stEndMemInfo.PagefileUsage/(1024.0f*1024.0f);
dwWorkSet = stEndMemInfo.WorkingSetSize/(1024.0f*1024.0f);
return true;
}
bool GetProcessThreadNum(DWORD dwProcessID,DWORD &dwThreadNum)
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, dwProcessID );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
return false;
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof( PROCESSENTRY32 );
// Retrieve information about the first process,
// and exit if unsuccessful
if( !Process32First( hProcessSnap, &pe32 ) )
{
CloseHandle( hProcessSnap ); // Must clean up the snapshot object!
return false;
}
do
{
if (pe32.th32ProcessID == dwProcessID)
{
dwThreadNum = pe32.cntThreads;
break;
}
} while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap );
return true;
}
bool getGDINum(DWORD dwProcessID, DWORD &dwGDINum)
{
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION,FALSE,dwProcessID );
dwGDINum = GetGuiResources(hProcess,GR_GDIOBJECTS);
return true;
}
int main(int argc, char* argv[])
{
DWORD dwProcessID = 0;
DWORD dwGDINum=0, dwThreadNum=0;
float dwVirtualSize=0.0, dwFreeVirtualSize=0.0,dwPrivateByte=0.0, dwWorkSet=0.0;
WCHAR *csProcessName = NULL;
if (argc<2)
{
cout<<"parameters are not correct! example: /r/nOutputPID.exe c://BugInfo//PID.txt/r/n";
return -1;
}
ofstream ofs(argv[1],ios::out|ios::trunc);
if (!ofs.is_open())
{
cout<<"open output log file failed, please check the directory!";
return -1;
}
ofs.setf(ios::left);
ofs.width(32);
ofs<<"Image Name";
ofs.width(12);
ofs<<"PID";
ofs.width(16);
ofs<<"Private Byte(M)";
ofs.width(16);
ofs<<"Virtual Size(M)";
ofs.width(16);
ofs<<"Free Size(M)";
ofs.width(16);
ofs<<"Working Set(M)";
ofs.width(12);
ofs<<"GDI Number";
ofs.width(12);
ofs<<"Thread Number";
ofs<<"/n";
HANDLE hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == (HANDLE)-1)
{
printf("/nCreateToolhelp32Snapshot() failed:%d",GetLastError());
return 1;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
do
{
dwProcessID = pe32.th32ProcessID;
// dwProcessID = 1240;
getGDINum(dwProcessID, dwGDINum);
GetProcessThreadNum(dwProcessID, dwThreadNum);
getMemoryInfo(dwProcessID, dwVirtualSize, dwFreeVirtualSize,dwPrivateByte, dwWorkSet);
// cout<<dwProcessID<<" "<<dwGDINum<<" "<<dwThreadNum<<" "<<dwPrivateByte<<" "<<dwWorkSet<<" "<<dwVirtualSize<<" "<<pe32.szExeFile<<endl;
ofs.setf(ios::left);
ofs.width(32);
ofs<<pe32.szExeFile;
ofs.width(12);
ofs<<dwProcessID;
ofs.width(16);
ofs.setf(ios::fixed, ios::scientific);
ofs.precision(6);
ofs<<dwPrivateByte;
ofs.width(16);
ofs<<dwVirtualSize;
ofs.width(16);
ofs<<dwFreeVirtualSize;
ofs.width(16);
ofs<<dwWorkSet;
ofs.width(12);
ofs<<dwGDINum;
ofs.width(12);
ofs<<dwThreadNum;
ofs<<"/n";
}
while (Process32Next(hProcessSnap, &pe32));
}
else
{
printf("/nProcess32Firstt() failed:%d",GetLastError());
}
CloseHandle (hProcessSnap);
return 0;
}