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.
View Code

单一实例的判断。

posted @ 2017-11-13 11:00  A_dan  阅读(1141)  评论(0编辑  收藏  举报