電源オン、オフの時間の所得

解決


ちょく  2009-02-19 23:17:50  No: 33409

ログオン、ログオフの時間でもいいのですが、取得する方法を
知りたいのです。システムログから抽出できればと
漠然としか考えつかないのですが・・・
よい方法があればご教授下さい。


ちょく  2009-02-19 23:24:18  No: 33410

すみません。環境はD7.XPです。


Ru  2009-02-20 18:56:31  No: 33411

NetUserEnum  APIを使用すれば取得できそうなことは書いてますがどうでしょう?
サンプル少ないですが。もっとさがせばあるのかな?

http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=021628

http://www.delphi-si.com/clanki/clanek.php?id=3

http://www.michael-puff.de/Developer/Delphi/Units/MpuNTUser.pas

他に詳しい人がいると思いますのでその人に期待・・・


Ru  2009-02-20 19:01:47  No: 33412

おまけ
http://www2.big.or.jp/~osamu/Delphi/tips.cgi?index=0088.txt


バビアン  2009-02-20 19:56:28  No: 33413

イベントログサービスの起動/停止時間で代用?
WMIを使う?
ゴメン、そんなのしか見つからなかった。参考にして・・・


Ru  2009-02-20 23:44:14  No: 33414

すいません。
上記URL参考に試してみたんですが
方法が悪いのかlast_logonやlast_logoffに思っている値が入ってきません。

っで別の方法探していたんですが下記のURL参考に組み込んで見たところ
大分近い値を取得してきました。
ただ時間がずれているのがよく分かっていません。

ログオン時間:  2009/02/20 02:23:36
※PSECURITY_LOGON_SESSION_DATA構造体  LogonTime.QuadPart

ちなみにログオフ時間の取得方法は分かりませんでした。
参考になれば・・・

//http://www.delphipraxis.net/post711939.html
//http://pasotech.altervista.org/delphi/articolo27.htm


ofZ  2009-02-21 00:19:03  No: 33415

一年以上前に作った、ログオンユーザーの登録プログラムでの結果ですが
ログオン日時は取得できましたが、ログオフ時間が入っていませんでした。

そのときは、以下のProject JEDI のページから、LanManager.zipを落として作成しました。
http://delphi-jedi.org/apilibrary.html

> ただ時間がずれているのがよく分かっていません。
日本は9時間ずれているせいでは?

イベントログを読むのであれば、OpenEventLog、GetNumberOfEventLogRecords、
ReadEventLog、CloseEventLog  あたりで検索したら、いいサンプルがみつかるかもしれません。


ofZ  2009-02-21 00:56:08  No: 33416

イベントログサービスの開始・終了をログオン・ログオフとする場合のイベントログから読み込むサンプル。

TButtonとTMemoをおいて

type
  // Internal structure for event logs
  PEVENTLOGRECORD = ^EVENTLOGRECORD;
  EVENTLOGRECORD = packed record
    Length : DWORD;
    Reserved : DWORD;
    RecordNumber : DWORD;
    TimeGenerated : DWORD;
    TimeWritten : DWORD;
    EventID : DWORD;
    EventType : WORD;
    NumStrings : WORD;
    EventCategory : WORD;
    ReservedFlags : WORD;
    ClosingRecordNumber : DWORD;
    StringOffset : DWORD;
    UserSidLength : DWORD;
    UserSidOffset : DWORD;
    DataLength : DWORD;
    DataOffset : DWORD;
    // Then follows Variant Area .....
    // TCHAR SourceName[]
    // TCHAR Computername[]
    // SID   UserSid
    // TCHAR Strings[]
    // BYTE  Data[]
    // CHAR  Pad[]
    // DWORD Length;
  end;

  TEventLogRecord  =EVENTLOGRECORD;

const
  EVENTLOG_SEQUENTIAL_READ    = 1;
  EVENTLOG_SEEK_READ          = 2;
  EVENTLOG_FORWARDS_READ      = 4;
  EVENTLOG_BACKWARDS_READ     = 8;

function TimeGeneratedToDateTime(aTimeGenerated: DWORD): TDateTime;
const
  SecondPerDay  = 60 * 60 * 24; //一日の秒数
begin
  Result := EncodeDate(1970,1,1) + EncodeTime(9,0,0,0);
  Result := ((Result * SecondPerDay) + aTimeGenerated) / SecondPerDay;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
  //最新のログから順次読み込む
  READ_FLAG= EVENTLOG_SEQUENTIAL_READ or EVENTLOG_BACKWARDS_READ;
var
  eLogHandle: THandle;
  logCount: DWORD;
  i: Integer;
  eventID: Integer;
  pBuf: PEventLogRecord;
  bufSize: Integer;
  readNum, readNeed: DWORD;
  lastLogOn: TDateTime;
  lastLogOut: TDateTime;
begin
  eLogHandle := OpenEventLog(nil, 'System');

  //クリア
  lastLogOn := 0;
  lastLogOut := 0;
  Memo1.Lines.Clear;

  if eLogHandle > 0 then begin
    //ログ数を取得
    if not GetNumberOfEventLogRecords(eLogHandle, logCount) then
      logCount := 0;
    //メモリ確保
    bufSize := SizeOf(TEventLogRecord);
    pBuf := AllocMem(bufSize);

    for i := 1 to logCount do begin
      {読み込み}
      if not ReadEventLog(eLogHandle, READ_FLAG,
              logCount - 1, pBuf, bufSize, readNum, readNeed) then begin
       if GetLastError = ERROR_INSUFFICIENT_BUFFER then begin
         //メモリの再割り当て
         bufSize := readNeed;
         ReallocMem(pBuf, bufSize);

         if not ReadEventLog(eLogHandle, READ_FLAG,
             logCount - 1, pBuf, readNeed, readNum, readNeed) then begin
           //失敗
           Break;
         end;
       end
       else begin
         //失敗
         Break;
       end;
      end;

      eventID := pBuf^.EventID AND $FFFF;
      if eventID = 6005 then begin
       lastLogOn := TimeGeneratedToDateTime(pBuf^.TimeGenerated);
       if lastLogOut > 0 then Break;
      end
      else if eventID = 6006 then begin
       lastLogOut := TimeGeneratedToDateTime(pBuf^.TimeGenerated);
       if lastLogOn > 0 then Break;
      end;
    end;

    Memo1.Lines.Add('最終ログイン:' + FormatDateTime('yyyy/mm/dd hh:nn:ss', lastLogOn));
    Memo1.Lines.Add('最終ログオフ:' + FormatDateTime('yyyy/mm/dd hh:nn:ss', lastLogOut));

    //メモリ開放
    FreeMem(pBuf);
    //ログを閉じる
    CloseEventLog(eLogHandle);
  end;
end;

細かいとこわかってないので、突っ込んだ質問には答えられません。


Ru  2009-02-21 02:45:10  No: 33417

> 日本は9時間ずれているせいでは?
なるほど。再ログインしたところたしかに9時間ずれていました。

イベントログの方法試してみました。
このログイン、ログアウトの時間はPC起動時,シャットダウン時の物かも?
今、再ログインしても時間に変化がなかったものですので。
でもこれは,質問主さんの電源のOF,OFFに相当するのでこれでいいのかな。


ちょく  2009-02-21 08:30:10  No: 33418

皆さんに私のやってること以上に調べて頂いたり、詳細なソースまで
のせいていただき恐縮です。最終的にクライアントごとにデータを
集積したいのですが…
まずはofzさんのPGで試してみます。
有難うございます。


ちょく  2009-02-21 09:19:50  No: 33419

ofZさん。希望どうりでした。有難うございました。
Ruさん。本当にいろいろ有難うございました。
クライアントごとには自分で考えないとまずいかな…
解決とさせて頂きます。
バビアンさんも有難うございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加