?
Solved

Uptime past 49.7 days (without using GetTickCount)

Posted on 2004-03-24
25
Medium Priority
?
1,628 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 150 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 300 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

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.

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
Suggested Courses
Course of the Month11 days, 12 hours left to enroll

752 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