Get System UpTime - Remotely on NT systems

Hello Experts.

How is it possible to use either these functions or access to
get the remote system uptime?

Do any have examples for this?

HKEY_PERFORMANCE_DATA
NetStatisticsGet

Thanks, ETJ.
visexpertAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ivanov_GCommented:
Get Windows uptime?
http://www.swissdelphicenter.ch/torry/showcode.php?id=56

1) You can compile the code in a stand-alone console application. The enable Telnet Service and do it like this:
     - connect via telnet
     - execute the console application
     - parse the text and extract uptime
2) Use sockets... Listening socket on the target machine which write uptime OnConnect.
0
visexpertAuthor Commented:
Hello.

Thanks for your response.

Is it possible to get this remote against NT computers
via the remote registry and HKEY_PERFORMANCE_DATA?
0
Imthiyaz_phCommented:
The following code will help you. I have taken the code from
http://www.luckie-online.de/Delphi/Sonstiges/GetTickCountEx.html
and modified a bit for remote registry access.

function GetSystemUpTimeNt(sMachine: string): 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}
  RemoteKey: HKey;
begin
  Result := 0;  // indicates failure

  if RegConnectRegistry(PChar(sMachine), HKEY_PERFORMANCE_DATA, RemoteKey) <> ERROR_SUCCESS then
    Exit;

{$IFDEF WIN32}
  ValSize := 0;
  if (RegQueryValueEx(RemoteKey, 'Counter 009', nil, nil, nil,
    @ValSize) = ERROR_SUCCESS) then
  try
    Inc(ValSize, 1024);
    Counter := GetMemory(ValSize);
    if (Counter <> nil) then
    try
      if (RegQueryValueEx(RemoteKey, '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(RemoteKey, 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(RemoteKey);
  end;
{$ENDIF}
end;
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

Ivanov_GCommented:
> "Is it possible to get this remote against NT computers via the remote registry and HKEY_PERFORMANCE_DATA?"

Yes, It is. But the it is related to security issues. Your user may not have permission to access the registry. If the users are in domain, Active Directory, etc...
0
visexpertAuthor Commented:
Great, now the final. Is it possible to translate the value to days, hours etc... and maybe
return it as string value?

Thanks,
0
visexpertAuthor Commented:
100. Points extra for that part.
0
Imthiyaz_phCommented:
function TicksToString(Tick: Int64): string;
var
  Seconds, Minutes, Hours, Days, Weeks : integer;
begin
  // Tick to Seconds
  Seconds := Tick div 1000 mod 60;
  // Tick to Minutes
  Minutes := Tick div 1000 div 60 mod 60;
  // Tick to Hours
  Hours := Tick div 1000 div 60 div 60 mod 24;
  // Tick to Days
  Days := Tick div 1000 div 60 div 60 div 24 mod 7;
  // Tick to Weeks
  Weeks := Tick div 1000 div 60 div 60 div 24 div 7 mod 52;

  Result := Format('%d Days / %d Hours / %d Minutes / %d Seconds',
    [Days, Hours, Minutes, Seconds]);
end;
0
visexpertAuthor Commented:
Thank you, really appreciated!.

P.S: I don't find out how to raise points by 100. :-(
0
Imthiyaz_phCommented:
No problem with points
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.