40

実行時にいくつかの設定を HKEY_LOCAL_MACHINE に変更する必要があります。

実行時に必要に応じて uac の昇格を要求することはできますか?それとも、「汚れた作業」を行うために昇格した 2 つ目のプロセスを起動する必要がありますか?

4

4 に答える 4

26

私は自分自身を昇格して再起動し、昇格したことを示すコマンドラインパラメーターを渡します。その後、適切なフォームに直接ジャンプするか、HKLM のものを保存するだけです。

function RunAsAdmin(hWnd: HWND; filename: string; Parameters: string): Boolean;
{
    See Step 3: Redesign for UAC Compatibility (UAC)
    http://msdn.microsoft.com/en-us/library/bb756922.aspx

    This code is released into the public domain. No attribution required.
}
var
    sei: TShellExecuteInfo;
begin
    ZeroMemory(@sei, SizeOf(sei));
    sei.cbSize := SizeOf(TShellExecuteInfo);
    sei.Wnd := hwnd;
    sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
    sei.lpVerb := PChar('runas');
    sei.lpFile := PChar(Filename); // PAnsiChar;
    if parameters <> '' then
        sei.lpParameters := PChar(parameters); // PAnsiChar;
    sei.nShow := SW_SHOWNORMAL; //Integer;

    Result := ShellExecuteEx(@sei);
end;

マイクロソフトが推奨するもう 1 つの解決策は、(特別に作成された CoCreateInstanceAsAdmin 関数を使用して) COM オブジェクトをアウト プロセスで作成することです。COMオブジェクトを作成して登録する必要があるため、このアイデアは好きではありません。


注:「CoCreateInstanceAsAdmin」API 呼び出しはありません。それはただのコードが浮かんでいるだけです。これが私がつまずいたDephiバージョンです。通常は非表示のコードが内部的にCoGetObjectを呼び出すときに、クラス GUID 文字列の前に " Elevation:Administrator!new: " プレフィックスを付けるトリックに基づいているようです。

function CoGetObject(pszName: PWideChar; pBindOptions: PBindOpts3; 
      const iid: TIID; ppv: PPointer): HResult; stdcall; external 'ole32.dll';

procedure CoCreateInstanceAsAdmin(const Handle: HWND; 
      const ClassID, IID: TGuid; PInterface: PPointer);
var
   BindOpts: TBindOpts3;
   MonikerName: WideString;
   Res: HRESULT;
begin
   //This code is released into the public domain. No attribution required.
   ZeroMemory(@BindOpts, Sizeof(TBindOpts3));
   BindOpts.cbStruct := Sizeof(TBindOpts3);
   BindOpts.hwnd := Handle;
   BindOpts.dwClassContext := CLSCTX_LOCAL_SERVER;

   MonikerName := 'Elevation:Administrator!new:' + GUIDToString(ClassID);

   Res := CoGetObject(PWideChar(MonikerName), @BindOpts, IID, PInterface);
   if Failed(Res) then 
      raise Exception.Create(SysErrorMessage(Res));
end;

もう 1 つの質問: Windows XP で標準ユーザーとして実行しているユーザーをどのように処理しますか?

于 2009-06-05T19:11:06.747 に答える