Hi Rick,
Perhaps I’m stupid (a distinct possibility), but I can’t find
a mechanism for getting the system boot time. I’d prefer one
that can be done from WIN32 on NT & 9x systems (98+).
I know GetTickCount() will give me the clock ticks since system
boot and I can calculate boot time. However, that rolls over evey
49.2 days. I know it is a stretch that any Windows system will ever
be up longer than that, but it could happen someday and I’d rather
not have to deal with that.
Thanks in advance for any help and please forgive my ignorance if
the answer was obvious. I promose I searched the MSDN library
extensively before asking.
Below is some sample source code that checks on some useful performance
counters. It works on NT/2000, but not Win9x.
However, on Win9x, you might be able to query HKEY_DYN_DATA for similar
information. (For more information, see
http://support.microsoft.com/support/kb/articles/q174/6/31.asp and/or search
the MSDN library for “HKEY_DYN_DATA”.)
Back to the code below…
Note that it distinguishes between the time a system has been awake (i.e.,
not hibernated) and how much time has elapsed.
The one feature that is missing is the ability to compare against the
GetTickCounts() (which gives a slightly different time, btw) and the ability
to grovel over the event log to get the system startup event that the
eventlog service posts (which is also probably slight different).
I hope this helps.
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include <winperf.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <pdh.h>
#include <psapi.h>
void
print_time(
char* prefix,
__int64 t
)
{
__int64 secs = t % 60;
t /= 60;
int64 mins = t % 60;
t /= 60;
int64 hours = t % 24;
t /= 24;
__int64 days = t;
printf(“%s”
“%3I64d days, %2I64d hours, %2I64d minutes, %2I64d seconds\n”,
prefix,
days, hours, mins, secs);
}
PDH_STATUS
get_number_cv(
char* counter,
DWORD pdwType,
PDH_FMT_COUNTERVALUE pcv
)
{
PDH_STATUS pdhStatus = ERROR_SUCCESS;
HQUERY hQuery = 0;
HCOUNTER hCounter = 0;
pdhStatus = PdhOpenQuery(0, 0, &hQuery);
if (pdhStatus != ERROR_SUCCESS)
{
fprintf(stderr, “Error while opening query\n”);
goto cleanup;
}
pdhStatus = PdhAddCounter(hQuery, counter, 0, &hCounter);
if (pdhStatus)
{
fprintf(stderr, “Error while adding counter %s to query\n”,
counter);
goto cleanup;
}
pdhStatus = PdhCollectQueryData(hQuery);
if (pdhStatus)
{
fprintf(stderr, “Error collecting query data\n”);
goto cleanup;
}
pdhStatus = PdhGetFormattedCounterValue(hCounter,
PDH_FMT_LARGE | PDH_FMT_NOSCALE,
pdwType, pcv);
if (pdhStatus)
{
fprintf(stderr, “Error formatting counter value\n”);
goto cleanup;
}
// We can close the query since we do not need to refer to any of the
// string members.
cleanup:
if (hQuery)
PdhCloseQuery(hQuery);
return pdhStatus;
}
PDH_STATUS
get_and_print_time_cv(
char prefix,
char path
)
{
PDH_STATUS pdhStatus = ERROR_SUCCESS;
DWORD dwType = 0;
PDH_FMT_COUNTERVALUE cv;
pdhStatus = get_number_cv(path, &dwType, &cv);
if (pdhStatus)
return pdhStatus;
//printf(“Type: 0x%08x, Value: 0x%016I64x\n”, dwType, cv.largeValue);
print_time(prefix, cv.largeValue);
return 0;
}
__int64
filetime_to_seconds(
FILETIME ft
)
{
return ((__int64)&ft) / ( 1000 * 1000 * 1000 / 100 );
}
void
do_processes()
{
int i;
DWORD cb = 0;
BOOL ok = TRUE;
DWORD chunk = 5 * sizeof(DWORD);
DWORD size = chunk;
DWORD* ap = (DWORD*) malloc(size);
while ((ok = EnumProcesses(ap, size, &cb)) &&
(size < (sizeof(DWORD) + cb)))
{
cb = 0;
free(ap);
size += chunk;
ap = (DWORD*)malloc(size);
}
if (!ok)
{
printf(“Error enumerating processes (%u)\n”, GetLastError());
goto cleanup;
}
for (i = 0; i < (cb / sizeof(DWORD)); i++)
{
DWORD p = ap[i];
char label[64];
_snprintf(label, sizeof(label) - 1, “Up Time (%6u): “, p);
HANDLE hp = OpenProcess(STANDARD_RIGHTS_READ |
PROCESS_QUERY_INFORMATION,
FALSE, p);
if (!hp || (hp == INVALID_HANDLE_VALUE))
{
printf(”%s could not open process (error %u)\n”,
label, GetLastError());
continue;
}
fflush(stdout);
FILETIME ft;
FILETIME ft1;
FILETIME ft2;
FILETIME ft3;
if (GetProcessTimes(hp, &ft, &ft1, &ft2, &ft2))
{
FILETIME sft;
GetSystemTimeAsFileTime(&sft);
__int64 st = filetime_to_seconds(sft);
__int64 pt = filetime_to_seconds(ft);
if (pt)
{
print_time(label, st - pt);
}
else
{
printf(“%s no creation time\n”, label);
}
}
else
{
printf(“%s could not get times (error %u)\n”,
label, GetLastError());
}
}
cleanup:
if (ap)
free(ap);
}
void
usage(
char* progname
)
{
printf(“usage: %s [-p]\n”
" -p show process times\n",
progname);
exit(1);
}
int
main(
int argc,
char* argv
)
{
PDH_STATUS pdhStatus = ERROR_SUCCESS;
BOOL bProc = FALSE;
if (argc > 2)
usage(argv[0]);
if (argc > 1)
{
if (!strcmp(argv[1], “-p”))
{
bProc = TRUE;
}
else
{
usage(argv[0]);
}
}
pdhStatus = get_and_print_time_cv(" Awake Time: ",
“\System\System Up Time”);
if (pdhStatus)
exit(1);
pdhStatus = get_and_print_time_cv("Elapsed Time: ",
“\Process(System)\Elapsed Time”);
if (pdhStatus)
exit(1);
pdhStatus = get_and_print_time_cv("Elapsed Time: ",
“\Process(Idle)\Elapsed Time”);
if (pdhStatus)
exit(1);
if (bProc)
do_processes();
return 0;
}
—
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com</psapi.h></pdh.h></tchar.h></stdlib.h></stdio.h></malloc.h></winperf.h></windows.h>