1:获取程序运行的用户名
function GetProcessIdentity(): String;
var
hToken: THandle;
UserName, UserDomain: String;
cbName, cbDomainName: ULONG;
ReturnLength: DWORD;
Buff: array of Byte;
tu: PTokenUser;
peUse: SID_NAME_USE;
label
Cleanup;
begin
Result := '';
// 打开进程令牌
if not OpenProcessToken(GetCurrentProcess, MAXIMUM_ALLOWED, hToken) then Exit;
// 查询用户账户令牌
// 首先获取需要的缓冲区大小
if not GetTokenInformation(hToken, TokenUser, nil, 0, ReturnLength) then
if GetLastError = ERROR_INSUFFICIENT_BUFFER then
begin
// 设置缓冲区大小
SetLength(Buff, ReturnLength);
// 获取数据
GetTokenInformation(hToken, TokenUser, @Buff[0], ReturnLength, ReturnLength);
tu := PTokenUser(@Buff[0]);
end
else
goto Cleanup
else
goto Cleanup;
// 通过 SID 查询用户名及登陆域
cbName := 0;
cbDomainName := 0;
// 获取需要的缓冲区大小
if not LookupAccountSid(nil, tu.User.Sid, nil, cbName, nil, cbDomainName, peUse) then
if GetLastError = ERROR_INSUFFICIENT_BUFFER then
begin
// 设置字符串长度(包含 NULL 字符)
SetLength(UserName, cbName);
SetLength(UserDomain, cbDomainName);
// 获取数据
if LookupAccountSid(nil, tu.User.Sid, @UserName[1], cbName, @UserDomain[1], cbDomainName, peUse) then
begin
// 截去最后的 NULL 字符
SetLength(UserName, cbName);
SetLength(UserDomain, cbDomainName);
end
else
goto Cleanup;
end
else
goto Cleanup
else
goto Cleanup;
// 组合信息
Result := UserDomain + '\' + UserName;
Cleanup:
// 关闭令牌
CloseHandle(hToken);
end;
2:获取用户是否以管理员模式运行
function GetProcessIsAdmin(): Boolean; //获取用户是否以管理员模式运行
const
SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (
value: (0, 0, 0, 0, 0, 5)
);
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
var
hAccessToken: THandle;
ptgGroups: PTokenGroups;
dwInfoBufferSize: DWORD;
psidAdministrators: PSID;
x: Integer;
bSuccess: BOOL;
begin
Result := False;
bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, hAccessToken);
if not bSuccess then
begin
if GetLastError = ERROR_NO_TOKEN then
bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hAccessToken);
end;
if bSuccess then
begin
GetMem(ptgGroups, 1024);
bSuccess := GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, 1024, dwInfoBufferSize);
CloseHandle(hAccessToken);
if bSuccess then
begin
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, psidAdministrators);
{$R-} //关闭边界检查
for x := 0 to ptgGroups.GroupCount - 1 do
if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
begin
Result := True;
Break;
end;
{$R+}
FreeSid(psidAdministrators);
end;
FreeMem(ptgGroups);
end;
end;
用Delphi编写的exe,win8系统及以上系统,启动exe需要管理员权限只要添加uac,xp系统不支持uac,需要判断是否是管理员身份启动。
var
mutex: HWND;
begin
if not GetProcessIsAdmin() then //判断是否以管理员启动
begin
Application.MessageBox('请以管理员身份启动', '警告', MB_ICONWARNING + MB_OK);
end
else
begin
mutex := CreateMutex(nil, False, ‘Global\xxx’); { 创建单一实例 }
if ((mutex <> 0) and (GetLastError() = ERROR_ALREADY_EXISTS)) then
begin
Application.MessageBox('程序已经运行', '警告', MB_ICONWARNING + MB_OK);
end
else
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.Title := 'xxx';
Application.CreateForm(TfrmMain, frmMain);
Application.ShowMainForm := False;
Application.Run;
end;
end;
end.