开发者

Launch an application and send it to second monitor?

开发者 https://www.devze.com 2023-01-17 06:54 出处:网络
Is there any way to start/lunch a program through Process in another screen? Someone asked that here but there was no answer.

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

Someone asked that here but there was no answer.

Note: it is not a form in my app, I'm asking a开发者_高级运维bout running an external program in another screen!


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

  • 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.)

  • Use SetWindowPos to change the position of the window.

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

  • Launch the process and get the process handle by retrieving 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.

  • Use SetWindowPos to change the position of the window.

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.


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.


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.

  • You may have a look at the solution on 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).

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:

    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);
    }
    

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.


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.


Try to put this code in the form_load method:

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.

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.


If you do not maximize your window but have it non-maximized when you close it, the next time the app is being opened, it will appear on the monitor it was on last time.

If the app / window is maximized when you close it, and if you open it up again next time, it will appear on your primary monitor instead.

0

精彩评论

暂无评论...
验证码 换一张
取 消