Jak pobrać uptime pod Windowsem

0

Witam.
Na wstępie powiem, że z Windowsami mam mało do czynienia i niestety błądzę w tym temacie. Szukam jakiegoś kodu, który pozwoli mi pobrać czas pracy systemu Windows. Doszedłem do takiego czegoś:

#include <windows.h>
#include <stdio.h>
int main()
{
int time = 0;
time = GetTickCount();
printf("%i", time);
return(time);
}

Jednak z tego co czytałem to licznik przekręca się po 49 dniach. Byłbym wdzięczny za jakieś inne linki, źródła programów. Interesuje mnie C/C++.

0

Tam też sprawdzałem i większość ma: Limited to only 49 days. Pod Linuksem to jest prosto...
Znalazłe jeszcze takie coś: http://www.grzegorz.net/programowanie/uptime.zip
Kod wykląda całkiem, całkiem... pytanie czy działa. Pod Linuksem to ciężko sprawdzić.
Szukam dalej. Może ktoś ma jeszcze jakieś przykłady?

0

Dorwalem cos takiego:

#include <stdio.h>
#include <windows.h>
#include <string.h>

char* GetUptime()
{
 
   int tickCount,nTime[5];
   char szUptime[1000];
   tickCount  = GetTickCount();
   nTime[0]  = tickCount / 1000 % 60;          // Seconds
   nTime[1]  = tickCount / 1000 / 60 % 60;        // Minutes
   nTime[2]  = tickCount / 1000 / 60 / 60 % 24;      // Hours
   nTime[3]  = tickCount / 1000 / 60 / 60 / 24 % 7;    // Days
   nTime[4]  = tickCount / 1000 / 60 / 60 / 24 / 7 % 52;  // Weeks
   memset(szUptime, 0, sizeof(szUptime));
   for(int i = 4; i >= 0; i--)
   {
         char*  szLabel;
         char  tmpUptime[4];
if    (i == 4) (nTime[4] > 1 || nTime[4] == 0) ?  szLabel = " Weeks, "  : szLabel = " Week, ";
else if  (i == 3) (nTime[3] > 1 || nTime[3] == 0) ?  szLabel = " Days, "    : szLabel = " Day, ";
else if  (i == 2) (nTime[2] > 1 || nTime[2] == 0) ?  szLabel = " Hours, "  : szLabel = " Hour, ";
else if  (i == 1) (nTime[1] > 1 || nTime[1] == 0) ?  szLabel = " Minutes, "  : szLabel = " Minute, ";
else if  (i == 0) (nTime[0] > 1 || nTime[0] == 0) ?  szLabel = " Seconds"  : szLabel = " Second";
memset(tmpUptime, 0, sizeof(tmpUptime));
itoa(nTime[i], tmpUptime, 10);
strcat(strcat(szUptime, tmpUptime), szLabel);
   }
   return szUptime;
}

void main()
{

	while(getchar() !=' ')
	{
		printf("%s\n",GetUptime());
	}

}
0

Hmmm..... Ale ten program korzysta z: GetTickCount() a podobno ta funkcja przekręca się po 49 dniach. Niestety nie mam możliwości tego sprawdzić. Nikt z moich znajomych nie ma Windowsa z takim uptime. Gdyby się dało jakoś zasymulować i sprawdzić to.....

0

Można pobrać date ostatniej modyfikacji jakiegoś pliku systemowego aktualizowanego tylko podczas uruchamiania. Obliczoną różnice porównać z GetTickCount i wybrać to co większe.

0

Remarks
The elapsed time is stored as a DWORD value. Therefore, the time will wrap around to zero if the system is run continuously for 49.7 days.

If you need a higher resolution timer, use a multimedia timer or a high-resolution timer.

To obtain the time elapsed since the computer was started, retrieve the System Up Time counter in the performance data in the registry key HKEY_PERFORMANCE_DATA. The value returned is an 8-byte value. For more information, see Performance Monitoring.

0
Valarius napisał(a)

retrieve the System Up Time counter in the performance data in the registry key HKEY_PERFORMANCE_DATA. The value returned is an 8-byte value. For more information, see Performance Monitoring.

Pokaż jak wyciągnąć te 8 bajtów z rejestru pod kluczem HKEY_PERFORMANCE_DATA.
Jest tam dużo liczników: odczyty dysku, pamięci, itp.,
ale nie widzę tam nic podobnego do 'System Up Time counter'.

0

Coś czytałem o tych rejestrach, ale niestety nie mam dostępu w ogóle do Windowsa. Jeżeli są tam przechowywane różne tego typu dane to będę szczęśliwy jak ktoś zna sposób by je wyciągnąć :)

0

Nie mogę znaleźć HKEY_PERFORMANCE_DATA w Windowsie XP 8-O

@Edit

You won't find this key by looking in the Registry Editor; this key is available only programmatically through the Windows registry functions, such as RegQueryValueEx. Performance information isn't actually stored in the registry; the registry functions use this key to locate the information from performance data providers.

Masakra z tymi Windowsami ;]

// skoro juz przeszedles męke i znasz odpowiedz, to fajnie byloby, gdybys wrzucil gotową funkcję do faq. [mf]

0
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <pdh.h>

char* GetUptime(int iTickCount);


#define SAMPLE_INTERVAL_MS  1000
#define MAXPATH 80

int __cdecl _tmain (int argc, TCHAR **argv)
{

   HQUERY          hQuery;
   HCOUNTER        *pCounterHandle;
   PDH_STATUS      pdhStatus;
   PDH_FMT_COUNTERVALUE   fmtValue;
   DWORD           ctrType;
   SYSTEMTIME      stSampleTime;
   PDH_BROWSE_DLG_CONFIG  BrowseDlgData;
   CHAR            szPathBuffer[MAXPATH];
   int             nRetCode = 0;

   // Open the query object.
   pdhStatus = PdhOpenQuery (0, 0, &hQuery);

   // Allocate the counter handle array. Allocate room for
   //  one handle per command line arg, not including the
   //  executable file name.
   pCounterHandle = (HCOUNTER *)GlobalAlloc(GPTR, sizeof(HCOUNTER));



   strcpy(szPathBuffer,"\\System\\System Up Time");
   

   pdhStatus = PdhAddCounter (hQuery,
	   szPathBuffer, 
	   0, 
	   pCounterHandle);

   // "Prime" counters that need two values to display a 
   //   formatted value.
   pdhStatus = PdhCollectQueryData (hQuery);

   // Print counter values until a key is pressed.
   while (!_kbhit()) {

	   // Wait one interval.
	   Sleep(SAMPLE_INTERVAL_MS);

	   // Get the sample time.
	   GetLocalTime (&stSampleTime);

	   // Get the current data values.
	   pdhStatus = PdhCollectQueryData (hQuery);

	   // Print the time stamp for the sample.
	   _tprintf (TEXT("\n %2.2d/%2.2d/%4.4d %2.2d:%2.2d:%2.2d.%3.3d "),
		   stSampleTime.wMonth, 
		   stSampleTime.wDay, 
		   stSampleTime.wYear,
		   stSampleTime.wHour, 
		   stSampleTime.wMinute, 
		   stSampleTime.wSecond,
		   stSampleTime.wMilliseconds);

	   // Get the current value of this counter.
	   pdhStatus = PdhGetFormattedCounterValue (*pCounterHandle,
		   PDH_FMT_DOUBLE,
		   &ctrType,
		   &fmtValue);

	   if (pdhStatus == ERROR_SUCCESS) {
		   //_tprintf (TEXT(",\"%.20g\""), fmtValue.doubleValue);
			_tprintf(TEXT(", %s"),GetUptime((int)fmtValue.doubleValue));
	   } else {

		   // Print the error value.
		   _tprintf (TEXT(".\"-1\"")); 
	   }
   }

   // Close the query.
   pdhStatus = PdhCloseQuery (hQuery);

   return nRetCode;
}


char* GetUptime(int tickCount)
{
	int nTime[5];
	char szUptime[1000];
	
	nTime[0]  = tickCount % 60;          // Seconds
	nTime[1]  = tickCount / 60 % 60;        // Minutes
	nTime[2]  = tickCount  / 60 / 60 % 24;      // Hours
	nTime[3]  = tickCount  / 60 / 60 / 24 % 7;    // Days
	nTime[4]  = tickCount  / 60 / 60 / 24 / 7 % 52;  // Weeks
	memset(szUptime, 0, sizeof(szUptime));
	for(int i = 4; i >= 0; i--)
	{
		char*  szLabel;
		char  tmpUptime[4];
		if    (i == 4) (nTime[4] > 1 || nTime[4] == 0) ?  szLabel = " Weeks, "  : szLabel = " Week, ";
		else if  (i == 3) (nTime[3] > 1 || nTime[3] == 0) ?  szLabel = " Days, "    : szLabel = " Day, ";
		else if  (i == 2) (nTime[2] > 1 || nTime[2] == 0) ?  szLabel = " Hours, "  : szLabel = " Hour, ";
		else if  (i == 1) (nTime[1] > 1 || nTime[1] == 0) ?  szLabel = " Minutes, "  : szLabel = " Minute, ";
		else if  (i == 0) (nTime[0] > 1 || nTime[0] == 0) ?  szLabel = " Seconds"  : szLabel = " Second";
		memset(tmpUptime, 0, sizeof(tmpUptime));
		itoa(nTime[i], tmpUptime, 10);
		strcat(strcat(szUptime, tmpUptime), szLabel);
	}
	return szUptime;
}

Sprawdz to ;)
nie dam glowy ze sie nie przekreci licznik po tych 49.7 dniach :)
ale kod jest z msdn.

0

Valarius, dzięki, ale podobny kod dałem w moim 3 poście.
Jutro będę sprawdzał co się da. Jadę specjalnie do narzeczonej tylko po to by siedzieć przed XPkiem i bawić się C++. Zabije mnie :]

Rozwiązania jeszcze nie mam. Poza uptime interesuje mnie jeszcze kilka innych danych, ale jak z tym sobie poradzę to reszta pewnie pójdzie z górki i dam coś do FAQ.

0

Po co takie cudactwa - tu wystarczy użyć GetProcessTimes i odczytać datę startu explorera.

Dla pewności można przelecieć po wszystkich procesach i znaleźć najstarszy - EnumProcesses

0

nie, kazdy procesz mozna ubic, łącznie z explorerem, jesli microsoft nie pomyślał o ułątwieniach dla programistów i trzeba wykonać hocki, aby pobrac rzeczywisty uptime, to trzeba wykonac.

0
flabra napisał(a)

kazdy procesz mozna ubic, łącznie z explorerem
Nie każdy, w XP procesy CSRSS.EXE, LSASS.EXE, SERVICES.EXE, SMSS.EXE, WINLOGON.EXE są nie do ubicia z poziomu menadżera zadań "To jest ktytyczny proces systemu. Menager zadań nie może zakończyć tego procesu.". Nie wiem jak z ubijaniem programowo, ale wydaje mi sie, że po zabiciu takiego procesu pokaże się okienko informujące o błędzie kryrtycznym i konieczności zamknięcia systemu z 30...29...28... sekund.

0

nie, można zabić wszystkie
gdyby było inaczej to nie wyłączysz komputera, a wiadomo - perpetum mobile nie istnieje. [rotfl]

0
fiak napisał(a)

nie, można zabić wszystkie
gdyby było inaczej to nie wyłączysz komputera, a wiadomo - perpetum mobile nie istnieje. [rotfl]
Ale jak zamyka sie system to uptime już nie jest potrzebny, niektóre procesy muszą działać podczas pracy systemu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1