After you run the application with administrator privileges, programs running with ShellExecute in this application inherit administrator permission. But this is not what I want: it just needs to start regularly without additional permissions. ShellExecute accepts OPEN (regular) and RUNAS (administrator). But if you use OPEN after you run the application as an administrator, it still acts like RUNAS .
The following example demonstrates this: if you run it using regular permissions, it says "Start normal". As soon as you press 1 for "admin", it will start as an administrator. If you press 2 in the newly created invitation, it will not start the โregularโ invitation, but the โAdministratorโ prompt will appear again.
I found something about some parameters in RUNAS ( https://superuser.com/a/374866 ), but they cannot be passed to ShellExecute . Any ideas?
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.