Here's working C# source code to open and arrange 3 Firefox browsers on a 4K monitor wtih Windows
modify to suit your tastes or improve it? working now without any known issues.
using System.Diagnostics; using System.Runtime.InteropServices; using System.Text;
namespace FirefoxWindowPositioner {
class Program { [DllImport("user32.dll", SetLastError = true)] private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll", SetLastError = true)] private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)] private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
[DllImport("user32.dll", SetLastError = true)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", SetLastError = true)] private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
private const uint GW_OWNER = 4; private const int MaxRetries = 100; private const int SleepTime = 200; private const string ClassNameToFind = "MozillaWindowClass";
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
private static IntPtr foundWindowHandle = IntPtr.Zero;
private static bool EnumWindowsCallback(IntPtr hWnd, IntPtr lParam) { uint processId; GetWindowThreadProcessId(hWnd, out processId);
if (IsWindowVisible(hWnd) && GetWindow(hWnd, GW_OWNER) == IntPtr.Zero) { StringBuilder className = new StringBuilder(256); GetClassName(hWnd, className, className.Capacity);
if (className.ToString() == ClassNameToFind) { foundWindowHandle = hWnd; Console.WriteLine($"Found window handle {hWnd} for process ID {processId}"); return false; // Stop enumerating windows once the desired window is found } }
return true; // Continue enumerating windows }
static void Main(string[] args) { string path = @"C:\Program Files\Mozilla Firefox\firefox.exe";
// Define positions and sizes int[,] positions = new int[,] { {0, 0, 1284, 2120}, {1280, 0, 1284, 2120}, {2560, 0, 1284, 2120} };
int initialDelay = 750; // Initial delay in milliseconds, 1000 worked int retryDelay = 200; // Delay between retries in milliseconds
// Start three Firefox processes sequentially and move them to specified positions for (int i = 0; i < 3; i++) { Process firefoxProcess = Process.Start(path); Thread.Sleep(initialDelay); // Wait for the process to initialize
foundWindowHandle = IntPtr.Zero; int retries = 0;
while (foundWindowHandle == IntPtr.Zero && retries < MaxRetries) { EnumWindows(EnumWindowsCallback, IntPtr.Zero); if (foundWindowHandle == IntPtr.Zero) { Thread.Sleep(retryDelay); // Wait before retrying retries++; } }
if (foundWindowHandle != IntPtr.Zero) { bool success = MoveWindow(foundWindowHandle, positions[i, 0], positions[i, 1], positions[i, 2], positions[i, 3], true); if (success) { Console.WriteLine($"Moved window {i + 1} to X: {positions[i, 0]}, Y: {positions[i, 1]}, Width: {positions[i, 2]}, Height: {positions[i, 3]}"); } else { Console.WriteLine($"Failed to move window {i + 1}"); } } else { Console.WriteLine($"Failed to get handle for Firefox process {i + 1}"); } } } }
}
modify to suit your tastes or improve it? working now without any known issues.
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
namespace FirefoxWindowPositioner {
class Program {
[DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
private const uint GW_OWNER = 4;
private const int MaxRetries = 100;
private const int SleepTime = 200;
private const string ClassNameToFind = "MozillaWindowClass";
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
private static IntPtr foundWindowHandle = IntPtr.Zero;
private static bool EnumWindowsCallback(IntPtr hWnd, IntPtr lParam) {
uint processId;
GetWindowThreadProcessId(hWnd, out processId);
if (IsWindowVisible(hWnd) && GetWindow(hWnd, GW_OWNER) == IntPtr.Zero) {
StringBuilder className = new StringBuilder(256);
GetClassName(hWnd, className, className.Capacity);
if (className.ToString() == ClassNameToFind) {
foundWindowHandle = hWnd;
Console.WriteLine($"Found window handle {hWnd} for process ID {processId}");
return false; // Stop enumerating windows once the desired window is found
}
}
return true; // Continue enumerating windows
}
static void Main(string[] args) {
string path = @"C:\Program Files\Mozilla Firefox\firefox.exe";
// Define positions and sizes
int[,] positions = new int[,]
{
{0, 0, 1284, 2120},
{1280, 0, 1284, 2120},
{2560, 0, 1284, 2120}
};
int initialDelay = 750; // Initial delay in milliseconds, 1000 worked
int retryDelay = 200; // Delay between retries in milliseconds
// Start three Firefox processes sequentially and move them to specified positions
for (int i = 0; i < 3; i++) {
Process firefoxProcess = Process.Start(path);
Thread.Sleep(initialDelay); // Wait for the process to initialize
foundWindowHandle = IntPtr.Zero;
int retries = 0;
while (foundWindowHandle == IntPtr.Zero && retries < MaxRetries) {
EnumWindows(EnumWindowsCallback, IntPtr.Zero);
if (foundWindowHandle == IntPtr.Zero) {
Thread.Sleep(retryDelay); // Wait before retrying
retries++;
}
}
if (foundWindowHandle != IntPtr.Zero) {
bool success = MoveWindow(foundWindowHandle, positions[i, 0], positions[i, 1], positions[i, 2], positions[i, 3], true);
if (success) {
Console.WriteLine($"Moved window {i + 1} to X: {positions[i, 0]}, Y: {positions[i, 1]}, Width: {positions[i, 2]}, Height: {positions[i, 3]}");
} else {
Console.WriteLine($"Failed to move window {i + 1}");
}
} else {
Console.WriteLine($"Failed to get handle for Firefox process {i + 1}");
}
}
}
}
}