gpt4 book ai didi

c++ - 如何从命令行或其他应用程序打开桌面应用程序并将其置于最前面?

转载 作者:可可西里 更新时间:2023-11-01 10:07:21 26 4
gpt4 key购买 nike

有时需要从命令行打开新程序(例如,Windows Powerpoint 演示文稿作为幻灯片可以通过命令行“powerpnt.exe/s”打开),将此程序最大化并将其置于最前面桌面作为用户可以看到和使用的第一个程序。如果用户直接在命令提示符中输入命令,默认情况下会发生这种情况,因为命令提示符是事件窗口。

但问题是 - 如果命令行是从后台进程执行的,如何做到这一点 - 例如来自 Windows Task Scehduler 的自定义 Windows 服务应用程序 - 在这两种情况下,新窗口都不会作为第一个窗口出现。

目前我只能想象非常困难的解决方案(其缺点是它们需要编码并且不能从任务计划程序中使用):

  1. 可以尝试获取已打开程序主窗口的句柄并操纵该窗口 - 例如最大化等等;
  2. 可以尝试完全放弃命令行,而是将 Windows Office 应用程序作为 COM 对象进行操作。

也许有更简单的方法?

最佳答案

您可以创建一个小型(非图形用户界面)启动器应用程序,它将为您调用新程序(我知道,这就是您所说的硬解决方案),然后在任务计划程序上安排此启动器。

此启动器应用程序必须创建 de 进程(CreateProcess function),然后从 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;

希望这就是您所需要的。如果不是,我们深表歉意。

最好的问候。

关于c++ - 如何从命令行或其他应用程序打开桌面应用程序并将其置于最前面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14297934/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com