添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Introduction

This article is a brief explanation of how to use the GetProcessTimes API. There are times when knowing how long a process has been running might be useful.

The time values returned from GetProcessTimes are fairly easy to convert into something useful/readable. Let's operate on this code snippet:

HANDLE hProcess;
</CODE>FILETIME ftCreation,
         ftExit,
         ftKernel,
         ftUser;
GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);

Calculating running-time

A processes' running-time is the amount of time that has elapsed between the current time and the processes' creation time. This is stored in a FILETIME structure.

Once the elapsed time is calculated, then it's a matter of converting it to hours, minutes, seconds, etc. Luckily, the COleDateTime class makes this a painless process.

COleDateTime timeNow = COleDateTime::GetCurrentTime(),
timeCreation = ftCreation;
COleDateTimeSpan timeDiff = timeNow - timeCreation;

From here, you can use the different methods of COleDateTimeSpan to get the elapsed hours, minutes, etc.

Calculating kernel and user times

Per the documentation, the kernel and user times are amounts of time rather than an actual time period . The value in the FILETIME structure is expressed in 100-nanosecond units. To convert that to something useful, let's look at two methods.

Method 1

We can convert that to seconds with some basic arithmetic. A nanosecond is one billionth of a second, but since the time is already expressed in 100-nanosecond units, we'll only divide by 10 million:

__int64 i64Kernel = *((__int64 *) &ftKernel);
DWORD dwKernel = (DWORD) (i64Kernel / 10000000U);

As an alternative to the casting used above, a union could have just as easily been employed:

union
FILETIME ftKernel;
__int64 i64Kernel;
} timeKernel;
timeKernel.ftKernel = ftKernel;
DWORD dwKernel = (DWORD) (timeKernel.i64Kernel / 10000000U);

Either way, dwKernel now represents the number of elapsed seconds that the process has been in kernel mode. Converting seconds to hours, minutes, and seconds is a straightforward process.

Method 2

An alternative method that does not require anything other than a function call is to use the FileTimeToSystemTime API. This stores the result in a SYSTEMTIME structure, where we then have access to the wHour , wMinute , and wSecond members.

SYSTEMTIME stKernel;
FileTimeToSystemTime(&ftKernel, &stKernel);

The user-mode time is handled in the same way as kernel-mode time.

Summary

That's all there is to it. Looking at all of this together yields:

GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);
timeCreation = ftCreation;
strData.Format("Created at %02d:%02d:%02d", timeCreation.GetHour(), 
               timeCreation.GetMinute(), timeCreation.GetSecond());
timeDiff = timeNow - timeCreation;
strData.Format("Elapsed time = %ud %uh %um %us", timeDiff.GetDays(), 
               timeDiff.GetHours(), timeDiff.GetMinutes(), 
               timeDiff.GetSeconds());
FileTimeToSystemTime(&ftKernel, &stKernel);
strData.Format("Time in kernel mode = %uh %um %us", stKernel.wHour,
               stKernel.wMinute, stKernel.wSecond);

Notes

The way the demo code is currently written, some system-level processes did not allow their name and time-information to be retrieved.


The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.
HTTP 404 - File not found
Internet Information Services
compiled code using Microsoft Visual C++ 2005
program is in a loop at this point under wincore.cpp
ASSERT(::IsWindow(m_hWnd));
// don't translate non-input events
if ((lpMsg->message < WM_KEYFIRST || lpMsg->message > WM_KEYLAST) &&
(lpMsg->message < WM_MOUSEFIRST || lpMsg->message > AFX_WM_MOUSELAST))
return FALSE;
return IsDialogMessage(lpMsg);
int CWnd::RunModalLoop(DWORD dwFlags)
ASSERT(::IsWindow(m_hWnd)); // window must be created
ASSERT(!(m_nFlags & WF_MODALLOOP)); // window must not already be in modal state
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);
HWND hWndParent = ::GetParent(m_hWnd);
m_nFlags |= (WF_MODALLOOP|WF_CONTINUEMODAL);
MSG *pMsg = AfxGetCurrentMessage();
// acquire and dispatch messages until the modal state is done
for (;;)
ASSERT(ContinueModal());
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
ASSERT(ContinueModal());
// show the dialog when the message queue goes idle
if (bShowIdle)
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
// call OnIdle while in bIdle state
if (!(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL && lIdleCount == 0)
// send WM_ENTERIDLE to the parent
::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);
if ((dwFlags & MLF_NOKICKIDLE) ||
!SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))
// stop idle processing next time
bIdle = FALSE;
// phase2: pump messages while available
ASSERT(ContinueModal());
// pump message, but quit on WM_QUIT
if (!AfxPumpMessage())
AfxPostQuitMessage(0);
return -1;
// show the window when certain special messages rec'd
if (bShowIdle &&
(pMsg->message == 0x118 || pMsg->message == WM_SYSKEYDOWN))
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
if (!ContinueModal())
goto ExitModal;
// reset "no idle" state after pumping "normal" message
if (AfxIsIdleMessage(pMsg))
bIdle = TRUE;
lIdleCount = 0;
} while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
ExitModal:
m_nFlags &= ~(WF_MODALLOOP|WF_CONTINUEMODAL);
return m_nModalResult;
Sign In · View Thread I want to check memory usage by a process running in a remote system. Here is the code snippet I am using. I am specifying the system name/ IP, but call to PdhAddCounter()is failing. Any suggestion?
TCHAR szAvailBytes[256] = TEXT("");
TCHAR szWorkingSet[256] = TEXT("");
TCHAR szBuffer[256] = TEXT("");
DWORD dwBufferSize = sizeof(szAvailBytes);
HCOUNTER hAvailBytes,
hCacheBytes,
hWorkingSet;
HQUERY hQuery = NULL;
PDH_COUNTER_PATH_ELEMENTS pdhCpe;
PDH_STATUS pdhStatus;
PDH_FMT_COUNTERVALUE pdhfmtAvail,
pdhfmtWorking;
__try
pdhStatus = PdhOpenQuery(NULL, 0, &hQuery);
if (pdhStatus != ERROR_SUCCESS)
__leave;
// Make Counter Path
pdhCpe.szMachineName = TEXT(<system name="" ip="">);
pdhCpe.szObjectName = TEXT("Memory");
pdhCpe.szInstanceName = NULL;
pdhCpe.szParentInstance = NULL;
pdhCpe.dwInstanceIndex = -1;
pdhCpe.szCounterName = TEXT("Available Bytes");
pdhStatus = PdhMakeCounterPath(&pdhCpe, szAvailBytes, &dwBufferSize, 0);
if (pdhStatus != ERROR_SUCCESS)
__leave;
pdhCpe.szObjectName = TEXT("Process");
pdhCpe.szInstanceName = TEXT("explorer");
pdhCpe.szCounterName = TEXT("Working Set");
dwBufferSize = sizeof(szWorkingSet);
pdhStatus = PdhMakeCounterPath(&pdhCpe, szWorkingSet, &dwBufferSize, 0);
if (pdhStatus != ERROR_SUCCESS)
__leave;
// Add counters.
pdhStatus = PdhAddCounter(hQuery, szWorkingSet, 0, &hWorkingSet); // failing here :: Access denied
if (pdhStatus != ERROR_SUCCESS)
__leave;
// Get the data.
pdhStatus = PdhCollectQueryData(hQuery);
if (pdhStatus != ERROR_SUCCESS)
__leave;
pdhStatus = PdhGetFormattedCounterValue(hWorkingSet, PDH_FMT_LONG | PDH_FMT_NOSCALE, NULL, &pdhfmtWorking);
if (pdhStatus != ERROR_SUCCESS)
__leave;
wsprintf(szBuffer, TEXT("Working Set = %ld\n"), pdhfmtWorking.longValue);
OutputDebugString(szBuffer);
__finally
if (hQuery != NULL)
pdhStatus = PdhCloseQuery(hQuery);
if (pdhStatus != ERROR_SUCCESS)
Sign In · View Thread
Are you using Windows XP or Vista?
Aryan S wrote:
pdhStatus = PdhAddCounter(hQuery, szWorkingSet, 0, &hWorkingSet); // failing here :: Access denied

Is this one of the PDH error status codes defined in PDHMsg.h?

"A good athlete is the result of a good and worthy opponent." - David Crow

"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne


Sign In · View Thread Sir,with all due respect.
I want to know, How much memory each processes are consuming as it shown by taskmgr in win2000 and Upward
Sign In · View Thread TCHAR szAvailBytes[256] = TEXT( " " ); TCHAR szCacheBytes[256] = TEXT( " " ); TCHAR szWorkingSet[256] = TEXT( " " ); TCHAR szBuffer[256] = TEXT( " " ); DWORD dwBufferSize = sizeof (szAvailBytes); HCOUNTER hAvailBytes, hCacheBytes, hWorkingSet; HQUERY hQuery = NULL; PDH_COUNTER_PATH_ELEMENTS pdhCpe; PDH_STATUS pdhStatus; PDH_FMT_COUNTERVALUE pdhfmtAvail, pdhfmtCache, pdhfmtWorking; __try pdhStatus = PdhOpenQuery(NULL, 0 , &hQuery); if (pdhStatus != ERROR_SUCCESS) __leave; // Make Counter Path pdhCpe.szMachineName = TEXT( " your machine" ); pdhCpe.szObjectName = TEXT( " Memory" ); pdhCpe.szInstanceName = NULL; pdhCpe.szParentInstance = NULL; pdhCpe.dwInstanceIndex = -1; pdhCpe.szCounterName = TEXT( " Available Bytes" ); pdhStatus = PdhMakeCounterPath(&pdhCpe, szAvailBytes, &dwBufferSize, 0 ); if (pdhStatus != ERROR_SUCCESS) __leave; pdhCpe.szCounterName = TEXT( " Cache Bytes" ); dwBufferSize = sizeof (szCacheBytes); pdhStatus = PdhMakeCounterPath(&pdhCpe, szCacheBytes, &dwBufferSize, 0 ); if (pdhStatus != ERROR_SUCCESS) __leave; pdhCpe.szObjectName = TEXT( " Process" ); pdhCpe.szInstanceName = TEXT( " _Total" ); pdhCpe.szCounterName = TEXT( " Working Set" ); dwBufferSize = sizeof (szWorkingSet); pdhStatus = PdhMakeCounterPath(&pdhCpe, szWorkingSet, &dwBufferSize, 0 ); if (pdhStatus != ERROR_SUCCESS) __leave; // Add counters. pdhStatus = PdhAddCounter(hQuery, szAvailBytes, 0 , &hAvailBytes); if (pdhStatus != ERROR_SUCCESS) __leave; pdhStatus = PdhAddCounter(hQuery, szCacheBytes, 0 , &hCacheBytes); if (pdhStatus != ERROR_SUCCESS) __leave; pdhStatus = PdhAddCounter(hQuery, szWorkingSet, 0 , &hWorkingSet); if (pdhStatus != ERROR_SUCCESS) __leave; // Get the data. pdhStatus = PdhCollectQueryData(hQuery); if (pdhStatus != ERROR_SUCCESS) __leave; // Format counter values. pdhStatus = PdhGetFormattedCounterValue(hAvailBytes, PDH_FMT_LONG | PDH_FMT_NOSCALE, NULL, &pdhfmtAvail); if (pdhStatus != ERROR_SUCCESS) __leave; pdhStatus = PdhGetFormattedCounterValue(hCacheBytes, PDH_FMT_LONG | PDH_FMT_NOSCALE, NULL, &pdhfmtCache); if (pdhStatus != ERROR_SUCCESS) __leave; pdhStatus = PdhGetFormattedCounterValue(hWorkingSet, PDH_FMT_LONG | PDH_FMT_NOSCALE, NULL, &pdhfmtWorking); if (pdhStatus != ERROR_SUCCESS) __leave; wsprintf(szBuffer, TEXT( " Avail Bytes = %ld\n" ), pdhfmtAvail.longValue); OutputDebugString(szBuffer); wsprintf(szBuffer, TEXT( " Cache Bytes = %ld\n" ), pdhfmtCache.longValue); OutputDebugString(szBuffer); wsprintf(szBuffer, TEXT( " Working Set = %ld\n" ), pdhfmtWorking.longValue); OutputDebugString(szBuffer); wsprintf(szBuffer, TEXT( " Physical Mem = %ldMB\n" ), (pdhfmtAvail.longValue + pdhfmtCache.longValue + pdhfmtWorking.longValue) / ( 1024 * 1024 )); OutputDebugString(szBuffer); __finally if (hQuery != NULL) pdhStatus = PdhCloseQuery(hQuery); if (pdhStatus != ERROR_SUCCESS) }

"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen


-- modified at 8:41 Monday 11th September, 2006
Sign In · View Thread Is it possible to obtain the dll module called by the specific process.
sometime the memory allocation was done in the external dlls, so I want to know how about that.
Best Regards
Sign In · View Thread
Hi DavidCrow,
I can add the counter with instance and i am increasing the raw value of it but i can not see that value it is showing only 0. If i am incrementing the counter value without instance then it can be monitored but with instance i am unable to monitor it.
i creating the counter like it
CounterCreationDataCollection^ CCDC = gcnew CounterCreationDataCollection;
// Add the counter.
CounterCreationData^ averageCount64 = gcnew CounterCreationData;
averageCount64->CounterType = PerformanceCounterType::AverageCount64;
averageCount64->CounterName = "Counter2";
CCDC->Add( averageCount64 );
// Add the base counter.
CounterCreationData^ averageCount64Base = gcnew CounterCreationData;
averageCount64Base->CounterType = PerformanceCounterType::AverageBase;
averageCount64Base->CounterName = "Counter3";
CCDC->Add( averageCount64Base );
PerformanceCounterCategory::Create( "ZAverageInstanceCategory", "Demonstrates usage of the AverageCounter64 performance counter type.", CCDC );
PerformanceCounter^% PC = gcnew PerformanceCounter( "ZAverageInstanceCategory","Counter2","instance1", false );
PC->RawValue = 10;
PerformanceCounter^% BPC = gcnew PerformanceCounter( "ZAverageInstanceCategory","Counter3","instance2", false );
BPC->RawValue = 0;
Thanks
vijay

Sign In · View Thread i downloaded your code. it gives a compilin error sayin
fatal error RC1015: cannot open include file 'res//ProcessInfo.rc2'
i cant find that file in the dwnloaded files.. pls chk
Sign In · View Thread The file is in the zip. I suspect you have unzipped all of the files into a single folder. If this is the case, there are 2 solutions:
1) create a res folder underneath the folder you extracted to, and place ProcessInfo.rc2 and ProcessInfo.ico into it.
2) Extract the files again, and make sure that " Use Folder Names " is checked
Sign In · View Thread It is now, but wasn't when pranay posted.

"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)


Sign In · View Thread How to get CPU usage per process? Shall be possible to calculate trough GetProcessTimes, but how?
Sign In · View Thread PDH_STATUS pdhStatus; HQUERY hQuery = NULL; HCOUNTER hProcessorTime; PDH_COUNTER_PATH_ELEMENTS pdhCpe; PDH_FMT_COUNTERVALUE pdhfmtProcessorTime; TCHAR szProcessorTime[256], szBuffer[256]; DWORD dwBufferSize; __try pdhStatus = PdhOpenQuery(NULL, 0 , &hQuery); if (pdhStatus != ERROR_SUCCESS) __leave; // make counter path pdhCpe.szMachineName = TEXT( " crow-nt" ); pdhCpe.szObjectName = TEXT( " Process" ); pdhCpe.szInstanceName = TEXT( " Idle" ); pdhCpe.szParentInstance = NULL; pdhCpe.dwInstanceIndex = -1; pdhCpe.szCounterName = TEXT( " % Processor Time" ); dwBufferSize = sizeof (szProcessorTime); pdhStatus = PdhMakeCounterPath(&pdhCpe, szProcessorTime, &dwBufferSize, 0 ); if (pdhStatus != ERROR_SUCCESS) __leave; // add counter pdhStatus = PdhAddCounter(hQuery, szProcessorTime, 0 , &hProcessorTime); if (pdhStatus != ERROR_SUCCESS) __leave; // get the data pdhStatus = PdhCollectQueryData(hQuery); if (pdhStatus != ERROR_SUCCESS) __leave; // format counter value pdhStatus = PdhGetFormattedCounterValue(hProcessorTime, PDH_FMT_LONG, NULL, &pdhfmtProcessorTime); if (pdhStatus != ERROR_SUCCESS) __leave; if (ERROR_SUCCESS == pdhStatus) wsprintf(szBuffer, TEXT( " Processor Time = %ld\n" ), pdhfmtProcessorTime.longValue); __finally if (hQuery != NULL) pdhStatus = PdhCloseQuery(hQuery);

"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)


Sign In · View Thread Hello,
thanks for this sample, i need little help to use this Frown | :( ,
i must to read the current cpu usage!
My program crash with Access violation after:
pdhStatus = PdhCollectQueryData(hQuery); if (pdhStatus != ERROR_SUCCESS) __leave; // in my case program execution stops every time here! I recive an PDH_NO_DATA, what to do now?
// A counter with a negative denominator value was detected. i make something wrong, but idont know what! Frown | :(
By compilig there are no errors, nothing, looks ok!
thanks for help!
termal
-- modified at 9:03 Friday 20th July, 2007
Sign In · View Thread
termal wrote:
My program crash with Access violation after:
pdhStatus = PdhCollectQueryData(hQuery);

Is hQuery valid?

"A good athlete is the result of a good and worthy opponent." - David Crow

"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne


Sign In · View Thread __try{ pdhStatus = PdhOpenQuery(NULL, 0 , &hQuery); // hQuery is not NULL if (pdhStatus != ERROR_SUCCESS) __leave; // make counter path pdhCpe.szMachineName = TEXT( " crow-nt" ); pdhCpe.szObjectName = TEXT( " Process" ); pdhCpe.szInstanceName = TEXT( " Idle" ); pdhCpe.szParentInstance = NULL; pdhCpe.dwInstanceIndex = -1; pdhCpe.szCounterName = TEXT( " % Processor Time" ); dwBufferSize = sizeof (szProcessorTime); pdhStatus = PdhMakeCounterPath(&pdhCpe, szProcessorTime, &dwBufferSize, 0 ); if (pdhStatus != ERROR_SUCCESS) // this is ok __leave; // add counter pdhStatus = PdhAddCounter(hQuery, szProcessorTime, 0 , &hProcessorTime); // on this line i see in a output window there is an exception, but program stops in next call for data if (pdhStatus != ERROR_SUCCESS) // __leave; // get the data pdhStatus = PdhCollectQueryData(hQuery); if (pdhStatus != ERROR_SUCCESS) // here not, unhandled exception! :( __leave; ...... // follow rest of code This is what i try to read current cpu usage
Many thanks for help!
termal
Sign In · View Thread

"A good athlete is the result of a good and worthy opponent." - David Crow

"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne


Sign In · View Thread
termal wrote:
here to set own machine name!?

Of course. That's why the member variable is called szMachineName .

"A good athlete is the result of a good and worthy opponent." - David Crow

"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne


Sign In · View Thread
Airport1 wrote:
How to get CPU usage per process? Shall be possible to calculate trough GetProcessTimes, but how?
Sign In · View Thread Why are you quoting Airport1 ?

"When I was born I was so surprised that I didn't talk for a year and a half." - Gracie Allen


Sign In · View Thread By using above example we are getting kernel,user,creation times of process.
How to get number of cpu cycles a particular process has executed from these information. Confused | :confused:
Sign In · View Thread See my response to Airport1 .

"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)


Sign In · View Thread I noticed that GetProcessTimes returns the same user time and kernel time if the application is idle; that is, if I have an application which has been idle for eight hours, the user time at the end of that eight hours is the same as the beginning of the eight hours. Same goes for the kernel time.
How can I differentiate an idle application from a frozen application?
thanks.
Sign In · View Thread m.bergman wrote:
I noticed that GetProcessTimes returns the same user time and kernel time if the application is idle; that is, if I have an application which has been idle for eight hours, the user time at the end of that eight hours is the same as the beginning of the eight hours. Same goes for the kernel time.
As it should. Just because a process is idle does not mean it is doing absolutely nothing (e.g., waiting around for user input is doing something). It is still in either the user or kernel mode.
m.bergman wrote:
How can I differentiate an idle application from a frozen application?
See if this article helps. It does nothing with frozen, however. I did see the "How can I detect if an application is frozen" question some time back. Maybe you can Google for it. I seem to recall it mentioning something about sending the suspect application a message and noting the result, if any. Try SendMessageTimeout(..., WM_NULL, ..., SMTO_ABORTIFHUNG, 4000, ...) , which waits 4 seconds for the window to respond.
Sign In · View Thread