启动应用程序并将其发送到第二台显示器?

有没有办法在另一个屏幕上通过Process开始/午餐?

有人在这里问,但没有答案。

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

由于窗口不是您的,因此您只能通过调用Windows API来移动它。 你必须这样做:

  • 启动该过程。

  • 使用FindWindow检索窗口的句柄。 如果窗口尚不存在,则该进程尚未创建它; 睡500码,然后再试一次。 (但不要进入无限循环;如果在合理的超时后找不到窗口,请停止。)

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

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

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

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

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

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

首先使用以下方法获取第二台显示器的区域:

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

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

Timwi提供了一个非常有用的提示,因此我决定创建一个PowerShell脚本,使用这些函数调用库以便于使用,并共享解决方案。

  • 您可以查看GitHub上的解决方案: https : //github.com/alex-tomin/Tomin.Tools.KioskMode

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

但底层逻辑是一样的:

  1. 找到要操作的Windows句柄。 您可以像Timwi提到的那样在一般情况下使用FindWindow或EnumWindows。 但是,如果您的流程很简单并且只有一个主窗口,那么它只是:

     var hndl = proc.MainWindowHandle 
  2. 有了句柄,您可以使用以下function。 您只需要提供显示编号(从1开始)和句柄:

     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 。

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

尝试将此代码放在form_load方法中:

 this.setdesktoplocation(int x, int y); this.windowstate = formwindowstate.maximized; 

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

它对我有用。 但它仅用于调试目的。 毕竟,当应用程序完成时,您必须在主监视器中运行它。