ThomasRiedelDk 0 Posted February 27 I am trying to run a Win32.exe from inside a service application, - trying to make a servicemanager similar to NSSM. I try with AppPath = 'C:\Windows\notepad.exe', I get an error like: "Required privilege missing". Any clous? function TMyService.StartProcessAsUser(const AppPath: string): Boolean; var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; SecAttr: TSecurityAttributes; hToken, hDupToken: THandle; UserName, Password, Domain: string; begin Result := False; if LogonUser(PChar(FUserName), PChar(FDomain), PChar(FPassword), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken) then begin if DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, nil, SecurityImpersonation, TokenPrimary, hDupToken) then begin ZeroMemory(@StartupInfo, SizeOf(TStartupInfo)); StartupInfo.cb := SizeOf(TStartupInfo); StartupInfo.lpDesktop := PChar('Winsta0\Default'); StartupInfo.dwFlags := STARTF_USESHOWWINDOW; StartupInfo.wShowWindow := SW_show; if CreateProcessAsUser(hDupToken, PChar(AppPath), nil, nil, nil, False, CREATE_NEW_CONSOLE or CREATE_UNICODE_ENVIRONMENT, nil, nil, StartupInfo, ProcessInfo) then begin Result := True; CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); end else begin var ErrCode := GetLastError(); var errormsg : string; SetLength(ErrorMsg, 512); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS, nil, ErrCode, 0, PChar(ErrorMsg), Length(ErrorMsg), nil); ShowMessage('Fejl ved start af proces: ' + ErrorMsg); end; CloseHandle(hDupToken); end; CloseHandle(hToken); end; end; function SetTokenPrivilege(const APrivilege: string; const AEnable: Boolean = true): Boolean; var LToken: THandle; LTokenPriv: TOKEN_PRIVILEGES; LPrevTokenPriv: TOKEN_PRIVILEGES; LLength: Cardinal; LErrval: Cardinal; begin Result := False; if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, LToken) then try // Get the locally unique identifier (LUID) . if LookupPrivilegeValue(nil, PChar(APrivilege), LTokenPriv.Privileges[0].Luid) then begin LTokenPriv.PrivilegeCount := 1; // one privilege to set case AEnable of True: LTokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; False: LTokenPriv.Privileges[0].Attributes := 0; end; LPrevTokenPriv := LTokenPriv; // Enable or disable the privilege Result := AdjustTokenPrivileges(LToken, False, LTokenPriv, SizeOf(LPrevTokenPriv), LPrevTokenPriv, LLength); end; finally CloseHandle(LToken); end; end; function TMyService.StartProcess(const AppPath: string): Boolean; begin SetTokenPrivilege('SeAssignPrimaryTokenPrivilege'); SetTokenPrivilege('SeTcbPrivilege'); // Giver fuld kontrol over tokens SetTokenPrivilege('SeIncreaseQuotaPrivilege'); SetTokenPrivilege('SeImpersonatePrivilege'); //result := StartProcessWithLogon(apppath, fusername, fpassword, fdomain); Result := StartProcessAsUser(AppPath); end; Share this post Link to post
Lars Fosdal 1835 Posted February 27 Under which user is the service running? Open "Services", double-click your service, check the "Logon as" tab (W11). Does it allow interacting with the desktop? Share this post Link to post