S
S
SkyRZN2011-07-24 11:26:29
Delphi
SkyRZN, 2011-07-24 11:26:29

Delphi. Launching someone else's application from your service?

Good afternoon! Please let me know how to solve the following problem. There is a service written in Delphi, the service should launch someone else's application, I tried to launch it through the shellexecute and createprocess functions, the application starts (it can be seen in the task manager), but there is no application window. I checked the "Allow interaction with the desktop" checkbox.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
N
Nikita Permin, 2011-07-24
@NekitoSP

Service - it does not work from the user. And when the service is running, there is no such thing as an “active” desktop, because it’s no secret to anyone that you can open several accounts at the same time at a given time, let’s say the first is the main one, locally from the computer, and the second through RDP, so it turns out that there is no “active” desktop, but there is (most likely) a list of running accounts, from which you already need to get the desktop handle. I don’t know how you missed this moment when you read about services, but I remember exactly that this is how it was implemented. I advise you to read about Services and Drivers in Windows.

R
RomeroMsk, 2011-07-25
@RomeroMsk

If the task is to launch the active user on the desktop (the one who is looking at the monitor at the moment), then you can do this:

function WTSGetActiveConsoleSessionId: DWORD; stdcall; external 'Kernel32.dll';
function WTSQueryUserToken(SessionId: DWORD; phToken: pHandle):bool;stdcall;external 'wtsapi32.dll';

if WTSQueryUserToken(WtsGetActiveConsoleSessionID,@hToken) then
begin
  ZeroMemory(@si,SizeOf(si));
  si.cb:=SizeOf(si);
  si.lpDesktop:=nil;
  CreateProcessAsUser(hToken,nil,PANSIChar(FilePath),nil,nil,False,0,nil,nil,si,pi);
  CloseHandle(hToken);
end;

The point is that starting from Vista (if I'm not mistaken), launching an application in the system context will place the entire interactive in the “SYSTEM user desktop”.
But if the user logs in after launch, he will most likely not see the window. Solution: Cyclic check of the user's "activity" in the service and start in this way.

@
@antoo, 2011-07-24
_

function ExecAndWait(const FileName,
                     Params: ShortString;
                     const WinState: Word): boolean; export;
var
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CmdLine: ShortString;
begin
  { Помещаем имя файла между кавычками, с соблюдением всех пробелов в именах Win9x }
  CmdLine := '"' + Filename + '" ' + Params;
  FillChar(StartInfo, SizeOf(StartInfo), #0);
  with StartInfo do
  begin

    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := WinState;
  end;
  Result := CreateProcess(nil, PChar( String( CmdLine ) ), nil, nil, false,
                          CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
                          PChar(ExtractFilePath(Filename)),StartInfo,ProcInfo);
  { Ожидаем завершения приложения }
  if Result then
  begin
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    { Free the Handles }
    CloseHandle(ProcInfo.hProcess);
    CloseHandle(ProcInfo.hThread);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin

  ExecAndWait( 'C:\windows\notepad.exe', '', SW_SHOWNORMAL);
end;
</code>

попробуйте :)

S
SegaZero, 2011-07-24
@SegaZero

checkbox "interact with the desktop" in Vista and above simply does not work. I advise you to run using the task scheduler for example: api ? gunsmoker has a good write up on this

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question