如何知道Windows系統開運作時間(如果開機超過49.7天) |
尚未結案
|
guru1979
一般會員 發表:1 回覆:0 積分:0 註冊:2005-03-06 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
guru1979: 如果您不是非要在程式中計算開機使用時間的話,可以使用名為 uptime 的工具程式來獲得相關資訊,這種程式很多,您可以使用 uptime 為關鍵字透過搜尋引擎找到不少,Microsoft 也有提供指令行 (Command Line) 工具,我在 MS 網站的搜尋框輸入 uptime 字樣所找到的程式僅有 46KB (支援 NT4 SP4 或更新的系統),您參考一下吧。 附註:
1. 既然該程式能獲知開機使用時間,那麼理論上應該也可以由自己撰寫程式來取得的,如果您需要將該功能寫在程式內的話,或許也可以試著透過網路來找找相關資訊。 2. 如果必須要在程式內使用該功能,而且也急著用的話,那麼不妨再找到相關資料之前,先由程式內呼叫 uptime.exe 來執行,然後將輸出結果導向至一個文字檔,再由程式讀入該文字檔,這樣子就可以拆解出相關數據來使用了。
|
brook
資深會員 發表:57 回覆:323 積分:371 註冊:2002-07-12 發送簡訊給我 |
|
chris_shieh
高階會員 發表:46 回覆:308 積分:240 註冊:2004-04-26 發送簡訊給我 |
如果還是想要用原來方法
那就先把得到的天數存起來囉
var Form1: TForm1; preTickCount :DWORD; UpDays:Extended; //TDatetime bProcessDWORDLimit:Boolean; implementation {$R *.dfm} uses ...Math, DateUtil... function TimeStrInBetween(time1, time2: TDatetime):String; var days, year,mon,day, h, m, s, ms:Word; begin DivMod(DaysBetween(time1, time2), 365 , year, days); //精簡一下 DivMod(days, 30, mon, day); //精簡一下 DecodeTime(time1-time2,h,m,s,ms); Result:=Format('%d 年, %d 月, %d 日, %d 小時, %d 分, %d 秒', [year, mon, day, h, m, s]); end; procedure TForm1.Timer1Timer(Sender: TObject); var dtElapse:TDatetime; begin if (not bProcessDWORDLimit) and ((MAXDWORD - GetTickCount)<=10000) then //到49.7天10秒前先將天數存起來 begin UpDays:=MAXDWORD / (1000*60*60*24); //約等於49.7天後面有一堆小數點 preTickCount:=GetTickCount; bProcessDWORDLimit:=True; end; if bProcessDWORDLimit and ((GetTickCount-preTickCount)<0) then //預存天數後 歸零發生 bProcessDWORDLimit:=False; dtElapse:=UpDays GetTickCount / (1000*60*60*24); Label1.Caption:=TimeStrInBetween(0, dtElapse); end;不過這方法遇到GetTickCount歸零過的電腦就沒用拉 真正要得到這個訊息 根據Delphi 所附的Windows SDK Help 可以去讀取registry, Windows會一直去update HKEY_PERFORMANCE_DATA 內的 資料 [GetTickCount] Windows NT: To obtain the time elapsed since the computer was started, look up the System Up Time counter in the performance data in the registry key HKEY_PERFORMANCE_DATA. The value returned is an 8 byte value. 可以參考這裡有完整的函式與範例 http://www.delphipraxis.net/topic16973.html //////////////////////////////////////////////////////////////////////////////// // // GetSystemUpTimeNt() // // Uses the registry interface to get the value of the performance counter // '\\localhost\System\System Up Time' in milliseconds (returns 0 on error). // function GetSystemUpTimeNt(): Int64; {$IFDEF WIN32} type PPerfDataBlock = ^TPerfDataBlock; TPerfDataBlock = packed record Signature : array [0..3] of WCHAR; LittleEndian : DWORD; Version : DWORD; Revision : DWORD; TotalByteLength : DWORD; HeaderLength : DWORD; NumObjectTypes : DWORD; DefaultObject : DWORD; SystemTime : SYSTEMTIME; PerfTime : LARGE_INTEGER; PerfFreq : LARGE_INTEGER; PerfTime100nSec : LARGE_INTEGER; SystemNameLength: DWORD; SystemNameOffset: DWORD; end; PPerfObjectType = ^TPerfObjectType; TPerfObjectType = packed record TotalByteLength : DWORD; DefinitionLength : DWORD; HeaderLength : DWORD; ObjectNameTitleIndex: DWORD; ObjectNameTitle : LPWSTR; ObjectHelpTitleIndex: DWORD; ObjectHelpTitle : LPWSTR; DetailLevel : DWORD; NumCounters : DWORD; DefaultCounter : DWORD; NumInstances : DWORD; CodePage : DWORD; PerfTime : LARGE_INTEGER; PerfFreq : LARGE_INTEGER; end; PPerfCounterDefinition = ^TPerfCounterDefinition; TPerfCounterDefinition = packed record ByteLength : DWORD; CounterNameTitleIndex: DWORD; CounterNameTitle : LPWSTR; CounterHelpTitleIndex: DWORD; CounterHelpTitle : LPWSTR; DefaultScale : DWORD; DetailLevel : DWORD; CounterType : DWORD; CounterSize : DWORD; CounterOffset : DWORD; end; PPerfInstanceDefinition = ^TPerfInstanceDefinition; TPerfInstanceDefinition = packed record ByteLength : DWORD; ParentObjectTitleIndex: DWORD; ParentObjectInstance : DWORD; UniqueID : DWORD; NameOffset : DWORD; NameLength : DWORD; end; PLARGE_INTEGER = ^LARGE_INTEGER; const PERF_SIZE_LARGE = $00000100; PERF_TYPE_COUNTER = $00000400; PERF_COUNTER_ELAPSED = $00040000; PERF_OBJECT_TIMER = $00200000; PERF_DISPLAY_SECONDS = $30000000; PERF_ELAPSED_TIME = PERF_SIZE_LARGE or PERF_TYPE_COUNTER or PERF_COUNTER_ELAPSED or PERF_OBJECT_TIMER or PERF_DISPLAY_SECONDS; PERF_NO_INSTANCES = DWORD(-1); var ValSize: DWORD; Counter: PChar; CurrIdx: PChar; CurrStr: PChar; CntrStr: PChar; CntrSys: DWORD; CntrSUT: DWORD; QrySize: DWORD; QryData: PPerfDataBlock; CurrObj: PPerfObjectType; ObjLoop: DWORD; CurrDef: PPerfCounterDefinition; DefLoop: DWORD; ObjInst: PPerfInstanceDefinition; CntrVal: PLARGE_INTEGER; {$ENDIF} begin Result := 0; // indicates failure {$IFDEF WIN32} ValSize := 0; if (RegQueryValueEx(HKEY_PERFORMANCE_DATA, 'Counter 009', nil, nil, nil, @ValSize) = ERROR_SUCCESS) then try Inc(ValSize, 1024); Counter := GetMemory(ValSize); if (Counter <> nil) then try if (RegQueryValueEx(HKEY_PERFORMANCE_DATA, 'Counter 009', nil, nil, PByte(Counter), @ValSize) = ERROR_SUCCESS) then begin CntrStr := nil; CntrSys := 0; CntrSUT := 0; CurrIdx := Counter; while (CurrIdx[0] <> #0) do begin CurrStr := PChar(@CurrIdx[StrLen(CurrIdx) 1]); if ((CntrSys = 0) and (StrComp(CurrStr, 'System') = 0)) then begin CntrStr := CurrIdx; CntrSys := StrToInt(string(CurrIdx)); if (CntrSUT <> 0) then Break; end; if ((CntrSUT = 0) and (StrComp(CurrStr, 'System Up Time') = 0)) then begin CntrSUT := StrToInt(string(CurrIdx)); if (CntrSys <> 0) then Break; end; CurrIdx := PChar(@CurrStr[StrLen(CurrStr) 1]); end; if ((CntrStr <> nil) and (CntrSys <> 0) and (CntrSUT <> 0)) then begin QrySize := 0; QryData := nil; try repeat Inc(QrySize, 4096); QryData := ReallocMemory(QryData, QrySize); if (QryData = nil) then Break; ValSize := QrySize; until (RegQueryValueEx(HKEY_PERFORMANCE_DATA, CntrStr, nil, nil, PByte(QryData), @ValSize) <> ERROR_MORE_DATA); if ((ValSize > 0) and (QryData <> nil)) then if (QryData.Signature = 'PERF') then begin CurrObj := PPerfObjectType(Cardinal(QryData) QryData.HeaderLength); for ObjLoop := 1 to QryData.NumObjectTypes do begin if ((CurrObj.ObjectNameTitleIndex = CntrSys) and (CurrObj.NumInstances > 0) and (CurrObj.PerfFreq.QuadPart >= 1000)) then begin CurrDef := PPerfCounterDefinition(Cardinal(CurrObj) CurrObj.HeaderLength); for DefLoop := 1 to CurrObj.NumCounters do begin if (CurrDef.CounterNameTitleIndex = CntrSUT) and (CurrDef.CounterType = PERF_ELAPSED_TIME) then begin if (CurrObj.NumInstances = PERF_NO_INSTANCES) then CntrVal := PLARGE_INTEGER(Cardinal(CurrObj) CurrObj.DefinitionLength CurrDef.CounterOffset) else begin // first instance ObjInst := PPerfInstanceDefinition(Cardinal(CurrObj) CurrObj.DefinitionLength); CntrVal := PLARGE_INTEGER(Cardinal(ObjInst) ObjInst.ByteLength CurrDef.CounterOffset); end; Result := (CurrObj.PerfTime.QuadPart - CntrVal.QuadPart) div (CurrObj.PerfFreq.QuadPart div 1000); // milliseconds Break; end; CurrDef := PPerfCounterDefinition(Cardinal(CurrDef) CurrDef.ByteLength); end; Break; end; CurrObj := PPerfObjectType(Cardinal(CurrObj) CurrObj.TotalByteLength); end; end; finally if (QryData <> nil) then FreeMemory(QryData); end; end; end; finally FreeMemory(Counter); end; finally RegCloseKey(HKEY_PERFORMANCE_DATA); end; {$ENDIF} end; //////////////////////////////////////////////////////////////////////////////// // // GetSystemUpTime9x() // // Uses GetTickCount() to get the 'System Up Time' in milliseconds. // Will wrap around to zero if the system is run continuously for 49.7 days! // function GetSystemUpTime9x(): Int64; begin {$IFDEF WIN32} Result := GetTickCount(); {$ELSE} Result := 0; {$ENDIF} end; //////////////////////////////////////////////////////////////////////////////// // // GetSystemUpTime() // // Wrapper for GetSystemUpTimeNt() and GetSystemUpTime9x() // function GetSystemUpTime(): Int64; begin Result := GetSystemUpTimeNt(); if (Result = 0) then Result := GetSystemUpTime9x(); end; //////////////////////////////////////////////////////////////////////////////// // Sample procedure TForm1.Button1Click(Sender: TObject); var UpTimeNt: Int64; UpTime9x: Int64; begin UpTime9x := GetSystemUpTime9x(); UpTimeNt := GetSystemUpTimeNt(); ShowMessage(Format('GetTickCount: %d day(s) %2.2d:%2.2d:%2.2d.%3.3d'#10 'Perf-Counter: %d day(s) %2.2d:%2.2d:%2.2d.%3.3d', [UpTime9x div 86400000, UpTime9x mod 86400000 div 3600000, UpTime9x mod 3600000 div 60000, UpTime9x mod 60000 div 1000, UpTime9x mod 1000, UpTimeNt div 86400000, UpTimeNt mod 86400000 div 3600000, UpTimeNt mod 3600000 div 60000, UpTimeNt mod 60000 div 1000, UpTimeNt mod 1000])); end;@瞭解越多.懂得越少@ |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |