Bri*_*ost 2 delphi dns administrator
客户在安装期间从我们的应用程序报告错误,这表示当域管理员执行安装时,下面的"IsWindowsAdministrator"中的代码返回FALSE.以本地管理员身份登录,一切正常.安装程序(Innosetup)调用exe文件,该文件执行一些服务控制管理器操作(见下文),但在调用下面的IsWindowsAdministrator以检查用户状态之后.
我想检查管理员状态的原因是在调用服务管理器任务以使用驱动程序之前提供一个优雅的错误(请参阅下面的驱动程序安装代码).这些是我在Innosetup内部不能轻易完成的任务,我选择将它们包装到安装程序调用的小exe中.
CHECK ADMIN CODE中的代码对此任务有效吗?或者我应该放弃它并将调用包装到服务控制管理器中,除非有更好的错误消息?
谢谢
=====================驱动程序安装代码========================
procedure ArtIODriver_Install( AShowSummary : boolean );
var
hServiceControlManager : THandle;
hService : SC_HANDLE;
ServiceStatus : TServiceStatus;
ServiceArgVectors : PAnsiString;
begin
If not IsWindowsAdministrator then
Raise EArtIODriver.Create(
'Error IODR4 - You must be a windows administrator to perform this action' );
If not FileExists( ArtIODriver_FilePath ) then
Raise EArtIODriver.CreateFmt(
'Error IODR7 - Unable to locate the driver file "%s"',
[ArtIODriver_FilePath] );
hService := 0;
hServiceControlManager := 0;
try
hServiceControlManager := OpenSCManager(
nil,
nil,
SC_MANAGER_ALL_ACCESS);
If hServiceControlManager = 0 then
Raise EArtIODriver.CreateFmt(
'Error IOD1 - Unable to open service control manager - %s',
[GetWinLastErrorStr] );
// can we see the service?
hService := OpenService(
hServiceControlManager,
JustDriverName,
SERVICE_ALL_ACCESS);
etc
etc
Run Code Online (Sandbox Code Playgroud)
=========检查管理员代码================
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;
Run Code Online (Sandbox Code Playgroud)
您应该简单地检查OpenSCManager()
和/或检查错误代码,而不是检查用户是否是管理员OpenService()
.如果用户没有足够的权限,GetLastError()
将返回ERROR_ACCESS_DENIED
,例如:
hServiceControlManager := OpenSCManager(
nil,
nil,
SC_MANAGER_ALL_ACCESS);
If hServiceControlManager = 0 then
Begin
If GetLastError() = ERROR_ACCESS_DENIED then
Raise EArtIODriver.Create('Error IODR4 - You must be a windows administrator to perform this action' )
else
Raise EArtIODriver.CreateFmt('Error IOD1 - Unable to open service control manager - %s', [GetWinLastErrorStr] );
End;
Run Code Online (Sandbox Code Playgroud)
我在一个应用程序中使用这种技术,该应用程序不需要大多数操作的管理员权限来检测何时在Vista +下手动调用UAC提示以获得足够的权限,并且它运行良好.
归档时间: |
|
查看次数: |
509 次 |
最近记录: |