有时需要从命令行打开新程序(例如Windows Powerpoint演示,因为幻灯片可以通过命令行“powerpnt.exe /s
”打开),最大化此程序并将其作为第一个程序带到桌面前面用户可以查看和使用。如果用户在命令提示符中直接输入命令,则默认情况下会发生这种情况,因为命令提示符是活动窗口。
但问题是 - 如果从后台进程执行命令行,如何执行此操作 - 例如来自Windows Task Scehduler的自定义Windows服务应用程序 - 在这两种情况下,新窗口都不会作为第一个窗口。
目前我只能想象相当难的解决方案(其缺点是它们需要编码而不能在任务计划程序中使用):
也许有更简单的方法?
答案 0 :(得分:3)
您可以创建一个小型(非gui)启动器应用程序,它将为您调用新程序(我知道,这就是您所谓的硬解决方案),然后在任务计划程序上安排此启动程序。
这个启动器应用程序必须创建de process(CreateProcess function),然后从pID获取Window Handle ...使用窗口句柄你可以使用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;
希望这就是你需要的......如果不是那就抱歉。
最诚挚的问候。
答案 1 :(得分:0)
创建一个批处理文件,打开所需的程序并让任务计划程序运行 。
批处理文件将像用户直接在命令提示符中输入命令一样运行,您将获得所需的结果。