启动一个应用程序并将其发送到第二个监视器?

28

有没有办法通过进程在另一个屏幕上启动/运行程序?

有人在这里提出了这个问题(链接),但是没有得到答案。

注意:我不是在问如何在我的应用程序中使用表单,我是在问如何在另一个屏幕上运行外部程序!


可能是重复的问题:启动应用程序并将其发送到第二个监视器 - Albin Sunnanbo
3
不是重复内容,而是稍有不同。另一篇文章涉及即时应用程序,他想移动一个外部应用程序窗口。 - Lloyd
6个回答

29

由于窗口不是您的窗口,因此您只能通过调用Windows API来移动它。您需要执行以下操作:

  • 启动进程。

  • 使用FindWindow检索窗口句柄。如果窗口尚不存在,则进程还没有创建它;睡眠500毫秒,然后再次尝试。(但不要陷入无限循环; 如果在合理的超时时间内找不到窗口,请停止。)

  • 使用SetWindowPos更改窗口的位置。

如果您不知道窗口的标题,就不能使用FindWindow。在这种情况下,

  • 启动进程,并通过检索Process.Handle获取进程句柄。

  • 使用EnumWindows检索所有窗口。对于每个窗口,使用GetWindowThreadProcessId检查它是否属于您的进程。如果没有窗口属于您的进程,请等待并继续尝试。

  • 使用SetWindowPos更改窗口的位置。

当然,您可以使用Screen.AllScreens[n].WorkingArea检索所需屏幕的位置和大小,然后根据此来定位窗口。


10

首先,使用类似以下的方法获得第二个显示器的区域:

Rectangle area = Screen.AllScreens[1].WorkingArea;

使用SetWindowPos Windows API来移动它,使用从另一个进程启动时获取的Process.MainWindowHandle作为句柄。


6
提供了一个非常有用的提示,所以我决定创建一个 PowerShell 脚本调用包含这些函数的库来更轻松地使用,并分享解决方案。

我需要在启动时运行多个 Chrome 窗口,而 GitHub 上的解决方案正是针对这个问题(相关问题:https://superuser.com/a/901790/111424)。

但底层逻辑是相同的:

  1. Find Windows Handle to operate with. You may use FindWindow or EnumWindows in generic case as Timwi mentioned. But if your process is simple one and has a single main window, it is just:

    var hndl = proc.MainWindowHandle
    
  2. Having the handle, you may use the following function. You just need to provide Display number (starting from 1) and the handle:

    public static bool MoveToMonitor(IntPtr windowHandle, int monitor)
    {
        monitor = monitor - 1;
        return WinApi.SetWindowPos(windowHandle, IntPtr.Zero, Screen.AllScreens[monitor].WorkingArea.Left,
            Screen.AllScreens[monitor].WorkingArea.Top, 1000, 800, SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOREDRAW);
    }
    

您可以在http://www.pinvoke.net/上找到所有的枚举和函数导入,或者只需复制我的GitHub代码:https://github.com/alex-tomin/Tomin.Tools.KioskMode


2

您需要启动该进程, 获取进程的主窗口并使用类似SetWindowPos()的API调用来将窗口移动到想要的屏幕。


0

如果您在关闭窗口时未将其最大化,而是以非最大化状态关闭它,则下次打开应用程序时,它将出现在上一次所在的监视器上。

如果应用程序/窗口在关闭时处于最大化状态,并且下次再次打开它时,它将出现在您的主要监视器上。


0
尝试将此代码放入 form_load 方法中:
this.setdesktoplocation(int x, int y);
this.windowstate = formwindowstate.maximized;

x的值必须大于您的主屏幕的宽度。例如,如果您的主屏幕分辨率为1366 x 786像素,则应将x的值设置为至少1368或更高。

这对我有用。但这仅用于调试目的。毕竟,在应用程序完成后,您将不得不在主监视器上运行它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接