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

时间:2021-10-28 21:02:26

Is there any way to start/lunch a program through Process in another screen?

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

Someone asked that here but there was no answer.

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

Note: it is not a form in my app, I'm asking about running an external program in another screen!

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

5 个解决方案

#1


23  

Since the window is not yours, you can only move it by invoking the Windows API. You will have to do this:

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

  • Launch the process.

    启动该过程。

  • Use FindWindow to retrieve the handle to the window. If the window doesn’t exist yet, the process hasn’t created it yet; sleep for 500ms and then try again. (But don’t go into an infinite loop; stop if you can’t find the window after a reasonable timeout.)

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

  • Use SetWindowPos to change the position of the window.

    使用SetWindowPos更改窗口的位置。

If you don’t know the title of the window, you can’t use FindWindow. In that case,

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

  • Launch the process and get the process handle by retrieving Process.Handle.

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

  • Use EnumWindows to retrieve all the windows. For each window, use GetWindowThreadProcessId to check whether it belongs to your process. If no window belongs to your process, wait and keep trying.

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

  • Use SetWindowPos to change the position of the window.

    使用SetWindowPos更改窗口的位置。

Of course, you can use Screen.AllScreens[n].WorkingArea to retrieve the position and size of the screen you want, and then you can position the window relative to that.

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

#2


10  

First get out the area of the second monitor using something like:

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

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

The use the Windows API SetWindowPos to move it, using the Process.MainWindowHandle you got from the starting of the other process as the handle.

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

#3


4  

Timwi provided a very useful tip, so I decided to create a powershell script calling a library with these functions for easier use, and share the solution.

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

I needed to run multiple Chrome windows on startup, and the solution on GitHub targets exactly this problem (related question: https://superuser.com/a/901790/111424).

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

But the underlying logic is the same:

但底层逻辑是一样的:

  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:

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

    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:

    有了句柄,您可以使用以下功能。您只需要提供显示编号(从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);}

All enums and function imports you may find on http://www.pinvoke.net/ or just copy my code on GitHub: https://github.com/alex-tomin/Tomin.Tools.KioskMode.

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

#4


2  

You would need to start the process, get the processes main window and use an API call like SetWindowPos() to move the window to the screen you want.

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

#5


0  

Try to put this code in the form_load method:

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

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

The value of x must be greater than the width of your main screen. For example, if your main screen has a resolution of 1366 by 786 pixels, you should give x a value of at least 1368 or above.

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

It worked for me. But it is just for debugging purposes only. After all, you'll have to run it in the main monitor when the app is finished.

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

#1


23  

Since the window is not yours, you can only move it by invoking the Windows API. You will have to do this:

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

  • Launch the process.

    启动该过程。

  • Use FindWindow to retrieve the handle to the window. If the window doesn’t exist yet, the process hasn’t created it yet; sleep for 500ms and then try again. (But don’t go into an infinite loop; stop if you can’t find the window after a reasonable timeout.)

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

  • Use SetWindowPos to change the position of the window.

    使用SetWindowPos更改窗口的位置。

If you don’t know the title of the window, you can’t use FindWindow. In that case,

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

  • Launch the process and get the process handle by retrieving Process.Handle.

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

  • Use EnumWindows to retrieve all the windows. For each window, use GetWindowThreadProcessId to check whether it belongs to your process. If no window belongs to your process, wait and keep trying.

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

  • Use SetWindowPos to change the position of the window.

    使用SetWindowPos更改窗口的位置。

Of course, you can use Screen.AllScreens[n].WorkingArea to retrieve the position and size of the screen you want, and then you can position the window relative to that.

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

#2


10  

First get out the area of the second monitor using something like:

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

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

The use the Windows API SetWindowPos to move it, using the Process.MainWindowHandle you got from the starting of the other process as the handle.

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

#3


4  

Timwi provided a very useful tip, so I decided to create a powershell script calling a library with these functions for easier use, and share the solution.

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

I needed to run multiple Chrome windows on startup, and the solution on GitHub targets exactly this problem (related question: https://superuser.com/a/901790/111424).

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

But the underlying logic is the same:

但底层逻辑是一样的:

  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:

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

    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:

    有了句柄,您可以使用以下功能。您只需要提供显示编号(从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);}

All enums and function imports you may find on http://www.pinvoke.net/ or just copy my code on GitHub: https://github.com/alex-tomin/Tomin.Tools.KioskMode.

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

#4


2  

You would need to start the process, get the processes main window and use an API call like SetWindowPos() to move the window to the screen you want.

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

#5


0  

Try to put this code in the form_load method:

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

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

The value of x must be greater than the width of your main screen. For example, if your main screen has a resolution of 1366 by 786 pixels, you should give x a value of at least 1368 or above.

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

It worked for me. But it is just for debugging purposes only. After all, you'll have to run it in the main monitor when the app is finished.

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