Иногда возникает необходимость открыть новую программу (например, презентацию Windows Powerpoint, так как слайд-шоу можно открыть из командной строки »powerpnt.exe /s
«) из командной строки разверните эту программу и разверните ее перед рабочим столом в качестве первой программы, которую пользователь может видеть и использовать. Это происходит по умолчанию, если пользователь непосредственно вводит команду в командной строке, потому что командная строка является активным окном.
Но вопрос в том, как это сделать, если командная строка выполняется из фонового процесса, например. из пользовательского приложения-службы Windows или из Windows Task Scehduler — в обоих случаях новые окна не выводятся в качестве первого окна.
В настоящее время я могу представить только довольно сложные решения (недостаток которых заключается в том, что они требуют кодирования и их нельзя использовать из планировщика задач):
Может быть, есть более простой способ?
Вы можете создать небольшое (не графическое) приложение запуска, которое будет вызывать новую программу для вас (я знаю, это то, что вы назвали трудным решением), а затем запланировать этот запуск в планировщике задач.
Это приложение запуска должно было бы создать де процесс (Функция 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;
Надеюсь, это то, что вам нужно .. извините, если это не так.
С уважением.
Создайте пакетный файл, который откроет необходимые программы и запустит планировщик задач тот.
Пакетный файл будет работать так, как если бы пользователь вводил команды непосредственно в командную строку, и вы получите желаемый результат.