我找工作(顯然)德爾福7碼這樣我就可以檢查我的程序是否啓動具有管理員權限。尋找Delphi 7代碼來檢測程序是否以管理員權限啓動?
在此先感謝
[---重要更新---]
審查後的答案到目前爲止的代碼,我意識到,我的問題也許不是那麼清楚,或者在至少是不完整的:
我想知道我的德爾福7程序是否開始與「以管理員身份運行」複選框,設置。
換句話說:我想知道是否有可能對我的德爾福7程序,在C創建/更新文件:\ Program Files文件夾...。
只是檢查您是否擁有管理員權限是不夠的。
我找工作(顯然)德爾福7碼這樣我就可以檢查我的程序是否啓動具有管理員權限。尋找Delphi 7代碼來檢測程序是否以管理員權限啓動?
在此先感謝
[---重要更新---]
審查後的答案到目前爲止的代碼,我意識到,我的問題也許不是那麼清楚,或者在至少是不完整的:
我想知道我的德爾福7程序是否開始與「以管理員身份運行」複選框,設置。
換句話說:我想知道是否有可能對我的德爾福7程序,在C創建/更新文件:\ Program Files文件夾...。
只是檢查您是否擁有管理員權限是不夠的。
項目JEDI的JEDI Code Library在JclSecurity單元中有一個IsAdministrator函數,它會告訴你。它仍然在Delphi 7中工作。
此代碼在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;
此代碼檢查您是否是管理員組的成員。此代碼的問題是您可以成爲管理員組的成員,但沒有任何管理權限。同樣,您可以擁有管理員權限,但不能成爲管理員組的成員。這個函數可能更好地稱爲「IsMemberOfAdministratorsGroup」,理解爲屬於管理員組的一部分並不意味着您擁有管理員權限。 – 2011-06-12 01:14:22
-1,這個函數被不同的ppl一遍又一遍地粘貼,正如Ian Boyd已經說過的那樣,只檢查一個是否是管理員組的成員。 – Remko 2011-12-01 09:16:02
在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;
換句話說:該功能爲您提供您想要的答案:不能更新程序文件。
你需要厭倦代碼,檢查你是否是管理員組的成員。您可以成爲管理員組的一員,但不具有任何管理權限。您也可以擁有管理權限,但不能成爲管理員組的一部分。
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.
Microsoft推薦的解決此問題的方法:將應用程序拆分爲兩部分。
http://msdn.microsoft.com/en-us/library/aa511445.aspx
第一應用程序檢查它是否必須運行第二個。
第二個應用程序包含一個「require admin」清單(如David寫的),並用ShellExecuteEx'runas'動詞打開它。
在網頁更新的情況下,工作流程可能是這樣的:
Updater1.exe
Updater2.exe
這有幾個優點:
它也適用於Windows XP,如果您不是管理員,您會看到一個登錄對話框。
Jwscl(Jedi Windows安全庫)具有此功能:JwCheckAdministratorAccess。
function JwCheckAdministratorAccess: boolean;
用法很簡單:
Uses
JwsclToken;
IsElevated := JwCheckAdministratorAccess;
此功能也適用於Windows Vista和以後如果啓用UAC。如果當前進程未提升,即使令牌包含管理員組(當時被禁用),返回值也是錯誤的。該功能可以檢測管理員組中的組成員身份,這意味着用戶不需要直接在管理員組中,而是可以成爲管理員組的成員。
對不起回覆老問題,不知道我是怎麼到這裏但沒有注意到 – Remko 2011-12-01 13:59:42
我測試了這個代碼用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;
接受的方式做到這一點是需要管理員需要編寫任何程序來體現到程序文件目錄。 – 2011-06-20 18:38:14
據我所知,管理員權限足以創建/更新c:\ program files中的文件! – Andreas 2011-06-30 15:04:49
@Andreas:並非如此,你必須用'以管理員身份運行'選項啓動程序。我在我的開發電腦上擁有完整的管理員權限,但無法在c:\ program files中創建/更新文件...除非我使用'運行廣告管理'來啓動它。因爲相同的程序(一種網頁更新程序的方式)可以運行或不運行'以管理員身份運行'我應該能夠檢查這種狀態。 – Edelcom 2011-06-30 15:45:08