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, useGetWindowThreadProcessId
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脚本,使用这些函数调用库以便于使用,并共享解决方案。
- You may have a look at the solution on GitHub: https://github.com/alex-tomin/Tomin.Tools.KioskMode
您可以查看GitHub上的解决方案:https://github.com/alex-tomin/Tomin.Tools.KioskMode
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:
但底层逻辑是一样的:
-
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
-
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, useGetWindowThreadProcessId
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脚本,使用这些函数调用库以便于使用,并共享解决方案。
- You may have a look at the solution on GitHub: https://github.com/alex-tomin/Tomin.Tools.KioskMode
您可以查看GitHub上的解决方案:https://github.com/alex-tomin/Tomin.Tools.KioskMode
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:
但底层逻辑是一样的:
-
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
-
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.
它对我有用。但它仅用于调试目的。毕竟,当应用程序完成时,您必须在主监视器中运行它。