2011-12-30 28 views
2

私のアプリは実行時にいくつかの特権操作を行う必要があります。たとえば、ユーザーが初めてアプリケーションを実行するときは、仮想ドライブを作成してフォーマットする必要があります。私は文書化されていないapi formatexを使って仲間の仕事をしていますが、formatexには管理者権限が必要です。 OSがVista以上の場合は、「COM Elevation Moniker」というUACダイアログを表示しても問題ありません。しかし、XPでは、この手法は適切ではないので、私は偽装メソッドを使用します。私はwin xpの下で実行時に自分のプロセスを昇格することができます

CredUIPromptForCredentials() -> prompt to get administrator credentials 
LogonUser() 
ImpersonateLoggedOnUser() 
formatex() 
RevertToSelf() 

formatexはまだ、もちろん ...失敗し、管理者が作品を意志としての私のアプリを実行しますが、それは私のアプリがインストールされている、良いではありません。アプリは限らユーザーとして実行され 場合、私はこのようなフォーマットしますかたとえユーザーが の限定ユーザーであっても、現在のユーザーコンテキストで動作するはずのマシンごとではなく、ユーザーごとに表示されます。

私は正しくformating仕事をするために実行時に私のアプリを上げることができますか?いずれかの助け?

答えて

2

解決策は、実際のフォーマットを実行するように指示された昇格された権限とコマンドラインパラメータでアプリケーションを再実行することです。

コード例:私は私のアプリで何をすべきかです

if (!IsUserAdmin()) { 
    RunAsAdmin(hwnd, exeName, "--do-format"); 
} else { 
    DoFormat(); 
} 
... 

BOOL RunAsAdmin(HWND hWnd, LPCTSTR lpFile, LPCTSTR lpParameters) 
{ 
    SHELLEXECUTEINFO sei; 
    ZeroMemory(&sei, sizeof(sei)); 

    sei.cbSize   = sizeof(SHELLEXECUTEINFOW); 
    sei.hwnd   = hWnd; 
    sei.fMask   = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI; 
    sei.lpVerb   = _TEXT("runas"); 
    sei.lpFile   = lpFile; 
    sei.lpParameters = lpParameters; 
    sei.nShow   = SW_SHOWNORMAL; 

    if (!ShellExecuteEx(&sei)) { 
      return FALSE; 
    } 
    return TRUE; 
} 

BOOL IsUserAdmin(VOID) 
{ 
    BOOL b; 
    SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY }; 
    PSID AdministratorsGroup; 
    b = AllocateAndInitializeSid(
      &NtAuthority, 
      2, 
      SECURITY_BUILTIN_DOMAIN_RID, 
      DOMAIN_ALIAS_RID_ADMINS, 
      0, 0, 0, 0, 0, 0, 
      &AdministratorsGroup); 
    if (b) { 
      if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) { 
        b = FALSE; 
      } 
      FreeSid(AdministratorsGroup); 
    } 

    return b; 
} 
+0

(ただし、IsUserAdmin()チェックなし - 私はWin32 API関数が私の代わりに 'ERROR_ELEVATION_NEEDED'を報告しましょう)、そしてそれは非常に動作しますよく –

+0

ディミトリの答えをありがとう。私は、ディミトリによって提案された方法を使用して終了しましたが、少し異なります。私は、CredUIPromptForCredentials() - > LogonUser() - > IsUserAdmin(私の関数) - > CreateProcessWithLogonWループを使用して、管理者の資格を確保します。すべてが今すぐうまくいく。 – toki

関連する問題