Solved

Uptime past 49.7 days (without using GetTickCount)

Posted on 2004-03-24
25
1,559 Views
Last Modified: 2007-12-19
I want to get the system uptime.. I can't use GetTickCount because it returns a 32-bit integer, resulting in a wraparound after 49.7 days.

I've read that using the registry root HKEY_PERFORMANCE_DATA you can read the system uptime (using RegQueryValueEx) but I'm not sure how to go about it.. the stuff over at MSDN isn't very helpful and I haven't managed to find any sample Delphi code anywhere.

Any help appreciated :)

nem2k4
0
Comment
Question by:nem2k4
  • 12
  • 10
  • 3
25 Comments
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10673153
Maybe this can help you.....

 Delphi 3.0 Performance Data Viewer for NT

 displays a tree view of the data held in the dynamic HKEY_PERFORMANCE_DATA registry hive.  
The download  includes components which encapsulate the performance data - including source, and a demo program.

http://www.wilsonc.demon.co.uk/delphi3.htm#NT%20Specific%20Components

Shane

0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10673154
Maybe this can help you.....

 Delphi 3.0 Performance Data Viewer for NT

 displays a tree view of the data held in the dynamic HKEY_PERFORMANCE_DATA registry hive.  
The download  includes components which encapsulate the performance data - including source, and a demo program.

http://www.wilsonc.demon.co.uk/delphi3.htm#NT%20Specific%20Components

Shane

0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10673202
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:nem2k4
ID: 10673300
Thanks.. http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20047646.html?query=HKEY_PERFORMANCE_DATA&searchType=topic has the same problem I'm having - how do you actually query it (concrete code)?


The Performance Data Viewer displays perfmon info which is handy but there's no uptime statistic in there.. it uses HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\PerfLib\009
0
 
LVL 11

Assisted Solution

by:shaneholmes
shaneholmes earned 50 total points
ID: 10673336
hmmmm,

I' have never dove into that far into the registry (i.e. HKEY_PERFORMANCE_DATA key).

Nor have I had any inclination to use the system uptime, but i did find some example code on how to use
 RegQueryValueEx in another delphi example ....


Maybe you can use this....

Shane

Here is an example which reads the content of the "CommonFilesDir" value under "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion"

procedure TForm1.Button1Click(Sender: TObject);
var
  hReg: Integer;
  dwType, BufSize: DWORD;
  pBuf: array[0..MAX_PATH] of Char;
begin
  if RegOpenKey(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Windows\CurrentVersion', hReg) = ERROR_SUCCESS then begin
    BufSize := MAX_PATH;
    RegQueryValueEx(hReg, 'CommonFilesDir', nil, @dwType, @pBuf, @BufSize);
    if (dwType = REG_SZ) then ShowMessage(string(PChar(@pBuf)));
    RegCloseKey(hReg);
  end;
end;
0
 

Author Comment

by:nem2k4
ID: 10673510
Thanks, I'll try that... what do I use in place of 'Software\Microsoft\Windows\CurrentVersion' though? :)
0
 

Author Comment

by:nem2k4
ID: 10673559
(and 'CommonFilesDir' ?)
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10673560
You may be able to use an empty string "", try that

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10673574
CommonFilesDir is what you are looking for.

This is the key to you query, cause if your gonna query for something, ya have to know what your querying for, in this case, the name which holds the value your looking for.

Again, since i've never dealt in to that part of the Registry, i dont have a clue where in that Key (HKEY_PERFORMANCE_DATA) it exists.

There are a lot of experts on in the morning, so you may want to wait until then to see if any will jump in here and help you with this issue.

Shane


0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10673576
Im sorry, i should explain more....

"CommonFilesDir" should be relaced with what you are looking for


Shane
0
 

Author Comment

by:nem2k4
ID: 10673593
Using this code:



procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  hReg: HKEY;
  dwType, BufSize: DWORD;
  pBuf: array[0..MAX_PATH] of Char;
begin
  if RegOpenKey(HKEY_PERFORMANCE_DATA, '', hReg) = ERROR_SUCCESS then begin
    BufSize := MAX_PATH;
    RegQueryValueEx(hReg, 'CommonFilesDir', nil, @dwType, @pBuf, @BufSize);
    if (dwType = REG_SZ) then ShowMessage(string(PChar(@pBuf)));
    RegCloseKey(hReg);
  end else
    showmessage('unsuccessful');
end;


I just get the message "unsuccessful".
0
 

Author Comment

by:nem2k4
ID: 10673600
Yeah, that's the problem.. I don't know the exact names of what the names of the things I am looking for either.
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10673637
Yeah, thats why i was saying, wait till morning, maybe some of the other experts will no some of the names of the things your looking for. Im still looking myself though...

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10673651
0
 

Author Comment

by:nem2k4
ID: 10673773
craig_capel's stuff down the bottom looks promising, but according to him it doesn't quite work?

Perhaps using the code you posted, we can use "\\compname\System\System Up Time" as the key value?

The other stuff isn't suitable cuz you have to have a seperate program run on startup etc, my app needs to be self-contained.
0
 

Author Comment

by:nem2k4
ID: 10673782
some thing like:

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  hReg: HKEY;
  dwType, BufSize: DWORD;
  pBuf: array[0..MAX_PATH] of Char;
begin
  if RegOpenKey(HKEY_PERFORMANCE_DATA, 'System', hReg) = ERROR_SUCCESS then begin
    BufSize := MAX_PATH;
    RegQueryValueEx(hReg, 'System Up Time', nil, @dwType, @pBuf, @BufSize);
    if (dwType = REG_SZ) then ShowMessage(string(PChar(@pBuf)));
    RegCloseKey(hReg);
  end else
    showmessage('unsuccessful');
end;


? (doesn't work, but maybe with some tweaking..)
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10673852

Some thing like this below, but if that worked, that would only give us the key to open, we would still need to know the name  of the Value, in order to extract its data

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  hReg: HKEY;
  dwType, BufSize: DWORD;
  pBuf: array[0..MAX_PATH] of Char;
begin
  if RegOpenKey(HKEY_PERFORMANCE_DATA, '\compname\System\System Up Time', hReg) = ERROR_SUCCESS then begin
    BufSize := MAX_PATH;
    RegQueryValueEx(hReg, 'NAME OF VALUE HERE', nil, @dwType, @pBuf, @BufSize);
    if (dwType = REG_SZ) then ShowMessage(string(PChar(@pBuf)));
    RegCloseKey(hReg);
  end else
    showmessage('unsuccessful');
end;


unless its this...


procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  hReg: HKEY;
  dwType, BufSize: DWORD;
  pBuf: array[0..MAX_PATH] of Char;
begin
  if RegOpenKey(HKEY_PERFORMANCE_DATA, '\compname\System', hReg) = ERROR_SUCCESS then begin
    BufSize := MAX_PATH;
    RegQueryValueEx(hReg, 'System Up Time', nil, @dwType, @pBuf, @BufSize);
    if (dwType = REG_SZ) then ShowMessage(string(PChar(@pBuf)));
    RegCloseKey(hReg);
  end else
    showmessage('unsuccessful');

Shane
end;
0
 

Author Comment

by:nem2k4
ID: 10674122
2nd one doesn't work..
0
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 100 total points
ID: 10674734
I use this and it works perfectly:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    txtUptime: TEdit;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses DateUtils;

{$R *.dfm}

function GetTickCount: Int64;
var
  nTime, freq: Int64;
begin
  if Windows.QueryPerformanceFrequency(freq) then
    if Windows.QueryPerformanceCounter(nTime) then
       result:=Trunc(nTime/Freq*1000)
    else
       result:= Windows.GetTickCount
  else
    result:= Windows.GetTickCount;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var dt: TDateTime;
begin
     dt:=0;
     dt:=IncMilliSecond(dt, GetTickCount);
     txtUptime.Text:=Format('%d d %s', [DaysBetween(dt, 0), FormatDateTime('hh:nn:ss', dt)]);
     txtUptime.SelectAll;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
     Timer1Timer(Sender);
end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
     if Key = VK_ESCAPE then
        Close;
end;

end.
0
 

Author Comment

by:nem2k4
ID: 10675066
That works well Lee_Nover, only one thing that bothers me about it - it seems to return the uptime 10 seconds shorter than what it should be (I'm comparing this uptime method you gave to the Windows Uptime application ( http://www.rundegren.com/software/windowsuptime/ ) which seems to be the standard.
0
 

Author Comment

by:nem2k4
ID: 10675080
(Sorry to be picky but my users are.. well.. even more picky!)
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 10675133
just tested .. both display the same value .. with an offset of ~0,5 sec because of the apps timers being out of sync
and are there any records of that app displaying uptimes beyond 50 days ?
0
 

Author Comment

by:nem2k4
ID: 10675155
Hmm.. is there any reason why you use

dt:=IncMilliSecond(dt, GetTickCount);

instead of

dt:=GetTickCount;

?
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 10675177
ofcourse .. left of the decimal are days ! check what IncMillisecond does
0
 

Author Comment

by:nem2k4
ID: 10675223
Sorry, I was just trying to work out why the uptimes differ for this app and Windows Uptime for my computer.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question