mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-24 14:55:37 +00:00
79 lines
2.4 KiB
TypeScript
79 lines
2.4 KiB
TypeScript
import { spawnSync } from "node:child_process";
|
|
|
|
/**
|
|
* Represents a Windows monitor handle and its physical desktop coordinates.
|
|
*/
|
|
export interface WinMonitorHandle {
|
|
handle: number;
|
|
x: number;
|
|
y: number;
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
/**
|
|
* Retrieves raw HMONITOR handles from the Windows OS using a PowerShell bridge.
|
|
* This is necessary because Electron's display IDs are often internal hashes that
|
|
* cannot be used directly with native Windows APIs like Graphics Capture (WGC).
|
|
*/
|
|
export function getMonitorHandles(): WinMonitorHandle[] {
|
|
if (process.platform !== "win32") return [];
|
|
|
|
// PowerShell snippet that uses P/Invoke to call EnumDisplayMonitors and return raw handles + bounds.
|
|
const psScript = `
|
|
Add-Type -TypeDefinition @"
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Collections.Generic;
|
|
|
|
public class MonitorHelper {
|
|
[DllImport("user32.dll")]
|
|
public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumProc lpfnEnum, IntPtr dwData);
|
|
|
|
public delegate bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr dwData);
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct Rect {
|
|
public int left;
|
|
public int top;
|
|
public int right;
|
|
public int bottom;
|
|
}
|
|
|
|
public static List<string> GetMonitors() {
|
|
List<string> result = new List<string>();
|
|
EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, (IntPtr hMonitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr dwData) => {
|
|
result.Add(string.Format("{0}|{1}|{2}|{3}|{4}", hMonitor.ToInt64(), lprcMonitor.left, lprcMonitor.top, lprcMonitor.right - lprcMonitor.left, lprcMonitor.bottom - lprcMonitor.top));
|
|
return true;
|
|
}, IntPtr.Zero);
|
|
return result;
|
|
}
|
|
}
|
|
"@
|
|
[MonitorHelper]::GetMonitors()
|
|
`.trim();
|
|
|
|
const result = spawnSync(
|
|
"powershell.exe",
|
|
["-NoProfile", "-NonInteractive", "-Command", psScript],
|
|
{
|
|
encoding: "utf-8",
|
|
timeout: 5000,
|
|
},
|
|
);
|
|
|
|
if (result.error || result.status !== 0) {
|
|
// Silent failure is preferred; the caller will fall back to coordinate-based matching.
|
|
return [];
|
|
}
|
|
|
|
return result.stdout
|
|
.split("\n")
|
|
.map((line) => line.trim())
|
|
.filter((line) => line.length > 0)
|
|
.map((line) => {
|
|
const [handle, x, y, width, height] = line.split("|").map(Number);
|
|
return { handle, x, y, width, height };
|
|
});
|
|
}
|