Windows95/98/NT4でユーザログオンの前にプログラムを実行する。

 Windowsのユーザログオン前(ユーザ名とパスワード入力のダイアログが表示される前)にプログラムを実行する場合に参考にしてください。
 Windows95/98/NT4に共通して使用出来る方法として、レジストリへ登録する方法があります。

 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion 内にrunというキーがあります。
 
 この中に適当な名前で文字列を作成し、実行したいプログラムをフルパスで設定するだけでWindowsのログオン前に実行出来るようになります。
 自動バックアッププログラム等,Windowsが起動中であるもののログロンしていない状態でも定期的に実行したいものを起動する場合に使用すると便利ですね(ちなみに拙作MiBackupの初期のバージョンでは、ここで起動させて自動バックアップが出来るようになっていました。常駐サイズが大きいのでやめてしまいましたが...)。

 また、runキーの他にRunOnceというキーも存在します。これは読んで時の如し、ここにプログラムを登録すると、Windowsが起動したときに一度だけ実行します。一度実行されると、ここに登録されているデータは自動的に消去されます。これはWindows95/98の場合には、Windowsフォルダにwininit.iniファイルを作成して、その中に実行するコマンドを記述することでも実現出来ますが、NT4の場合には使用出来ません。
 このRunOnceキーへのデータ登録を行うことで、Windows95/98/NTに関らない実行が保証されます。
 なお、ここに登録出来るのは実行プログラムだけではなく、DOSのバッチファイルを登録しても正常に動作します(DOS窓が開き、実行後に閉じます)。
 このRunOnceは、例えば新しいバージョンのプログラムをインストールする際に、以前のバージョンのファイルがWindowsにロックされており再起動しないと書き換えられない場合等,Windowsの再起動後に一度だけ処理させたいプログラム等がある場合に用いることが出来ます。

 以下はDLLファイルを更新する際にWindowsがロックしており、すぐに更新出来ない場合にRunOnceを用いるというサンプルです。拙作MiGrepのインストールプログラムで使用したコードです。
 ここでは書き換えようとするDLL名をMiGrep.Dll,新しいDLLは$MiGrep.Dllとします(新しいDLLは書換えに失敗しないように、最初は違う名前にしておきます)。。

function InstDll(const DestPath: string): Boolean;
var
  srcdate, dstdate: integer;
  path, srcname, dstname: string;
  inif: TStringList;
  reg: TRegistry;
begin
  // DestPathで渡されたインストール先のパス名をコピーする
  // 汎用化する場合にはDLLファイル名も渡す様にすべきですね
  path := DestPath;
  // 新しいファイル名と元のファイル名のフルパス名を作成
  srcname := path + '$MiGrep.dll';
  dstname := path + 'MiGrep.dll';
  // すでにMiGrep.Dllが存在しているかチェックする
  if FileExists(dstname) then
  begin
    // お互いのタイムスタンプを取得する
    dstdate := FileAge(dstname);
    srcdate := FileAge(srcname);
    // 新しいDLLをインストールしようとしているかチェック
    if srcdate > dstdate then
    begin
      // 元のファイルを削除出来た場合には、$MiGrep.DllをMiGrep.Dllに変更する
      if DeleteFile(dstname) then
        RenameFile(srcname, dstname);
      // 変更に失敗($MiGrep.Dllが未だ存在している)した場合には...
      if FileExists(srcname) then
      begin
        // 再起動後に実行するバッチファイルを構築する
        inif := TStringList.Create;
        // MiGrep.Dllを削除
        inif.Add('DEL "' + dstname + '"');
        // $MiGrep.DllをMiGrep.Dllに変更
        inif.Add('REN "' + srcname + '" "MiGrep.dll"');
        // inst.batという名前で保存する
        inif.SaveToFile(path + 'inst.bat');
        inif.Free;
        // レジストリに書込みする
        reg := TRegistry.Create;
        reg.RootKey := HKEY_LOCAL_MACHINE;
        if reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\RunOnce',
            False) then
        begin
          try
            // RunOneceにMiGrepInstという文字列を作成し、inst.batを登録する
            reg.WriteString('MiGrepInst', path + 'inst.bat');
            Result := True;
          except
            // ここでMessageBoxを使用しているのは、Formを用いずサイズの小さな実行ファイルを
            // 作成するため。また当然ApplicationやFormのハンドルがないので、代りにhInstance
            // を使用している。
            // もしFormを使用するプログラムの場合には、MessageDlgを使ったほうが便利でしょう。
            MessageBox(hInstance, PChar('レジストリ書込みに失敗しました.'),
                       PChar('失敗'), 0);
            Result := False;
          end;
        end else begin
          MessageBox(hInstance, PChar('レジストリをオープン出来ませんでした.'),
                     PChar('失敗'), 0);
          Result := False;
        end;
        reg.Free;
      end;
    // MiGrep.Dllと$MiGrep.Dllが同じ日付だったら、$MiGrep.Dllを削除する
    end else begin
      DeleteFile(srcname);
      Result := False;
    end;
  // MiGrep.Dllが存在していない場合(初めてのインストール)には$MiGrep.DllをMiGrep.Dllに変更する
  end else begin
    RenameFile(srcname, dstname);
    Result := False;
  end;
end;

※このインストールプログラムのソース(Delphi3.1用)が欲しいという方はメールを頂ければ差し上げます。

戻る