TomR
TomR

Reputation: 3056

How to open and bring in front a desktop application from command line or from other application?

Sometimes there is need to open new program (e.g. Windows Powerpoint presentation as slideshow can be opened by command line "powerpnt.exe /s") from commandline, maximize this program and bring it in front of desktop as the first program the user can see and use. This happens by default if user directly enters command in the command prompt, because the command prompt is the active window.

But the question is - how to do this, if command line is executed from background process - e.g. from custom Windows service application of from the Windows Task Scehduler - in both cases the new windows is not brought as the first window.

At present I can imagine only quite hard solutions (whose drawback is that they required coding and they can not be used from Task Scheduler):

  1. one can try to get handle of the main window of the opened program and the manipulate this window - e.g. maximize and so on;
  2. one can try to abandon command line at all and instead manipulate Windows Office applications as COM objects.

Maybe there is easier way?

Upvotes: 3

Views: 3709

Answers (2)

Casey
Casey

Reputation: 10946

Create a batch file that opens the required program(s) and have the Task Scheduler run that.

The batch file will run as if a user entered the commands directly into the command prompt and you will get the desired result.

Upvotes: 0

GabrielF
GabrielF

Reputation: 2121

You can create a small (non-gui) launcher application that will call the new program for you (I know, that's what you've called the hard solution) and then schedule this launcher on the task scheduler.

This launcher application would have to create de process (CreateProcess function), and then get the Window Handle from the pID... with the window handle you can use SetForegroundWindow to do what you need, or call other functions for things like maximize, etc.

Since you tagged delphi, I'm posting a possible delphi implementation of that.

function WindowFromPID(pID: Cardinal; VisibleWindow: Boolean): Cardinal;
type
  TProcData = record
    pID: Cardinal;
    pHandle: Cardinal;

    VisibleWindow: Boolean;
  end;

var 
  wPData: TProcData;

  function EnumProc(Handle: HWND; var pProcData: TProcData): Bool; stdcall;
  var pID: DWORD;
  begin
    Result := True;
    if pProcData.VisibleWindow then
      if not IsWindowVisible(Handle) then
        Exit;

    GetWindowThreadProcessId(Handle, @pID);
    if pID = pProcData.pID then begin
      if GetWindow(Handle, GW_OWNER) = 0 then begin
        pProcData.pHandle := Handle;
        Result := false;
      end;
    end;
  end;
begin
  wPData.pHandle := 0;
  wPData.pID := pID;
  wPData.VisibleWindow := VisibleWindow;

  EnumWindows(@EnumProc, Integer(@wPData));
  while (wPData.pHandle = 0) do begin
    Sleep(50);
    EnumWindows(@EnumProc, Integer(@wPData));
  end;

  Result := wPData.pHandle;
end;

procedure RunAndGetWindowHandle(const FileName, Params: String; const WindowState: Word): Cardinal;
var 
  SUInfo: TStartupInfo;
  CmdLine: String;
  ProcInfo: TProcessInformation
begin
  CmdLine := '"' + Filename + '"' + Params;
  FillChar(SUInfo, SizeOf(SUInfo), #0);
  with SUInfo do begin
    cb := SizeOf(SUInfo);
    dwFlags := StartF_UseShowWindow;
    wShowWindow := WindowState;
  end;

  if not CreateProcess(Nil, PChar(CmdLine), nil, nil, False, Create_New_Console Or Normal_Priority_Class, nil, PChar(ExtractFilePath(Filename)), SUInfo, ProcInfo) then
    raise Exception.Create('Error running process');

  if WaitForSingleObject(ProcInfo.hProcess, 50) <> WAIT_TIMEOUT then
    raise Exception.Create('Error running process!');

  CloseHandle(ProcInfo.hThread);
  while Result = 0 do begin
    Sleep(50);
    Result := WindowFromPID(ProcInfo.dwProcessId, true);
  end;
end;

...

var WindowHandle: Cardinal;
begin
  WindowHandle := RunAndGetWindowHandle("powerpnt.exe", " /s", SW_SHOWNORMAL);
  SetForegroundWindow(WindowHandle);
end;

Hope that's what you need.. sorry if it's not.

Best Regards.

Upvotes: 4

Related Questions