管理者権限でアプリケーションを起動すると、そのアプリケーションでShellExecute
を使用して実行されたプログラムは管理者権限を継承します。しかし、それは私が望むものではありません。余分なパーミッションなしで定期的に開始するだけです。 ShellExecute
は、パラメータOPEN
(通常)とRUNAS
(管理者)を受け入れます。しかし、管理者としてアプリケーションを起動した後にOPEN
を使用すると、それでもRUNAS
のように動作します。管理者権限のないアプリケーションの起動
次の例はこれを示しています。正規のアクセス権で起動すると、「Started regular」と表示されます。 「管理者」のために1を押すと、管理者として開始されます。新しく作成したプロンプトで2を押すと、「通常の」プロンプトは表示されませんが、「管理者」プロンプトが再度表示されます。
RUNAS(https://superuser.com/a/374866)でいくつかのパラメータについて知りましたが、ShellExecute
で渡すことはできません。何か案は?
program WindowsPrivilegeTest;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Winapi.Windows,
Winapi.ShellAPI;
function CheckTokenMembership(TokenHandle: THANDLE; SidToCheck: Pointer; var
IsMember: BOOL): BOOL; stdcall; external advapi32 name 'CheckTokenMembership';
// Source: http://stackoverflow.com/a/28572886/1870208
function IsAdministrator: Boolean;
var
psidAdmin: Pointer;
B: BOOL;
const
SECURITY_NT_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
SE_GROUP_USE_FOR_DENY_ONLY = $00000010;
begin
psidAdmin := nil;
try
Win32Check(AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
psidAdmin));
if CheckTokenMembership(0, psidAdmin, B) then
Result := B
else
Result := False;
finally
if psidAdmin <> nil then
FreeSid(psidAdmin);
end;
end;
var
lLine : String;
lOperation : PChar;
begin
try
if IsAdministrator then
begin
Writeln('Started as administrator');
end
else
begin
Writeln('Started regular');
end;
while True do
begin
Writeln('');
Writeln('How to start? 1 = admin, 2 = regular user. Type number and press enter');
ReadLn(lLine);
lOperation := '';
if lLine = '1' then
begin
lOperation := 'RUNAS';
end
else
if lLine = '2' then
begin
lOperation := 'OPEN';
end;
if lOperation <> '' then
begin
ShellExecute(0, lOperation, PChar(ParamStr(0)), nil, nil, SW_SHOWNORMAL);
Break;
end;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
返される投票には、正しい方法ではないという質問の答えとして、正しい方法はプロセストークンを取得することです。トークンを取得するためには 'TokenLinkedToken'パラメータで' GetTokenInformation'を呼び出します非溶けたトークン。そのトークンを使用して新しいプロセスを起動します。明らかに、UACが実際に有効になっているかどうかもチェックしてください(http://www.remkoweijnen.nl/blog/2011/08/11/gettokeninformation-with-tokenlinkedtoken-returns-error-1312/)。 – Remko