mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-08 06:16:27 +08:00
206 lines
5.6 KiB
JavaScript
206 lines
5.6 KiB
JavaScript
const { execFile } = require("child_process");
|
|
const { promisify } = require("util");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const os = require("os");
|
|
|
|
const execFileAsync = promisify(execFile);
|
|
const readFileAsync = promisify(fs.readFile);
|
|
const unlinkAsync = promisify(fs.unlink);
|
|
|
|
// Windows C# 截图代码
|
|
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
|
|
{
|
|
[DllImport("user32.dll")]
|
|
static extern IntPtr GetDC(IntPtr hwnd);
|
|
|
|
[DllImport("user32.dll")]
|
|
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 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 nWidth, int nHeight);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
static extern IntPtr CreateCompatibleDC(IntPtr hDC);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
static extern bool DeleteDC(IntPtr hDC);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
static extern bool DeleteObject(IntPtr hObject);
|
|
|
|
[DllImport("gdi32.dll")]
|
|
static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
|
|
|
|
public Image CaptureScreen()
|
|
{
|
|
return CaptureWindow(GetDesktopWindow());
|
|
}
|
|
|
|
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 {
|
|
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;
|
|
}
|
|
}
|
|
|
|
// macOS 截图实现
|
|
async function captureMacScreen() {
|
|
const tmpFile = path.join(os.tmpdir(), `screen-${Date.now()}.png`);
|
|
|
|
try {
|
|
await execFileAsync("screencapture", ["-x", "-C", "-T", "0", tmpFile]);
|
|
const imageBuffer = await readFileAsync(tmpFile);
|
|
return `data:image/png;base64,${imageBuffer.toString("base64")}`;
|
|
} catch (error) {
|
|
console.error("macOS截图失败:", error);
|
|
return null;
|
|
} finally {
|
|
await unlinkAsync(tmpFile).catch(() => {});
|
|
}
|
|
}
|
|
|
|
// Linux 截图实现
|
|
async function captureLinuxScreen() {
|
|
const tmpFile = path.join(os.tmpdir(), `screen-${Date.now()}.png`);
|
|
|
|
try {
|
|
// 检查可用的截图工具
|
|
let tool = null;
|
|
try {
|
|
await execFileAsync("which", ["gnome-screenshot"]);
|
|
tool = "gnome-screenshot";
|
|
} catch {
|
|
try {
|
|
await execFileAsync("which", ["scrot"]);
|
|
tool = "scrot";
|
|
} catch {
|
|
try {
|
|
await execFileAsync("which", ["import"]);
|
|
tool = "import";
|
|
} catch {
|
|
console.error("未找到可用的Linux截图工具");
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 根据可用工具执行截图
|
|
switch (tool) {
|
|
case "gnome-screenshot":
|
|
await execFileAsync("gnome-screenshot", ["-f", tmpFile]);
|
|
break;
|
|
case "scrot":
|
|
await execFileAsync("scrot", [tmpFile]);
|
|
break;
|
|
case "import":
|
|
await execFileAsync("import", ["-window", "root", tmpFile]);
|
|
break;
|
|
}
|
|
|
|
const imageBuffer = await readFileAsync(tmpFile);
|
|
return `data:image/png;base64,${imageBuffer.toString("base64")}`;
|
|
} catch (error) {
|
|
console.error("Linux截图失败:", error);
|
|
return null;
|
|
} finally {
|
|
await unlinkAsync(tmpFile).catch(() => {});
|
|
}
|
|
}
|
|
|
|
// 统一的截图接口
|
|
async function captureScreen() {
|
|
try {
|
|
if (process.platform === "darwin") {
|
|
return await captureMacScreen();
|
|
} else if (process.platform === "win32") {
|
|
return await captureWindowsScreen();
|
|
} else if (process.platform === "linux") {
|
|
return await captureLinuxScreen();
|
|
}
|
|
} catch (error) {
|
|
console.error("截图失败:", error);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
module.exports = { captureScreen };
|