Delphi 判断exe是否以管理员身份启动
1 1:获取程序运行的用户名 2 function GetProcessIdentity(): String; 3 var 4 hToken: THandle; 5 UserName, UserDomain: String; 6 cbName, cbDomainName: ULONG; 7 ReturnLength: DWORD; 8 Buff: array of Byte; 9 tu: PTokenUser; 10 peUse: SID_NAME_USE; 11 label 12 Cleanup; 13 begin 14 Result := ''; 15 // 打开进程令牌 16 if not OpenProcessToken(GetCurrentProcess, MAXIMUM_ALLOWED, hToken) then Exit; 17 18 // 查询用户账户令牌 19 20 // 首先获取需要的缓冲区大小 21 if not GetTokenInformation(hToken, TokenUser, nil, 0, ReturnLength) then 22 if GetLastError = ERROR_INSUFFICIENT_BUFFER then 23 begin 24 // 设置缓冲区大小 25 SetLength(Buff, ReturnLength); 26 // 获取数据 27 GetTokenInformation(hToken, TokenUser, @Buff[0], ReturnLength, ReturnLength); 28 tu := PTokenUser(@Buff[0]); 29 end 30 else 31 goto Cleanup 32 else 33 goto Cleanup; 34 35 // 通过 SID 查询用户名及登陆域 36 cbName := 0; 37 cbDomainName := 0; 38 // 获取需要的缓冲区大小 39 if not LookupAccountSid(nil, tu.User.Sid, nil, cbName, nil, cbDomainName, peUse) then 40 if GetLastError = ERROR_INSUFFICIENT_BUFFER then 41 begin 42 // 设置字符串长度(包含 NULL 字符) 43 SetLength(UserName, cbName); 44 SetLength(UserDomain, cbDomainName); 45 // 获取数据 46 if LookupAccountSid(nil, tu.User.Sid, @UserName[1], cbName, @UserDomain[1], cbDomainName, peUse) then 47 begin 48 // 截去最后的 NULL 字符 49 SetLength(UserName, cbName); 50 SetLength(UserDomain, cbDomainName); 51 end 52 else 53 goto Cleanup; 54 end 55 else 56 goto Cleanup 57 else 58 goto Cleanup; 59 60 // 组合信息 61 Result := UserDomain + '\' + UserName; 62 63 Cleanup: 64 // 关闭令牌 65 CloseHandle(hToken); 66 end; 67 68 2:获取用户是否以管理员模式运行 69 function GetProcessIsAdmin(): Boolean; //获取用户是否以管理员模式运行 70 const 71 SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = ( 72 value: (0, 0, 0, 0, 0, 5) 73 ); 74 SECURITY_BUILTIN_DOMAIN_RID = $00000020; 75 DOMAIN_ALIAS_RID_ADMINS = $00000220; 76 var 77 hAccessToken: THandle; 78 ptgGroups: PTokenGroups; 79 dwInfoBufferSize: DWORD; 80 psidAdministrators: PSID; 81 x: Integer; 82 bSuccess: BOOL; 83 begin 84 Result := False; 85 bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, hAccessToken); 86 if not bSuccess then 87 begin 88 if GetLastError = ERROR_NO_TOKEN then 89 bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hAccessToken); 90 end; 91 if bSuccess then 92 begin 93 GetMem(ptgGroups, 1024); 94 bSuccess := GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, 1024, dwInfoBufferSize); 95 CloseHandle(hAccessToken); 96 if bSuccess then 97 begin 98 AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, psidAdministrators); 99 {$R-} //关闭边界检查 100 for x := 0 to ptgGroups.GroupCount - 1 do 101 if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then 102 begin 103 Result := True; 104 Break; 105 end; 106 {$R+} 107 FreeSid(psidAdministrators); 108 end; 109 FreeMem(ptgGroups); 110 end; 111 end;
用Delphi编写的exe,vista系统及以上系统,启动exe需要管理员权限只要添加uac,xp系统不支持uac,需要判断是否是管理员身份启动。
1 var 2 mutex: HWND; 3 4 begin 5 if not GetProcessIsAdmin() then //判断是否以管理员启动 6 begin 7 Application.MessageBox('请以管理员身份启动', '警告', MB_ICONWARNING + MB_OK); 8 end 9 else 10 begin 11 mutex := CreateMutex(nil, False, ‘Global\xxx’); { 创建单一实例 } 12 if ((mutex <> 0) and (GetLastError() = ERROR_ALREADY_EXISTS)) then 13 begin 14 Application.MessageBox('程序已经运行', '警告', MB_ICONWARNING + MB_OK); 15 end 16 else 17 begin 18 Application.Initialize; 19 Application.MainFormOnTaskbar := True; 20 Application.Title := 'xxx'; 21 Application.CreateForm(TfrmMain, frmMain); 22 Application.ShowMainForm := False; 23 Application.Run; 24 end; 25 end; 26 end.
单一实例的判断。