At some point in time you got frustrated that Windows console app opens on monitor that is not ideal for you or you just want to move it to another screen. Unfortunately Console does not offer out of the box solution to fix this problem so we need to find solution out of the box.
My solution is based upon consuming Windows API’s and Windows Forms to easily create maintainable solution.
SetWindowPos function seems to be a good start. By using it we can set Windows starting X and Y axis, as well as its width, height and window position. To use this function there are 2 challenges:
Getting monitors starting X point and getting the console Windows handle.
Monitors X axis point can be easily acquired by using WinForms System.Windows.Forms.Screen.AllScreens property, which stores all connected monitors ant their information.
Getting Console Window handle is a bit trickier. First we need to use GetConsoleWindow function assign it to the pointer and then pass it to the SetWindowPos.
SetWindowPos has a limitation thou. If we want to maximize screen, we cannot do it (we can extend it to monitors max width and height but its state would still not be maximized). Here we can use ShowWindow function where we pass our Console window and it’s desired state.
That would be all for this short tutorial, code sample is bellow.
Happy coding!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace ConsoleApp { class Program { //https://docs.microsoft.com/en-us/windows/console/getconsolewindow [DllImport("kernel32.dll", ExactSpelling = true)] private static extern IntPtr GetConsoleWindow(); private static readonly IntPtr MyConsoleWindow = GetConsoleWindow(); //https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowpos [DllImport("user32.dll", EntryPoint = "SetWindowPos")] public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags); //https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); static void Main(string[] args) { Console.WriteLine("Hello monitor!"); int monitorNumber = 2; OpenConsoleWindowOnAnotherScreen(monitorNumber, 400, 200); //Changes console windows state ShowWindow(MyConsoleWindow, (int)WindowState.Maximized); Console.ReadLine(); } private static void OpenConsoleWindowOnAnotherScreen(int monitorNumber, int width, int height) { Console.WriteLine($"Hello from monitor {monitorNumber}."); if (monitorNumber > 1) { if (Screen.AllScreens.Length < monitorNumber) { Console.WriteLine("There is no such window."); } else { // Array is zero based monitorNumber--; // Gets selected monitor // first monitors x axis starts from 0 and ends with its resolution width, // so we need to find out where on x axis n monitor starts var monitor = Screen.AllScreens[monitorNumber].WorkingArea; // Changes window position to the desired monitor // SetWindowPos cannot change monitor state // Setting correct width and height of Window is not necessary if wFlags is set to 1, // try experimenting with wFlags value by visiting https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowpos // and experimenting with uFlags values // for further experimentation try changing x an y parameters to position console to your choosing on the screen SetWindowPos( MyConsoleWindow, 0, monitor.Left, monitor.Top, width, height, 0); } } else { Console.WriteLine("No need to change console window to another screen."); } } } public enum WindowState { Hidden = 0, Maximized = 3, Minimized = 6, Restored = 9 } } |