2011-06-07 75 views
8

我找工作顯然德爾福7碼這樣我就可以檢查我的程序是否啓動具有管理員權限尋找Delphi 7代碼來檢測程序是否以管理員權限啓動?

在此先感謝

[---重要更新---]

審查後的答案到目前爲止的代碼,我意識到,我的問題也許不是那麼清楚,或者在至少是不完整的:

  • 我想知道我的德爾福7程序是否開始與「以管理員身份運行」複選框,設置

  • 換句話說:我想知道是否有可能對我的德爾福7程序,在C創建/更新文件:\ Program Files文件夾...

只是檢查您是否擁有管理員權限是不夠的。

+0

接受的方式做到這一點是需要管理員需要編寫任何程序來體現到程序文件目錄。 – 2011-06-20 18:38:14

+0

據我所知,管理員權限足以創建/更新c:\ program files中的文件! – Andreas 2011-06-30 15:04:49

+0

@Andreas:並非如此,你必須用'以管理員身份運行'選項啓動程序。我在我的開發電腦上擁有完整的管理員權限,但無法在c:\ program files中創建/更新文件...除非我使用'運行廣告管理'來啓動它。因爲相同的程序(一種網頁更新程序的方式)可以運行或不運行'以管理員身份運行'我應該能夠檢查這種狀態。 – Edelcom 2011-06-30 15:45:08

回答

5

項目JEDI的JEDI Code Library在JclSecurity單元中有一個IsAdministrator函數,它會告訴你。它仍然在Delphi 7中工作。

1

此代碼在D7..XE inc下工作。

function IsWindowsAdministrator: Boolean; 
// Returns TRUE if the user has administrator priveleges 
// Returns a boolean indicating whether or not user has admin 
// privileges. Call only when running under NT. Win9.x will return false! 
var 
    hAccessToken  : tHandle; 
    ptgGroups   : pTokenGroups; 
    dwInfoBufferSize : DWORD; 
    psidAdministrators : PSID; 
    int    : integer;   // counter 
    blnResult   : boolean;   // return flag 

const 
    SECURITY_NT_AUTHORITY: SID_IDENTIFIER_AUTHORITY = 
    (Value: (0,0,0,0,0,5)); // ntifs 
    SECURITY_BUILTIN_DOMAIN_RID: DWORD = $00000020; 
    DOMAIN_ALIAS_RID_ADMINS: DWORD = $00000220; 
    DOMAIN_ALIAS_RID_USERS : DWORD = $00000221; 
    DOMAIN_ALIAS_RID_GUESTS: DWORD = $00000222; 
    DOMAIN_ALIAS_RID_POWER_: DWORD = $00000223; 

begin 
    Result := False; 
    blnResult := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, 
           True, hAccessToken); 
    if (not blnResult) then 
    begin 
    if GetLastError = ERROR_NO_TOKEN then 
    blnResult := OpenProcessToken(GetCurrentProcess, 
         TOKEN_QUERY, hAccessToken); 
    end; 

    ptgGroups := nil; 

    if (blnResult) then 
    try 

    GetMem(ptgGroups, 1024); 
    blnResult := GetTokenInformation(hAccessToken, TokenGroups, 
             ptgGroups, 1024, 
             dwInfoBufferSize); 
    CloseHandle(hAccessToken); 

    if (blnResult) then 
    begin 

     AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, 
           SECURITY_BUILTIN_DOMAIN_RID, 
           DOMAIN_ALIAS_RID_ADMINS, 
        0, 0, 0, 0, 0, 0, 
        psidAdministrators); 
     {$IFOPT R+} 
     {$DEFINE RMINUS} 
     {$R-} 
     {$ENDIF} 
     for int := 0 to ptgGroups.GroupCount - 1 do 

     if EqualSid(psidAdministrators, 
        ptgGroups.Groups[ int ].Sid) then 
     begin 
      Result := True; 
      Break; 
     end; 
     {$IFDEF IMINUS} 
     {$R-} 
     {$UNDEF IMINUS} 
     {$ENDIF} 

     FreeSid(psidAdministrators); 
    end; 

    finally 
    If ptgGroups <> nil then 
     FreeMem(ptgGroups); 
    end; 
end; 
+2

此代碼檢查您是否是管理員組的成員。此代碼的問題是您可以成爲管理員組的成員,但沒有任何管理權限。同樣,您可以擁有管理員權限,但不能成爲管理員組的成員。這個函數可能更好地稱爲「IsMemberOfAdministratorsGroup」,理解爲屬於管理員組的一部分並不意味着您擁有管理員權限。 – 2011-06-12 01:14:22

+0

-1,這個函數被不同的ppl一遍又一遍地粘貼,正如Ian Boyd已經說過的那樣,只檢查一個是否是管理員組的成員。 – Remko 2011-12-01 09:16:02

15

在Windows API(使用)有一個輔助功能(IsUserAnAdmin)告訴如果您正在使用管理權限運行。

OS    Account Type UAC   IsUserAdmin 
============== ============= ============ =========== 
Windows XP  Standard  n/a   False 
Windows XP  Administrator n/a   True 
Windows Vista Standard  Disabled  False 
Windows Vista Administrator Disabled  True 
Windows Vista Standard  Not Elevated False 
Windows Vista Administrator Not Elevated False 
Windows Vista Standard  Elevated  True 
Windows Vista Administrator Elevated  True 

不推薦使用Shell32包裝函數;這是很好的,因爲它只是a wrapper around other code, which you can still call自己:

function IsUserAdmin: Boolean; 
var 
    b: BOOL; 
    AdministratorsGroup: PSID; 
begin 
    { 
    This function returns true if you are currently running with admin privileges. 
    In Vista and later, if you are non-elevated, this function will return false 
    (you are not running with administrative privileges). 
    If you *are* running elevated, then IsUserAdmin will return true, as you are 
    running with admin privileges. 

    Windows provides this similar function in Shell32.IsUserAnAdmin. 
    But the function is deprecated, and this code is lifted 
    from the docs for CheckTokenMembership: 
     http://msdn.microsoft.com/en-us/library/aa376389.aspx 
    } 

    { 
    Routine Description: This routine returns TRUE if the callers 
    process is a member of the Administrators local group. Caller is NOT 
    expected to be impersonating anyone and is expected to be able to 
    open its own process and process token. 
     Arguments: None. 
     Return Value: 
     TRUE - Caller has Administrators local group. 
     FALSE - Caller does not have Administrators local group. 
    } 
    b := AllocateAndInitializeSid(
     SECURITY_NT_AUTHORITY, 
     2, //2 sub-authorities 
     SECURITY_BUILTIN_DOMAIN_RID, //sub-authority 0 
     DOMAIN_ALIAS_RID_ADMINS,  //sub-authority 1 
     0, 0, 0, 0, 0, 0,    //sub-authorities 2-7 not passed 
     AdministratorsGroup); 
    if (b) then 
    begin 
    if not CheckTokenMembership(0, AdministratorsGroup, b) then 
     b := False; 
     FreeSid(AdministratorsGroup); 
    end; 

    Result := b; 
end; 

換句話說:該功能爲您提供您想要的答案:不能更新程序文件。

你需要厭倦代碼,檢查你是否是管理員組的成員。您可以成爲管理員組的一員,但不具有任何管理權限。您也可以擁有管理權限,但不能成爲管理員組的一部分。

4
program Project1; 

{$APPTYPE CONSOLE} 

uses 
    Windows, 
    ShellAPI; 

// high-level wrapper, see Ian Boyd's answer for details on this function 
function IsUserAnAdmin(): BOOL; external shell32; 

begin 
    if IsUserAnAdmin() then 
    Writeln('TEH R00T OMG') 
    else 
    Writeln('rtfmnoobkthx'); 

    Readln; 
end. 
3

Microsoft推薦的解決此問題的方法:將應用程序拆分爲兩部分。

http://msdn.microsoft.com/en-us/library/aa511445.aspx

第一應用程序檢查它是否必須運行第二個。

第二個應用程序包含一個「require admin」清單(如David寫的),並用ShellExecuteEx'runas'動詞打開它。

在網頁更新的情況下,工作流程可能是這樣的:

Updater1.exe

  1. 檢查是否有可用的更新。
  2. (可選)詢問用戶是否要安裝更新。
  3. 將更新下載到臨時位置。
  4. 用ShellExecuteEx和'runas'動詞運行Updater2.exe。

Updater2.exe

  1. 將得到UAC evalated如果用戶確認的提示或將無法在所有的運行。
  2. 然後可以將文件從臨時位置複製到最終位置。

這有幾個優點:

  • 的Updater2只包含要跑升高的最低操作。
  • Updater2可以是下載文件的一部分。
  • 有沒有必要檢查任何特權,UAC負責照顧。

它也適用於Windows XP,如果您不是管理員,您會看到一個登錄對話框。

2

Jwscl(Jedi Windows安全庫)具有此功能:JwCheckAdministratorAccess

function JwCheckAdministratorAccess: boolean; 

用法很簡單:

Uses 
    JwsclToken; 

IsElevated := JwCheckAdministratorAccess; 

此功能也適用於Windows Vista和以後如果啓用UAC。如果當前進程未提升,即使令牌包含管理員組(當時被禁用),返回值也是錯誤的。該功能可以檢測管理員組中的組成員身份,這意味着用戶不需要直接在管理員組中,而是可以成爲管理員組的成員。

+0

對不起回覆老問題,不知道我是怎麼到這裏但沒有注意到 – Remko 2011-12-01 13:59:42

2

我測試了這個代碼用Delphi 7,在Windows XP,Windows 7和8(管理員和有限賬戶):

Function CheckTokenMembership(TokenHandle: THandle; SIdToCheck: PSID; var IsMember: Boolean): Boolean; StdCall; External AdvApi32; 

Function IsAdmin: Boolean; 
const 
    DOMAIN_ALIAS_RID_ADMINS = $00000220; 
    SECURITY_BUILTIN_DOMAIN_RID = $00000020; 
    SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5)); 
var 
    Admin: Boolean; 
    AdmGroup: PSID; 
Begin 
    Admin := AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 
    2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 
    0, 0, 0, 0, 0, 0, AdmGroup); 
    If (Admin) Then 
    Begin 
    If (not CheckTokenMembership(0, AdmGroup, Admin)) Then 
     Admin := False; 
    FreeSid(AdmGroup); 
    end; 
    Result := Admin; 
end; 
相關問題