Как открыть и вывести на экран настольное приложение из командной строки или из другого приложения?

Иногда возникает необходимость открыть новую программу (например, презентацию Windows Powerpoint, так как слайд-шоу можно открыть из командной строки »powerpnt.exe /s«) из командной строки разверните эту программу и разверните ее перед рабочим столом в качестве первой программы, которую пользователь может видеть и использовать. Это происходит по умолчанию, если пользователь непосредственно вводит команду в командной строке, потому что командная строка является активным окном.

Но вопрос в том, как это сделать, если командная строка выполняется из фонового процесса, например. из пользовательского приложения-службы Windows или из Windows Task Scehduler — в обоих случаях новые окна не выводятся в качестве первого окна.

В настоящее время я могу представить только довольно сложные решения (недостаток которых заключается в том, что они требуют кодирования и их нельзя использовать из планировщика задач):

  1. можно попытаться получить дескриптор главного окна открытой программы и манипулировать этим окном — например, максимизировать и т. д .;
  2. можно вообще отказаться от командной строки и вместо этого манипулировать приложениями Windows Office как объектами COM.

Может быть, есть более простой способ?

2

Решение

Вы можете создать небольшое (не графическое) приложение запуска, которое будет вызывать новую программу для вас (я знаю, это то, что вы назвали трудным решением), а затем запланировать этот запуск в планировщике задач.

Это приложение запуска должно было бы создать де процесс (Функция CreateProcess), а затем получить дескриптор окна из pID … с дескриптором окна вы можете использовать SetForegroundWindow, чтобы делать то, что вам нужно, или вызывать другие функции для таких вещей, как максимизация и т. д.

Поскольку вы пометили Delphi, я публикую возможную реализацию Delphi.

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;

Надеюсь, это то, что вам нужно .. извините, если это не так.

С уважением.

3

Другие решения

Создайте пакетный файл, который откроет необходимые программы и запустит планировщик задач тот.

Пакетный файл будет работать так, как если бы пользователь вводил команды непосредственно в командную строку, и вы получите желаемый результат.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector