diff --git a/plugin/lib/quickcomposer/simulate/screenCapture.js b/plugin/lib/quickcomposer/simulate/screenCapture.js index 3825eaa..62ee22e 100644 --- a/plugin/lib/quickcomposer/simulate/screenCapture.js +++ b/plugin/lib/quickcomposer/simulate/screenCapture.js @@ -9,100 +9,116 @@ const readFileAsync = promisify(fs.readFile); const unlinkAsync = promisify(fs.unlink); // Windows C# 截图代码 -const csharpScript = Buffer.from( - ` +const csharpScript = ` using System; using System.Runtime.InteropServices; using System.Drawing; using System.Drawing.Imaging; +using System.Collections.Generic; +using Microsoft.VisualBasic; -public class ScreenCapture { +public class ScreenCapture +{ [DllImport("user32.dll")] static extern IntPtr GetDC(IntPtr hwnd); [DllImport("user32.dll")] - static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc); + static extern IntPtr GetDesktopWindow(); + + [DllImport("user32.dll")] + static extern IntPtr GetWindowDC(IntPtr hWnd); + + [DllImport("user32.dll")] + static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC); [DllImport("gdi32.dll")] - static extern IntPtr CreateCompatibleDC(IntPtr hdc); + static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, + int nWidth, int nHeight, IntPtr hdcSrc, + int nXSrc, int nYSrc, int dwRop); [DllImport("gdi32.dll")] - static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int width, int height); + static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight); [DllImport("gdi32.dll")] - static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); + static extern IntPtr CreateCompatibleDC(IntPtr hDC); [DllImport("gdi32.dll")] - static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int width, int height, - IntPtr hdcSrc, int xSrc, int ySrc, int rop); - - [DllImport("gdi32.dll")] - static extern bool DeleteDC(IntPtr hdc); + static extern bool DeleteDC(IntPtr hDC); [DllImport("gdi32.dll")] static extern bool DeleteObject(IntPtr hObject); - [DllImport("user32.dll")] - static extern bool GetCursorPos(ref Point point); + [DllImport("gdi32.dll")] + static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); - [DllImport("user32.dll")] - static extern bool GetWindowRect(IntPtr hwnd, ref Rectangle rect); - - public static void CaptureScreen(string outputPath) { - IntPtr desktopDC = GetDC(IntPtr.Zero); - Rectangle bounds = System.Windows.Forms.Screen.PrimaryScreen.Bounds; - - IntPtr memoryDC = CreateCompatibleDC(desktopDC); - IntPtr bitmap = CreateCompatibleBitmap(desktopDC, bounds.Width, bounds.Height); - IntPtr oldBitmap = SelectObject(memoryDC, bitmap); - - try { - BitBlt(memoryDC, 0, 0, bounds.Width, bounds.Height, desktopDC, 0, 0, 0x00CC0020); - - using (var bmp = Image.FromHbitmap(bitmap)) { - bmp.Save(outputPath, ImageFormat.Png); - } - } - finally { - SelectObject(memoryDC, oldBitmap); - DeleteObject(bitmap); - DeleteDC(memoryDC); - ReleaseDC(IntPtr.Zero, desktopDC); - } + public Image CaptureScreen() + { + return CaptureWindow(GetDesktopWindow()); } -}` -).toString("base64"); + + private Image CaptureWindow(IntPtr handle) + { + IntPtr hdcSrc = GetWindowDC(handle); + User32.RECT windowRect = new User32.RECT(); + User32.GetWindowRect(handle, ref windowRect); + int width = windowRect.right - windowRect.left; + int height = windowRect.bottom - windowRect.top; + + IntPtr hdcDest = CreateCompatibleDC(hdcSrc); + IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, width, height); + IntPtr hOld = SelectObject(hdcDest, hBitmap); + + BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, 0x00CC0020); + SelectObject(hdcDest, hOld); + DeleteDC(hdcDest); + + Image img = Image.FromHbitmap(hBitmap); + DeleteObject(hBitmap); + ReleaseDC(handle, hdcSrc); + + return img; + } + + public void CaptureScreenToFile(string filename, ImageFormat format) + { + Image img = CaptureScreen(); + img.Save(filename, format); + } + + public class User32 + { + public struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + } + + [DllImport("user32.dll")] + public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect); + } + + public static void Main() + { + ScreenCapture sc = new ScreenCapture(); + sc.CaptureScreenToFile(">>tempscreenshot<<", ImageFormat.Png); + } +} +`; // Windows 截图实现 async function captureWindowsScreen() { const tmpFile = path.join(os.tmpdir(), `screen-${Date.now()}.png`); - try { - // 使用base64编码的C#代码执行 - const command = ` - $code = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('${csharpScript}')); - Add-Type -TypeDefinition $code; - [ScreenCapture]::CaptureScreen('${tmpFile.replace(/\\/g, "\\\\")}'); - `; - - await execFileAsync("powershell", [ - "-NoProfile", - "-NonInteractive", - "-ExecutionPolicy", - "Bypass", - "-Command", - command, - ]); - - // 读取截图 + await window.quickcommand.runCsharp( + csharpScript.replace(">>tempscreenshot<<", tmpFile.replace(/\\/g, "\\\\")) + ); const imageBuffer = await readFileAsync(tmpFile); return `data:image/png;base64,${imageBuffer.toString("base64")}`; } catch (error) { console.error("Windows截图失败:", error); return null; - } finally { - // 清理临时文件 - await unlinkAsync(tmpFile).catch(() => {}); } }