完善windows下截图功能,实现windows下找图,整体找图功能还需后续完善

This commit is contained in:
fofolee 2025-01-03 09:38:16 +08:00
parent eb66a16c00
commit 869cf06c71

View File

@ -9,100 +9,116 @@ const readFileAsync = promisify(fs.readFile);
const unlinkAsync = promisify(fs.unlink); const unlinkAsync = promisify(fs.unlink);
// Windows C# 截图代码 // Windows C# 截图代码
const csharpScript = Buffer.from( const csharpScript = `
`
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Collections.Generic;
using Microsoft.VisualBasic;
public class ScreenCapture { public class ScreenCapture
{
[DllImport("user32.dll")] [DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr hwnd); static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("user32.dll")] [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")] [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")] [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")] [DllImport("gdi32.dll")]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int width, int height, static extern bool DeleteDC(IntPtr hDC);
IntPtr hdcSrc, int xSrc, int ySrc, int rop);
[DllImport("gdi32.dll")]
static extern bool DeleteDC(IntPtr hdc);
[DllImport("gdi32.dll")] [DllImport("gdi32.dll")]
static extern bool DeleteObject(IntPtr hObject); static extern bool DeleteObject(IntPtr hObject);
[DllImport("user32.dll")] [DllImport("gdi32.dll")]
static extern bool GetCursorPos(ref Point point); static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("user32.dll")] public Image CaptureScreen()
static extern bool GetWindowRect(IntPtr hwnd, ref Rectangle rect); {
return CaptureWindow(GetDesktopWindow());
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);
}
} }
}`
).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 截图实现 // Windows 截图实现
async function captureWindowsScreen() { async function captureWindowsScreen() {
const tmpFile = path.join(os.tmpdir(), `screen-${Date.now()}.png`); const tmpFile = path.join(os.tmpdir(), `screen-${Date.now()}.png`);
try { try {
// 使用base64编码的C#代码执行 await window.quickcommand.runCsharp(
const command = ` csharpScript.replace(">>tempscreenshot<<", tmpFile.replace(/\\/g, "\\\\"))
$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,
]);
// 读取截图
const imageBuffer = await readFileAsync(tmpFile); const imageBuffer = await readFileAsync(tmpFile);
return `data:image/png;base64,${imageBuffer.toString("base64")}`; return `data:image/png;base64,${imageBuffer.toString("base64")}`;
} catch (error) { } catch (error) {
console.error("Windows截图失败:", error); console.error("Windows截图失败:", error);
return null; return null;
} finally {
// 清理临时文件
await unlinkAsync(tmpFile).catch(() => {});
} }
} }