const child_process = require("child_process"); const electron = require("electron"); const fs = require("fs"); const kill = require("tree-kill"); const iconv = require("iconv-lite"); const path = require("path"); const axios = require("axios"); const marked = require("marked"); const { chat, getModels } = require("./ai"); const { dbStorage } = utools; window.getModelsFromAiApi = getModels; const systemDialog = require("./dialog/service"); const { getQuickcommandTempFile } = require("./getQuickcommandFile"); const createTerminalCommand = require("./createTerminalCommand"); const ctlKey = window.utools.isMacOs() ? "command" : "control"; const getSleepCodeByShell = (ms) => { var cmd, tempFilePath; if (window.utools.isWindows()) { tempFilePath = getQuickcommandTempFile("vbs", "SleepVBSScript"); cmd = `echo set ws=CreateObject("Wscript.Shell") > ${tempFilePath} && echo Wscript.sleep ${ms} >> ${tempFilePath} && cscript /nologo ${tempFilePath}`; } else { cmd = `sleep ${ms / 1000}`; } return cmd; }; const quickcommand = { // 模拟复制操作 simulateCopy: function () { window.utools.simulateKeyboardTap("c", ctlKey); }, // 模拟粘贴操作 simulatePaste: function () { window.utools.simulateKeyboardTap("v", ctlKey); }, // setTimout 不能在 vm2 中使用,同时在 electron 中有 bug sleep: function (ms) { try { // node 16.13.1 child_process.execSync(getSleepCodeByShell(ms), { timeout: ms, windowsHide: true, }); } catch (ex) {} return; }, // 重写 setTimeout setTimeout: function (callback, ms) { const child = child_process.exec( getSleepCodeByShell(ms), { timeout: ms, }, () => { if (child.signalCode === "SIGKILL") return; callback(); } ); return child.pid; }, clearTimeout: function (pid) { kill(pid, "SIGKILL"); }, asyncSleep: async function (ms) { return new Promise((resolve) => { this.setTimeout(resolve, ms); }); }, // 关闭进程 kill: function (pid, signal = "SIGTERM", cb) { kill(pid, signal, cb); }, // dom 解析 htmlParse: function (html) { return new DOMParser().parseFromString(html, "text/html"); }, // markdown 解析 markdownParse: function (markdown) { return marked.parse(markdown); }, // 下载文件 downloadFile: function (url, file) { return new Promise((reslove, reject) => { if (!file || file instanceof Object) file = window.utools.showSaveDialog(JSON.parse(JSON.stringify(file))); axios({ method: "get", url: url, responseType: "arraybuffer", }) .then((res) => { var filebuffer = Buffer.from(res.data); fs.writeFile(file, filebuffer, (err) => { if (err) reject(err); else reslove(filebuffer); }); }) .catch((err) => { reject(err); }); }); }, // 上传文件 uploadFile: function (url, file, name = "file", formData = {}) { return new Promise((reslove, reject) => { var objfile; if (file instanceof File) { objfile = file; } else { if (!file || file instanceof Object) file = window.utools.showOpenDialog( JSON.parse(JSON.stringify(file)) )[0]; if (!fs.existsSync(file)) return reject("文件不存在"); var arraybuffer = fs.readFileSync(file).buffer; var objfile = new File([arraybuffer], path.basename(file)); } var form = new FormData(); form.append(name, objfile); var keys = Object.keys(formData); if (keys.length) keys.forEach((k) => form.append(k, formData[k])); axios .post(url, form, { headers: { accept: "application/json", "Content-Type": `multipart/form-data; boundary=${formData._boundary}`, }, }) .then((res) => { reslove(res); }) .catch((err) => { reject(err); }); }); }, // 载入在线资源 loadRemoteScript: async function (url) { if ( !/^((ht|f)tps?):\/\/([\w\-]+(\.[\w\-]+)*\/)*[\w\-]+(\.[\w\-]+)*\/?(\?([\w\-\.,@?^=%&:\/~\+#]*)+)?/.test( url ) ) throw "url 不合法"; let local = getQuickcommandTempFile("js"); await this.downloadFile(url, local); let source = require(local); fs.unlinkSync(local); return source; }, // 唤醒 uTools wakeUtools: function () { let uToolsPath = window.utools.isMacOs() ? process.execPath.replace(/\/Frameworks\/.*/, "/MacOS/uTools") : process.execPath; child_process.exec(uToolsPath, () => {}); }, readClipboard: function () { return electron.clipboard.readText(); }, writeClipboard: function (text) { electron.clipboard.writeText(text.toString()); }, readClipboardImage: function () { // 从剪贴板获取图片 const image = electron.clipboard.readImage(); if (!image.isEmpty()) { return image.toDataURL(); } // 尝试获取文本(可能是base64格式的图片) const clipboardText = electron.clipboard.readText(); if (clipboardText && clipboardText.startsWith("data:image")) { return clipboardText; } return null; }, askAI: async function (content, apiConfig, options) { if (window.lodashM.isEmpty(apiConfig)) { apiConfig = dbStorage.getItem("cfg_aiConfigs")?.[0] || {}; } return await chat(content, apiConfig, options); }, ...systemDialog, }; if (process.platform === "win32") { // 运行vbs脚本 quickcommand.runVbs = function (script) { return new Promise((reslove, reject) => { var tempfile = getQuickcommandTempFile("vbs"); fs.writeFile(tempfile, iconv.encode(script, "gbk"), () => { child_process.exec( `cscript.exe /nologo "${tempfile}"`, { encoding: "buffer", windowsHide: true, }, (err, stdout, stderr) => { if (err) reject(iconv.decode(stderr, "gbk")); else reslove(iconv.decode(stdout, "gbk")); fs.unlink(tempfile, () => {}); } ); }); }); }; // 运行powershell脚本 quickcommand.runPowerShell = function (script) { return new Promise((reslove, reject) => { let base64str = Buffer.from(script, "utf16le").toString("base64"); child_process.exec( `powershell.exe -e "${base64str}"`, { encoding: "buffer", windowsHide: true, }, (err, stdout, stderr) => { if (err) reject(iconv.decode(stderr, "gbk")); else reslove(iconv.decode(stdout, "gbk")); } ); }); }; } if (process.platform === "darwin") { // 运行AppleScript脚本 quickcommand.runAppleScript = function (script) { return new Promise((reslove, reject) => { child_process.execFile( "osascript", ["-e", script], (err, stdout, stderr) => { if (err) reject(stderr); else reslove(stdout); } ); }); }; } // python -c window.runPythonCommand = (py) => { try { let result = child_process.execFileSync("python", ["-c", py], { windowsHide: true, encoding: "buffer", }); return iconv .decode(result, window.utools.isWindows() ? "gbk" : "utf8") .trim(); } catch (e) { alert(e); return ""; } }; if (process.platform !== "linux") { // 在终端中执行 quickcommand.runInTerminal = function (cmdline, options) { // 兼容老版本接口, 老版本第二个参数是dir if (typeof options === "string") options = { dir: options }; let command = createTerminalCommand(cmdline, options); child_process.exec(command); }; } module.exports = quickcommand;