From 601df1f1e39e769cbdf944aefa22ece43cf1fc9e Mon Sep 17 00:00:00 2001 From: fofolee Date: Tue, 14 Jan 2025 10:44:43 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4C#=E8=B0=83=E7=94=A8=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E5=87=8F=E5=B0=91=E7=BC=96=E8=AF=91=E6=AC=A1?= =?UTF-8?q?=E6=95=B0=EF=BC=8C=E4=BC=98=E5=8C=96=E5=8F=82=E6=95=B0=E4=BC=A0?= =?UTF-8?q?=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/lib/csharp/dialog.cs | 18 +- plugin/lib/csharp/index.js | 93 +++ .../csharp/{automation.cs => sendmessage.cs} | 212 +++++-- plugin/lib/csharp/window.cs | 454 +++++++++++++++ plugin/lib/js/monitor.js | 49 -- plugin/lib/quickcomposer/windows/index.js | 6 +- plugin/lib/quickcomposer/windows/message.js | 316 ---------- plugin/lib/quickcomposer/windows/monitor.js | 13 +- .../windows/{automation.js => sendmessage.js} | 47 +- plugin/lib/quickcomposer/windows/window.js | 540 +++--------------- plugin/lib/systemDialog.js | 22 +- src/js/composer/commands/uiCommands.js | 218 +++---- src/js/composer/commands/windowsCommands.js | 28 +- 13 files changed, 956 insertions(+), 1060 deletions(-) create mode 100644 plugin/lib/csharp/index.js rename plugin/lib/csharp/{automation.cs => sendmessage.cs} (79%) create mode 100644 plugin/lib/csharp/window.cs delete mode 100644 plugin/lib/js/monitor.js delete mode 100644 plugin/lib/quickcomposer/windows/message.js rename plugin/lib/quickcomposer/windows/{automation.js => sendmessage.js} (68%) diff --git a/plugin/lib/csharp/dialog.cs b/plugin/lib/csharp/dialog.cs index bb455eb..f647fde 100644 --- a/plugin/lib/csharp/dialog.cs +++ b/plugin/lib/csharp/dialog.cs @@ -17,14 +17,14 @@ public class DialogGenerator private const int LOGPIXELSX = 88; private const int LOGPIXELSY = 90; - // 基础尺寸常量 (96 DPI下的尺寸,当前尺寸/1.75) - private const int BASE_WIDTH = 515; // 900/1.75 ≈ 515 - private const int BASE_HEIGHT = 200; // 350/1.75 ≈ 200 - private const int BASE_PADDING = 17; // 30/1.75 ≈ 17 - private const int BASE_BUTTON_HEIGHT = 29; // 50/1.75 ≈ 29 - private const int BASE_BUTTON_WIDTH = 80; // 140/1.75 ≈ 80 - private const int BASE_INPUT_HEIGHT = 23; // 40/1.75 ≈ 23 - private const int BASE_SPACING = 11; // 20/1.75 ≈ 11 + // 基础尺寸常量 (96 DPI下的尺寸,当前尺寸/2) + private const int BASE_WIDTH = 450; // 900/2 = 450 + private const int BASE_HEIGHT = 175; // 350/2 = 175 + private const int BASE_PADDING = 15; // 30/2 = 15 + private const int BASE_BUTTON_HEIGHT = 25; // 50/2 = 25 + private const int BASE_BUTTON_WIDTH = 70; // 140/2 = 70 + private const int BASE_INPUT_HEIGHT = 20; // 40/2 = 20 + private const int BASE_SPACING = 10; // 20/2 = 10 // 实际使用的缩放尺寸 private static int DEFAULT_WIDTH; @@ -80,7 +80,7 @@ public class DialogGenerator if (string.IsNullOrEmpty(type) || string.IsNullOrEmpty(title)) { - MessageBox.Show("必须指定 -type 和 -title 参数"); + ShowHelp(); return DialogResult.None; } diff --git a/plugin/lib/csharp/index.js b/plugin/lib/csharp/index.js new file mode 100644 index 0000000..71fb5dc --- /dev/null +++ b/plugin/lib/csharp/index.js @@ -0,0 +1,93 @@ +const fs = require("fs"); +const path = require("path"); +const iconv = require("iconv-lite"); +const child_process = require("child_process"); +const { getQuickcommandFolderFile } = require("../getQuickcommandFile"); +const getCsharpFeatureCs = (feature) => { + return path.join(__dirname, feature + ".cs"); +}; + +const getCsharpFeatureExe = async (feature, alwaysBuildNewExe = false) => { + const exePath = getQuickcommandFolderFile(feature, "exe"); + if (!fs.existsSync(exePath) || alwaysBuildNewExe) { + await buildCsharpFeature(feature); + } + return exePath; +}; + +const buildCsharpFeature = async (feature) => { + return new Promise((resolve, reject) => { + const exePath = getQuickcommandFolderFile(feature, "exe"); + const srcCsPath = getCsharpFeatureCs(feature); + const destCsPath = getQuickcommandFolderFile(feature, "cs"); + const cscPath = getCscPath(); + fs.copyFile(srcCsPath, destCsPath, (err) => { + if (err) return reject(err.toString()); + child_process.exec( + `${cscPath} /nologo /out:${exePath} ${destCsPath}`, + { encoding: null }, + (err, stdout) => { + if (err) return reject(iconv.decode(stdout, "gbk")); + else resolve(iconv.decode(stdout, "gbk")); + fs.unlink(destCsPath, () => {}); + } + ); + }); + }); +}; + +const getCscPath = () => { + const cscPath = path.join( + process.env.WINDIR, + "Microsoft.NET", + "Framework", + "v4.0.30319", + "csc.exe" + ); + if (!fs.existsSync(cscPath)) { + cscPath = path.join( + process.env.WINDIR, + "Microsoft.NET", + "Framework", + "v3.5", + "csc.exe" + ); + } + if (!fs.existsSync(cscPath)) { + throw new Error("未安装.NET Framework"); + } + return cscPath; +}; + +/** + * 运行C#插件 + * @param {string} feature - 插件名称 + * @param {string[]} args - 参数 + * @param {object} options - 选项 + * @param {boolean} options.alwaysBuildNewExe - 是否总是构建新的可执行文件 + * @returns {Promise} - 返回结果 + */ +const runCsharpFeature = async (feature, args = [], options = {}) => { + return new Promise(async (reslove, reject) => { + const { alwaysBuildNewExe = false } = options; + try { + const featureExePath = await getCsharpFeatureExe(feature, alwaysBuildNewExe); + child_process.execFile( + featureExePath, + args, + { + encoding: null, + }, + (err, stdout) => { + console.log(iconv.decode(stdout, "gbk")); + if (err) reject(iconv.decode(stdout, "gbk")); + else reslove(iconv.decode(stdout, "gbk")); + } + ); + } catch (error) { + return reject(error.toString()); + } + }); +}; + +module.exports = { runCsharpFeature }; diff --git a/plugin/lib/csharp/automation.cs b/plugin/lib/csharp/sendmessage.cs similarity index 79% rename from plugin/lib/csharp/automation.cs rename to plugin/lib/csharp/sendmessage.cs index e93281c..38ce5d1 100644 --- a/plugin/lib/csharp/automation.cs +++ b/plugin/lib/csharp/sendmessage.cs @@ -63,6 +63,7 @@ public class AutomationTool private const uint WM_KEYDOWN = 0x0100; private const uint WM_KEYUP = 0x0101; + private const uint WM_KEYPRESS = 0x0102; private const uint WM_CHAR = 0x0102; private const uint WM_SETTEXT = 0x000C; private const uint WM_LBUTTONDOWN = 0x0201; @@ -123,6 +124,9 @@ public class AutomationTool [DllImport("user32.dll")] private static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, ref RECT lParam); + + [DllImport("user32.dll")] + private static extern uint MapVirtualKey(uint uCode, uint uMapType); #endregion public static void Main(string[] args) @@ -172,46 +176,60 @@ public class AutomationTool } } - private static List FindTargetWindows(string window) + private static List FindTargetWindows(string[] args) { List targetWindows = new List(); - if (string.IsNullOrEmpty(window)) + string method = GetArgumentValue(args, "-method") ?? "title"; + string value = GetArgumentValue(args, "-window") ?? ""; + + if (method == "active") { targetWindows.Add(GetForegroundWindow()); + return targetWindows; } - else + + if (method == "handle") { - // 查找所有匹配的窗口 - EnumWindows((hwnd, param) => + targetWindows.Add(new IntPtr(long.Parse(value))); + return targetWindows; + } + + // title方式 + if (string.IsNullOrEmpty(value)) + { + return targetWindows; + } + + // 查找所有匹配的窗口 + EnumWindows((hwnd, param) => + { + StringBuilder title = new StringBuilder(256); + GetWindowText(hwnd, title, title.Capacity); + string windowTitle = title.ToString(); + + if (!string.IsNullOrEmpty(windowTitle) && + windowTitle.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) + { + targetWindows.Add(hwnd); + } + return true; + }, IntPtr.Zero); + + if (targetWindows.Count == 0) + { + Console.WriteLine("Error: 未找到匹配的窗口"); + return targetWindows; + } + + // 如果找到多个窗口,输出所有窗口信息 + if (targetWindows.Count > 1) + { + Console.WriteLine("找到 {0} 个匹配窗口:", targetWindows.Count); + foreach (IntPtr hwnd in targetWindows) { StringBuilder title = new StringBuilder(256); GetWindowText(hwnd, title, title.Capacity); - string windowTitle = title.ToString(); - - if (!string.IsNullOrEmpty(windowTitle) && - windowTitle.IndexOf(window, StringComparison.OrdinalIgnoreCase) >= 0) - { - targetWindows.Add(hwnd); - } - return true; - }, IntPtr.Zero); - - if (targetWindows.Count == 0) - { - Console.WriteLine("Error: 未找到匹配的窗口"); - return targetWindows; - } - - // 如果找到多个窗口,输出所有窗口信息 - if (targetWindows.Count > 1) - { - Console.WriteLine("找到 {0} 个匹配窗口:", targetWindows.Count); - foreach (IntPtr hwnd in targetWindows) - { - StringBuilder title = new StringBuilder(256); - GetWindowText(hwnd, title, title.Capacity); - Console.WriteLine("0x{0:X} - {1}", hwnd.ToInt64(), title); - } + Console.WriteLine("0x{0:X} - {1}", hwnd.ToInt64(), title); } } @@ -220,7 +238,6 @@ public class AutomationTool private static void HandleKeyboardOperation(string[] args) { - string window = GetArgumentValue(args, "-window"); string control = GetArgumentValue(args, "-control"); string action = GetArgumentValue(args, "-action"); string value = GetArgumentValue(args, "-value"); @@ -232,7 +249,7 @@ public class AutomationTool return; } - var targetWindows = FindTargetWindows(window); + var targetWindows = FindTargetWindows(args); if (targetWindows.Count == 0) { return; @@ -293,7 +310,6 @@ public class AutomationTool private static void HandleMouseOperation(string[] args) { - string window = GetArgumentValue(args, "-window"); string control = GetArgumentValue(args, "-control"); string controlText = GetArgumentValue(args, "-text"); string action = GetArgumentValue(args, "-action"); @@ -306,7 +322,7 @@ public class AutomationTool return; } - var targetWindows = FindTargetWindows(window); + var targetWindows = FindTargetWindows(args); if (targetWindows.Count == 0) { return; @@ -416,18 +432,17 @@ public class AutomationTool PostMessage(hWnd, WM_KEYDOWN, modifier, 0); } - // 按下主键 + // 发送主键字符 if (mainKey > 0) { - PostMessage(hWnd, WM_KEYDOWN, mainKey, 0); - Thread.Sleep(10); - PostMessage(hWnd, WM_KEYUP, mainKey, 0); + PostMessage(hWnd, WM_CHAR, mainKey, 0); } // 释放修饰键 for (int i = modifierKeys.Count - 1; i >= 0; i--) { - PostMessage(hWnd, WM_KEYUP, modifierKeys[i], 0); + byte modifier = modifierKeys[i]; + PostMessage(hWnd, WM_KEYUP, modifier, 0); } // 如果有多个按键组合,等待一下 @@ -438,6 +453,58 @@ public class AutomationTool } } + private static bool IsSpecialKey(byte vKey) + { + switch (vKey) + { + // 修饰键 + case 0xA0: // VK_LSHIFT + case 0xA2: // VK_LCONTROL + case 0xA4: // VK_LMENU + case 0x5B: // VK_LWIN + // 控制键 + case 0x08: // VK_BACK + case 0x09: // VK_TAB + case 0x0D: // VK_RETURN + case 0x1B: // VK_ESCAPE + case 0x20: // VK_SPACE + case 0x2E: // VK_DELETE + // 方向键 + case 0x25: // VK_LEFT + case 0x26: // VK_UP + case 0x27: // VK_RIGHT + case 0x28: // VK_DOWN + // 导航键 + case 0x24: // VK_HOME + case 0x23: // VK_END + case 0x21: // VK_PRIOR (PageUp) + case 0x22: // VK_NEXT (PageDown) + case 0x2D: // VK_INSERT + // 功能键 + case 0x70: // VK_F1 + case 0x71: // VK_F2 + case 0x72: // VK_F3 + case 0x73: // VK_F4 + case 0x74: // VK_F5 + case 0x75: // VK_F6 + case 0x76: // VK_F7 + case 0x77: // VK_F8 + case 0x78: // VK_F9 + case 0x79: // VK_F10 + case 0x7A: // VK_F11 + case 0x7B: // VK_F12 + // 其他常用键 + case 0x14: // VK_CAPITAL + case 0x90: // VK_NUMLOCK + case 0x91: // VK_SCROLL + case 0x2C: // VK_SNAPSHOT + case 0x13: // VK_PAUSE + return true; + default: + return false; + } + } + private static void SendText(IntPtr hWnd, string text) { StringBuilder sb = new StringBuilder(text); @@ -465,16 +532,47 @@ public class AutomationTool { switch (key.ToLower()) { - case "ctrl": return 0x11; - case "alt": return 0x12; - case "shift": return 0x10; - case "win": return 0x5B; + case "ctrl": + case "^": return 0xA2; // VK_LCONTROL + case "alt": return 0xA4; // VK_LMENU + case "shift": return 0xA0; // VK_LSHIFT + case "win": return 0x5B; // VK_LWIN case "enter": return 0x0D; case "tab": return 0x09; case "esc": return 0x1B; case "space": return 0x20; case "backspace": return 0x08; case "delete": return 0x2E; + // 方向键 + case "left": return 0x25; // VK_LEFT + case "up": return 0x26; // VK_UP + case "right": return 0x27; // VK_RIGHT + case "down": return 0x28; // VK_DOWN + // 导航键 + case "home": return 0x24; // VK_HOME + case "end": return 0x23; // VK_END + case "pageup": return 0x21; // VK_PRIOR + case "pagedown": return 0x22; // VK_NEXT + case "insert": return 0x2D; // VK_INSERT + // 功能键 + case "f1": return 0x70; // VK_F1 + case "f2": return 0x71; + case "f3": return 0x72; + case "f4": return 0x73; + case "f5": return 0x74; + case "f6": return 0x75; + case "f7": return 0x76; + case "f8": return 0x77; + case "f9": return 0x78; + case "f10": return 0x79; + case "f11": return 0x7A; + case "f12": return 0x7B; + // 其他常用键 + case "capslock": return 0x14; // VK_CAPITAL + case "numlock": return 0x90; // VK_NUMLOCK + case "scrolllock": return 0x91; // VK_SCROLL + case "printscreen": return 0x2C; // VK_SNAPSHOT + case "pause": return 0x13; // VK_PAUSE default: if (key.Length == 1) { @@ -628,11 +726,10 @@ public class AutomationTool private static void HandleInspectOperation(string[] args) { - string window = GetArgumentValue(args, "-window"); string filter = GetArgumentValue(args, "-filter"); bool background = bool.Parse(GetArgumentValue(args, "-background") ?? "false"); - var targetWindows = FindTargetWindows(window); + var targetWindows = FindTargetWindows(args); if (targetWindows.Count == 0) { return; @@ -739,7 +836,7 @@ Windows 界面自动化工具使用说明 ========================== 基本语法: -automation.exe -type <操作类型> [参数...] +sendmessage.exe -type <操作类型> [参数...] 操作类型: -------- @@ -749,6 +846,9 @@ automation.exe -type <操作类型> [参数...] 通用参数: -------- ++-method 窗口查找方式(可选,默认title) ++ 可选值:title(标题), handle(句柄), active(活动窗口) ++ -window 窗口标题或句柄(支持模糊匹配) -control 控件类名 -background 后台操作,不激活窗口,默认激活 @@ -771,19 +871,25 @@ automation.exe -type <操作类型> [参数...] 使用示例: -------- 1. 发送按键到指定窗口: - automation.exe -type keyboard -action keys -window ""记事本"" -value ""ctrl+a"" + sendmessage.exe -type keyboard -action keys -window ""记事本"" -value ""ctrl+a"" 2. 发送文本到指定控件: - automation.exe -type keyboard -action text -window ""记事本"" -control ""Edit"" -value ""Hello World"" + sendmessage.exe -type keyboard -action text -window ""记事本"" -control ""Edit"" -value ""Hello World"" 3. 点击指定控件: - automation.exe -type mouse -action click -window ""记事本"" -control ""Button"" -text ""确定"" + sendmessage.exe -type mouse -action click -window ""记事本"" -control ""Button"" -text ""确定"" 4. 后台发送文本: - automation.exe -type keyboard -action text -window ""记事本"" -value ""Hello"" -background + sendmessage.exe -type keyboard -action text -window ""记事本"" -value ""Hello"" -background 5. 获取窗口控件树: - automation.exe -type inspect -window ""记事本"" -filter ""button"" + sendmessage.exe -type inspect -window ""记事本"" -filter ""button"" + +6. 使用句柄查找窗口: + sendmessage.exe -type keyboard -method handle -window ""0x12345"" -value ""Hello"" + +7. 操作当前活动窗口: + sendmessage.exe -type keyboard -method active -value ""ctrl+s"" 注意事项: -------- @@ -791,6 +897,8 @@ automation.exe -type <操作类型> [参数...] 2. 控件类名需要完全匹配 3. 后台操作可能会影响某些程序的响应 4. 建议先用inspect获取正确的控件信息再进行操作 +5. handle方式查找窗口时需要提供正确的窗口句柄 +6. active方式不需要提供window参数,直接操作当前活动窗口 "; Console.WriteLine(help); } diff --git a/plugin/lib/csharp/window.cs b/plugin/lib/csharp/window.cs new file mode 100644 index 0000000..0c3a9b0 --- /dev/null +++ b/plugin/lib/csharp/window.cs @@ -0,0 +1,454 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; +using System.Diagnostics; +using System.Web.Script.Serialization; + +public class WindowManager +{ + #region Win32 API + [DllImport("user32.dll")] + private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); + + [DllImport("user32.dll")] + private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); + + [DllImport("user32.dll")] + private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); + + [DllImport("user32.dll")] + private static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll")] + private static extern bool SetForegroundWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags); + + [DllImport("user32.dll")] + private static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll")] + private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); + + [DllImport("user32.dll")] + private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + + [DllImport("user32.dll")] + private static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll")] + private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); + + [DllImport("user32.dll")] + private static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect); + + [DllImport("user32.dll")] + private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); + + [DllImport("user32.dll")] + private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); + + [DllImport("user32.dll")] + private static extern bool IsWindowVisible(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern bool IsIconic(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern bool IsZoomed(IntPtr hWnd); + + [DllImport("user32.dll")] + private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); + + [DllImport("user32.dll")] + private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); + + [StructLayout(LayoutKind.Sequential)] + private struct RECT + { + public int Left; + public int Top; + public int Right; + public int Bottom; + } + + private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); + private static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); + private const uint SWP_NOMOVE = 0x0002; + private const uint SWP_NOSIZE = 0x0001; + private const uint WM_CLOSE = 0x0010; + private const int GWL_STYLE = -16; + private const int GWL_EXSTYLE = -20; + private const int WS_BORDER = 0x00800000; + private const int WS_CAPTION = 0x00C00000; + private const int WS_CHILD = 0x40000000; + private const int WS_POPUP = unchecked((int)0x80000000); + private const int WS_SYSMENU = 0x00080000; + private const int WS_MINIMIZEBOX = 0x00020000; + private const int WS_MAXIMIZEBOX = 0x00010000; + private const int WS_EX_TOPMOST = 0x00000008; + private const int WS_EX_TRANSPARENT = 0x00000020; + private const int WS_EX_TOOLWINDOW = 0x00000080; + private const int WS_EX_LAYERED = 0x00080000; + private const uint LWA_ALPHA = 0x2; + private const int SW_HIDE = 0; + private const int SW_SHOW = 5; + private const int SW_NORMAL = 1; + private const int SW_MAXIMIZE = 3; + private const int SW_MINIMIZE = 6; + private const int SW_RESTORE = 9; + + private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); + #endregion + + public static void Main(string[] args) + { + if (args.Length == 0 || args[0] == "-h" || args[0] == "--help") + { + ShowHelp(); + return; + } + + string type = GetArgumentValue(args, "-type"); + if (string.IsNullOrEmpty(type)) + { + Console.Error.WriteLine("Error: 必须指定操作类型 (-type)"); + return; + } + + try + { + IntPtr hwnd = GetWindowHandle(args); + if (hwnd == IntPtr.Zero) + { + Console.Error.WriteLine("Error: 未找到目标窗口"); + return; + } + + switch (type.ToLower()) + { + case "topmost": + bool isTopMost = bool.Parse(GetArgumentValue(args, "-value") ?? "true"); + SetWindowPos(hwnd, isTopMost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + break; + + case "opacity": + int opacity = int.Parse(GetArgumentValue(args, "-value") ?? "100"); + SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); + SetLayeredWindowAttributes(hwnd, 0, (byte)(opacity * 2.55), LWA_ALPHA); + break; + + case "rect": + string[] rectValues = (GetArgumentValue(args, "-value") ?? "").Split(','); + if (rectValues.Length == 4) + { + int x = int.Parse(rectValues[0]); + int y = int.Parse(rectValues[1]); + int width = int.Parse(rectValues[2]); + int height = int.Parse(rectValues[3]); + MoveWindow(hwnd, x, y, width, height, true); + } + break; + + case "state": + string state = GetArgumentValue(args, "-value") ?? "normal"; + int cmdShow = state == "maximize" ? SW_MAXIMIZE : + state == "minimize" ? SW_MINIMIZE : SW_NORMAL; + ShowWindow(hwnd, cmdShow); + break; + + case "visible": + bool visible = bool.Parse(GetArgumentValue(args, "-value") ?? "true"); + ShowWindow(hwnd, visible ? SW_SHOW : SW_HIDE); + break; + + case "close": + PostMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); + break; + + case "focus": + if (IsIconic(hwnd)) + { + ShowWindow(hwnd, SW_RESTORE); + } + SetForegroundWindow(hwnd); + break; + + case "border": + bool hasBorder = bool.Parse(GetArgumentValue(args, "-value") ?? "true"); + int style = GetWindowLong(hwnd, GWL_STYLE); + style = hasBorder ? style | WS_CAPTION : style & ~WS_CAPTION; + SetWindowLong(hwnd, GWL_STYLE, style); + break; + + case "clickthrough": + bool isTransparent = bool.Parse(GetArgumentValue(args, "-value") ?? "true"); + int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); + exStyle |= WS_EX_LAYERED; + exStyle = isTransparent ? exStyle | WS_EX_TRANSPARENT : exStyle & ~WS_EX_TRANSPARENT; + SetWindowLong(hwnd, GWL_EXSTYLE, exStyle); + break; + + case "info": + GetWindowInfo(hwnd); + break; + + default: + Console.Error.WriteLine("Error: 不支持的操作类型"); + break; + } + } + catch (Exception ex) + { + Console.Error.WriteLine(string.Format("Error: {0}", ex.Message)); + } + } + + private static IntPtr GetWindowHandle(string[] args) + { + string method = GetArgumentValue(args, "-method") ?? "title"; + string value = GetArgumentValue(args, "-window") ?? ""; + + switch (method.ToLower()) + { + case "handle": + return new IntPtr(long.Parse(value)); + case "active": + return GetForegroundWindow(); + default: // title + if (string.IsNullOrEmpty(value)) + { + return IntPtr.Zero; + } + + IntPtr foundWindow = IntPtr.Zero; + EnumWindows((hwnd, param) => + { + StringBuilder title = new StringBuilder(256); + GetWindowText(hwnd, title, title.Capacity); + string windowTitle = title.ToString(); + + if (!string.IsNullOrEmpty(windowTitle) && + windowTitle.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) + { + foundWindow = hwnd; + return false; // 找到后停止枚举 + } + return true; + }, IntPtr.Zero); + + return foundWindow; + } + } + + private static void GetWindowInfo(IntPtr hwnd) + { + var windowRect = new RECT(); + GetWindowRect(hwnd, out windowRect); + + var clientRect = new RECT(); + GetClientRect(hwnd, out clientRect); + + var titleText = new StringBuilder(256); + GetWindowText(hwnd, titleText, 256); + + var className = new StringBuilder(256); + GetClassName(hwnd, className, 256); + + uint processId = 0; + GetWindowThreadProcessId(hwnd, out processId); + + string processName = ""; + string processPath = ""; + try + { + Process process = Process.GetProcessById((int)processId); + processName = process.ProcessName; + + var startInfo = new ProcessStartInfo + { + FileName = "wmic", + Arguments = string.Format("process where ProcessId={0} get ExecutablePath /value", processId), + UseShellExecute = false, + RedirectStandardOutput = true, + CreateNoWindow = true + }; + using (var proc = Process.Start(startInfo)) + { + string output = proc.StandardOutput.ReadToEnd(); + if (!string.IsNullOrEmpty(output)) + { + string[] lines = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); + foreach (string line in lines) + { + if (line.StartsWith("ExecutablePath=")) + { + processPath = line.Substring("ExecutablePath=".Length); + break; + } + } + } + } + } + catch { } + + int style = GetWindowLong(hwnd, GWL_STYLE); + int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); + + var data = new + { + handle = hwnd.ToInt64(), + processId = processId, + process = new + { + name = processName, + path = processPath + }, + title = titleText.ToString(), + className = className.ToString(), + window = new + { + x = windowRect.Left, + y = windowRect.Top, + width = windowRect.Right - windowRect.Left, + height = windowRect.Bottom - windowRect.Top + }, + client = new + { + width = clientRect.Right - clientRect.Left, + height = clientRect.Bottom - clientRect.Top + }, + state = new + { + visible = IsWindowVisible(hwnd), + minimized = IsIconic(hwnd), + maximized = IsZoomed(hwnd), + focused = GetForegroundWindow() == hwnd + }, + style = new + { + border = (style & WS_BORDER) != 0, + caption = (style & WS_CAPTION) != 0, + child = (style & WS_CHILD) != 0, + popup = (style & WS_POPUP) != 0, + sysmenu = (style & WS_SYSMENU) != 0, + minimizeBox = (style & WS_MINIMIZEBOX) != 0, + maximizeBox = (style & WS_MAXIMIZEBOX) != 0 + }, + exStyle = new + { + topmost = (exStyle & WS_EX_TOPMOST) != 0, + transparent = (exStyle & WS_EX_TRANSPARENT) != 0, + toolWindow = (exStyle & WS_EX_TOOLWINDOW) != 0, + layered = (exStyle & WS_EX_LAYERED) != 0 + } + }; + + var serializer = new JavaScriptSerializer(); + Console.WriteLine(serializer.Serialize(data)); + } + + private static string GetArgumentValue(string[] args, string key) + { + int index = Array.IndexOf(args, key); + if (index >= 0 && index < args.Length - 1) + { + return args[index + 1]; + } + return null; + } + + private static void ShowHelp() + { + string help = @" +Windows 窗口管理工具使用说明 +========================== + +基本语法: +window.exe -type <操作类型> [参数...] + +操作类型: +-------- +1. topmost - 设置窗口置顶 +2. opacity - 设置窗口透明度 +3. rect - 设置窗口位置和大小 +4. state - 设置窗口状态 +5. visible - 设置窗口可见性 +6. close - 关闭窗口 +7. focus - 设置窗口焦点 +8. border - 设置窗口边框 +9. clickthrough - 设置点击穿透 +10. info - 获取窗口信息 + +通用参数: +-------- +-method 窗口查找方式(可选,默认title) + 可选值:title, handle, active + +-window 窗口标题或句柄 + 示例:-window ""记事本"" + +-value 操作值,根据不同操作类型有不同含义 + +操作参数说明: +----------- +1. topmost: + -value true/false,是否置顶 + +2. opacity: + -value 0-100,透明度 + +3. rect: + -value x,y,width,height,窗口位置和大小 + +4. state: + -value normal/maximize/minimize,窗口状态 + +5. visible: + -value true/false,是否可见 + +6. border: + -value true/false,是否显示边框 + +7. clickthrough: + -value true/false,是否点击穿透 + +使用示例: +-------- +1. 设置窗口置顶: + window.exe -type topmost -window ""记事本"" -value true + +2. 设置窗口透明度: + window.exe -type opacity -window ""记事本"" -value 80 + +3. 设置窗口位置和大小: + window.exe -type rect -window ""记事本"" -value ""100,100,800,600"" + +4. 最大化窗口: + window.exe -type state -window ""记事本"" -value maximize + +5. 隐藏窗口: + window.exe -type visible -window ""记事本"" -value false + +6. 关闭窗口: + window.exe -type close -window ""记事本"" + +7. 获取窗口信息: + window.exe -type info -window ""记事本"" + +返回值: +------ +1. info操作返回JSON格式的窗口信息 +2. 其他操作无返回值,执行失败时输出错误信息 + +注意事项: +-------- +1. 窗口标题支持模糊匹配 +2. handle方式查找窗口时需要提供正确的窗口句柄 +3. active方式不需要提供window参数,直接操作当前活动窗口 +4. 某些操作可能需要管理员权限 +"; + Console.WriteLine(help); + } +} diff --git a/plugin/lib/js/monitor.js b/plugin/lib/js/monitor.js deleted file mode 100644 index c897c02..0000000 --- a/plugin/lib/js/monitor.js +++ /dev/null @@ -1,49 +0,0 @@ -const fs = require("fs"); -const path = require("path"); -const quickcommand = require("../../quickcommand"); - -// 读取 monitor.cs 模板 -const monitorTemplate = fs.readFileSync( - path.join(__dirname, "..", "csharp", "monitor.cs"), - "utf8" -); - -// 监控剪贴板变化 -const watchClipboard = async function () { - const args = ["-type", "clipboard"]; - const result = await quickcommand.runCsharp(monitorTemplate, args); - if (result && result.startsWith("Error:")) { - throw new Error(result.substring(7)); - } - return true; -}; - -// 监控文件系统变化 -const watchFileSystem = async function (options = {}) { - const { path: watchPath, filter = "*.*", recursive = true } = options; - - if (!watchPath) { - throw new Error("必须指定监控路径"); - } - - const args = ["-type", "filesystem", "-path", watchPath]; - - if (filter !== "*.*") { - args.push("-filter", filter); - } - - if (!recursive) { - args.push("-recursive", "false"); - } - - const result = await quickcommand.runCsharp(monitorTemplate, args); - if (result && result.startsWith("Error:")) { - throw new Error(result.substring(7)); - } - return true; -}; - -module.exports = { - watchClipboard, - watchFileSystem, -}; diff --git a/plugin/lib/quickcomposer/windows/index.js b/plugin/lib/quickcomposer/windows/index.js index 7393a2d..37f8aef 100644 --- a/plugin/lib/quickcomposer/windows/index.js +++ b/plugin/lib/quickcomposer/windows/index.js @@ -1,11 +1,9 @@ const window = require("./window"); -const message = require("./message"); -const automation = require("./automation"); +const sendmessage = require("./sendmessage"); const monitor = require("./monitor"); module.exports = { window, - message, - automation, + sendmessage, monitor, }; diff --git a/plugin/lib/quickcomposer/windows/message.js b/plugin/lib/quickcomposer/windows/message.js deleted file mode 100644 index d4eaa7f..0000000 --- a/plugin/lib/quickcomposer/windows/message.js +++ /dev/null @@ -1,316 +0,0 @@ -/** - * 发送窗口消息 - * @param {string} method 查找方式:title/handle/active - * @param {string} value 查找值(handle时为数字) - * @param {string} type 消息类型:click/key/text/custom - * @param {Object} params 消息参数 - */ -async function sendMessage(method, value, type, params) { - let messageScript = ""; - - switch (type) { - case "click": - messageScript = ` - const uint WM_LBUTTONDOWN = 0x0201; - const uint WM_LBUTTONUP = 0x0202; - const uint WM_RBUTTONDOWN = 0x0204; - const uint WM_RBUTTONUP = 0x0205; - const uint WM_MBUTTONDOWN = 0x0207; - const uint WM_MBUTTONUP = 0x0208; - - IntPtr wParam = IntPtr.Zero; - IntPtr lParam = (IntPtr)((${params.y} << 16) | ${params.x}); - - switch("${params.button}") { - case "left": - PostMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam); - PostMessage(hwnd, WM_LBUTTONUP, wParam, lParam); - break; - case "right": - PostMessage(hwnd, WM_RBUTTONDOWN, wParam, lParam); - PostMessage(hwnd, WM_RBUTTONUP, wParam, lParam); - break; - case "middle": - PostMessage(hwnd, WM_MBUTTONDOWN, wParam, lParam); - PostMessage(hwnd, WM_MBUTTONUP, wParam, lParam); - break; - }`; - break; - - case "key": - messageScript = ` - const uint WM_KEYDOWN = 0x0100; - const uint WM_KEYUP = 0x0101; - const uint WM_CHAR = 0x0102; - - // 处理组合键 - int modifiers = 0; - if(${params.ctrl}) modifiers |= 0x0008; - if(${params.alt}) modifiers |= 0x0001; - if(${params.shift}) modifiers |= 0x0004; - - IntPtr wParam = (IntPtr)${params.keyCode}; - IntPtr lParam = (IntPtr)((0x00000001 | (modifiers << 16))); - - PostMessage(hwnd, WM_KEYDOWN, wParam, lParam); - if(!${params.hold}) { - PostMessage(hwnd, WM_KEYUP, wParam, lParam); - }`; - break; - - case "text": - messageScript = ` - const uint WM_CHAR = 0x0102; - string text = @"${params.text}"; - - foreach(char c in text) { - PostMessage(hwnd, WM_CHAR, (IntPtr)c, IntPtr.Zero); - }`; - break; - - case "custom": - messageScript = ` - uint msg = ${params.message}; - IntPtr wParam = (IntPtr)${params.wParam}; - IntPtr lParam = (IntPtr)${params.lParam}; - - PostMessage(hwnd, msg, wParam, lParam);`; - break; - } - - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - - public class Program { - [DllImport("user32.dll")] - static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - [DllImport("user32.dll")] - static extern IntPtr GetForegroundWindow(); - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - ${messageScript} - } - } - } - `; - - await quickcommand.runCsharp(script); -} - -/** - * 发送鼠标点击消息 - */ -async function sendMouseClick(method, value, params) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - - public class Program { - [DllImport("user32.dll")] - static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - [DllImport("user32.dll")] - static extern IntPtr GetForegroundWindow(); - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - const uint WM_LBUTTONDOWN = 0x0201; - const uint WM_LBUTTONUP = 0x0202; - const uint WM_RBUTTONDOWN = 0x0204; - const uint WM_RBUTTONUP = 0x0205; - const uint WM_MBUTTONDOWN = 0x0207; - const uint WM_MBUTTONUP = 0x0208; - - IntPtr wParam = IntPtr.Zero; - IntPtr lParam = (IntPtr)((${params.y} << 16) | ${params.x}); - - switch("${params.button}") { - case "left": - PostMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam); - PostMessage(hwnd, WM_LBUTTONUP, wParam, lParam); - break; - case "right": - PostMessage(hwnd, WM_RBUTTONDOWN, wParam, lParam); - PostMessage(hwnd, WM_RBUTTONUP, wParam, lParam); - break; - case "middle": - PostMessage(hwnd, WM_MBUTTONDOWN, wParam, lParam); - PostMessage(hwnd, WM_MBUTTONUP, wParam, lParam); - break; - } - } - } - } - `; - await quickcommand.runCsharp(script); -} - -/** - * 发送键盘按键消息 - */ -async function sendKeyPress(method, value, params) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - - public class Program { - [DllImport("user32.dll")] - static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - [DllImport("user32.dll")] - static extern IntPtr GetForegroundWindow(); - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - const uint WM_KEYDOWN = 0x0100; - const uint WM_KEYUP = 0x0101; - const uint WM_CHAR = 0x0102; - - int modifiers = 0; - if(${params.ctrl}) modifiers |= 0x0008; - if(${params.alt}) modifiers |= 0x0001; - if(${params.shift}) modifiers |= 0x0004; - - IntPtr wParam = (IntPtr)${params.keyCode}; - IntPtr lParam = (IntPtr)((0x00000001 | (modifiers << 16))); - - PostMessage(hwnd, WM_KEYDOWN, wParam, lParam); - if(!${params.hold}) { - PostMessage(hwnd, WM_KEYUP, wParam, lParam); - } - } - } - } - `; - await quickcommand.runCsharp(script); -} - -/** - * 发送文本输入消息 - */ -async function sendText(method, value, params) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - - public class Program { - [DllImport("user32.dll")] - static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - [DllImport("user32.dll")] - static extern IntPtr GetForegroundWindow(); - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - const uint WM_CHAR = 0x0102; - string text = @"${params.text}"; - - foreach(char c in text) { - PostMessage(hwnd, WM_CHAR, (IntPtr)c, IntPtr.Zero); - } - } - } - } - `; - await quickcommand.runCsharp(script); -} - -/** - * 发送窗口命令消息 - */ -async function sendCommand(method, value, params) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - - public class Program { - [DllImport("user32.dll")] - static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - [DllImport("user32.dll")] - static extern IntPtr GetForegroundWindow(); - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - uint msg = ${params.message}; - IntPtr wParam = (IntPtr)${params.wParam}; - IntPtr lParam = (IntPtr)${params.lParam}; - - PostMessage(hwnd, msg, wParam, lParam); - } - } - } - `; - await quickcommand.runCsharp(script); -} - -/** - * 发送自定义消息 - */ -async function sendCustom(method, value, params) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - - public class Program { - [DllImport("user32.dll")] - static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - [DllImport("user32.dll")] - static extern IntPtr GetForegroundWindow(); - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - uint msg = ${params.message}; - IntPtr wParam = (IntPtr)${params.wParam}; - IntPtr lParam = (IntPtr)${params.lParam}; - - PostMessage(hwnd, msg, wParam, lParam); - } - } - } - `; - await quickcommand.runCsharp(script); -} - -module.exports = { - sendMessage, - sendMouseClick, - sendKeyPress, - sendText, - sendCommand, - sendCustom, -}; diff --git a/plugin/lib/quickcomposer/windows/monitor.js b/plugin/lib/quickcomposer/windows/monitor.js index caa72a7..9718904 100644 --- a/plugin/lib/quickcomposer/windows/monitor.js +++ b/plugin/lib/quickcomposer/windows/monitor.js @@ -1,16 +1,9 @@ -const fs = require("fs"); -const path = require("path"); - -// 读取 monitor.cs 模板 -const monitorTemplate = fs.readFileSync( - path.join(__dirname, "..", "..", "csharp", "monitor.cs"), - "utf8" -); +const { runCsharpFeature } = require("../../csharp"); // 监控剪贴板变化 const watchClipboard = async function () { const args = ["-type", "clipboard", "-once"]; - const result = await quickcommand.runCsharp(monitorTemplate, args); + const result = await runCsharpFeature("monitor", args); if (result && result.startsWith("Error:")) { throw new Error(result.substring(7)); } @@ -35,7 +28,7 @@ const watchFileSystem = async function (watchPath, options = {}) { args.push("-recursive", "false"); } - const result = await quickcommand.runCsharp(monitorTemplate, args); + const result = await runCsharpFeature("monitor", args); if (result && result.startsWith("Error:")) { throw new Error(result.substring(7)); } diff --git a/plugin/lib/quickcomposer/windows/automation.js b/plugin/lib/quickcomposer/windows/sendmessage.js similarity index 68% rename from plugin/lib/quickcomposer/windows/automation.js rename to plugin/lib/quickcomposer/windows/sendmessage.js index 5f92fdf..f9d2793 100644 --- a/plugin/lib/quickcomposer/windows/automation.js +++ b/plugin/lib/quickcomposer/windows/sendmessage.js @@ -1,16 +1,8 @@ -const fs = require("fs"); -const path = require("path"); -const quickcommand = require("../../quickcommand"); - -// 读取 automation.cs 模板 -const automationTemplate = fs.readFileSync( - path.join(__dirname, "..", "..", "csharp", "automation.cs"), - "utf8" -); +const { runCsharpFeature } = require("../../csharp"); /** * 键盘操作 - * @param {string} windowType 窗口类型:title/handle/active + * @param {string} method 窗口类型:title/handle/active * @param {string} window 窗口标题/句柄 * @param {string} keys 键盘按键 * @param {object} options 选项 @@ -18,15 +10,15 @@ const automationTemplate = fs.readFileSync( * @param {boolean} options.background 是否后台操作 * @returns {boolean} 是否成功 */ -const sendKeys = async function (windowType, window, keys, options = {}) { +const sendKeys = async function (method, window, keys, options = {}) { const { control, background = false } = options; const args = ["-type", "keyboard", "-action", "keys", "-value", keys]; - - if (windowType !== "active" && window) args.push("-window", window); + args.push("-method", method); + if (method !== "active" && window) args.push("-window", window); if (control) args.push("-control", control); args.push("-background", background.toString()); - const result = await quickcommand.runCsharp(automationTemplate, args); + const result = await runCsharpFeature("sendmessage", args); if (result && result.startsWith("Error:")) { throw new Error(result.substring(7)); } @@ -35,7 +27,7 @@ const sendKeys = async function (windowType, window, keys, options = {}) { /** * 发送文本 - * @param {string} windowType 窗口类型:title/handle/active + * @param {string} method 窗口类型:title/handle/active * @param {string} window 窗口标题/句柄 * @param {string} text 文本 * @param {object} options 选项 @@ -43,15 +35,16 @@ const sendKeys = async function (windowType, window, keys, options = {}) { * @param {boolean} options.background 是否后台操作 * @returns {boolean} 是否成功 */ -const sendText = async function (windowType, window, text, options = {}) { +const sendText = async function (method, window, text, options = {}) { const { control, background = false } = options; const args = ["-type", "keyboard", "-action", "text", "-value", text]; - if (windowType !== "active" && window) args.push("-window", window); + args.push("-method", method); + if (method !== "active" && window) args.push("-window", window); if (control) args.push("-control", control); args.push("-background", background.toString()); - const result = await quickcommand.runCsharp(automationTemplate, args); + const result = await runCsharpFeature("sendmessage", args); if (result && result.startsWith("Error:")) { throw new Error(result.substring(7)); } @@ -60,7 +53,7 @@ const sendText = async function (windowType, window, text, options = {}) { /** * 鼠标点击 - * @param {string} windowType 窗口类型:title/handle/active + * @param {string} method 窗口类型:title/handle/active * @param {string} window 窗口标题/句柄 * @param {string} action 动作:click/doubleClick/rightClick * @param {object} options 选项 @@ -71,7 +64,7 @@ const sendText = async function (windowType, window, text, options = {}) { * @returns {boolean} 是否成功 */ const click = async function ( - windowType, + method, window, action = "click", options = {} @@ -79,13 +72,14 @@ const click = async function ( const { control, text, pos, background = false } = options; const args = ["-type", "mouse", "-action", action]; - if (windowType !== "active" && window) args.push("-window", window); + args.push("-method", method); + if (method !== "active" && window) args.push("-window", window); if (control) args.push("-control", control); if (text) args.push("-text", text); if (pos) args.push("-pos", pos); args.push("-background", background.toString()); - const result = await quickcommand.runCsharp(automationTemplate, args); + const result = await runCsharpFeature("sendmessage", args); if (result && result.startsWith("Error:")) { throw new Error(result.substring(7)); } @@ -94,22 +88,23 @@ const click = async function ( /** * 获取窗口控件树 - * @param {string} windowType 窗口类型:title/handle/active + * @param {string} method 窗口类型:title/handle/active * @param {string} window 窗口标题/句柄 * @param {object} options 选项 * @param {string} options.filter 过滤条件 * @param {boolean} options.background 是否后台操作 * @returns {object} 控件树 */ -const inspectWindow = async function (windowType, window, options = {}) { +const inspectWindow = async function (method, window, options = {}) { const { filter, background = false } = options; const args = ["-type", "inspect"]; - if (windowType !== "active" && window) args.push("-window", window); + args.push("-method", method); + if (method !== "active" && window) args.push("-window", window); if (filter) args.push("-filter", filter); args.push("-background", background.toString()); - const result = await quickcommand.runCsharp(automationTemplate, args); + const result = await runCsharpFeature("sendmessage", args); if (result && result.startsWith("Error:")) { throw new Error(result.substring(7)); } diff --git a/plugin/lib/quickcomposer/windows/window.js b/plugin/lib/quickcomposer/windows/window.js index 8f25ba0..9c62a45 100644 --- a/plugin/lib/quickcomposer/windows/window.js +++ b/plugin/lib/quickcomposer/windows/window.js @@ -1,3 +1,5 @@ +const { runCsharpFeature } = require("../../csharp"); + /** * 窗口置顶 * @param {string} method 查找方式:title/handle/active @@ -5,40 +7,17 @@ * @param {boolean} isTopMost 是否置顶 */ async function setTopMost(method, value, isTopMost) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - using System.Diagnostics; - using System.Management; - - public class Program { - [DllImport("user32.dll")] - static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - [DllImport("user32.dll")] - static extern IntPtr GetForegroundWindow(); - - static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); - static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); - const uint SWP_NOMOVE = 0x0002; - const uint SWP_NOSIZE = 0x0001; - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - SetWindowPos(hwnd, ${ - isTopMost ? "HWND_TOPMOST" : "HWND_NOTOPMOST" - }, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - } - } - } - `; - - await quickcommand.runCsharp(script); + const args = [ + "-type", + "topmost", + "-method", + method, + "-window", + value, + "-value", + isTopMost.toString(), + ]; + await runCsharpFeature("window", args); } /** @@ -48,38 +27,17 @@ async function setTopMost(method, value, isTopMost) { * @param {number} opacity 透明度 0-100 */ async function setOpacity(method, value, opacity) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - using System.Diagnostics; - using System.Management; - - public class Program { - [DllImport("user32.dll")] - static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags); - - [DllImport("user32.dll")] - static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - const int GWL_EXSTYLE = -20; - const int WS_EX_LAYERED = 0x80000; - const uint LWA_ALPHA = 0x2; - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED); - SetLayeredWindowAttributes(hwnd, 0, (byte)(${opacity} * 2.55), LWA_ALPHA); - } - } - } - `; - - await quickcommand.runCsharp(script); + const args = [ + "-type", + "opacity", + "-method", + method, + "-window", + value, + "-value", + opacity.toString(), + ]; + await runCsharpFeature("window", args); } /** @@ -92,30 +50,17 @@ async function setOpacity(method, value, opacity) { * @param {number} height 高度 */ async function setWindowRect(method, value, x, y, width, height) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - using System.Diagnostics; - using System.Management; - - public class Program { - [DllImport("user32.dll")] - static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - MoveWindow(hwnd, ${x}, ${y}, ${width}, ${height}, true); - } - } - } - `; - - await quickcommand.runCsharp(script); + const args = [ + "-type", + "rect", + "-method", + method, + "-window", + value, + "-value", + `${x},${y},${width},${height}`, + ]; + await runCsharpFeature("window", args); } /** @@ -125,40 +70,17 @@ async function setWindowRect(method, value, x, y, width, height) { * @param {string} state 状态:normal/maximize/minimize */ async function setWindowState(method, value, state) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - using System.Diagnostics; - using System.Management; - - public class Program { - [DllImport("user32.dll")] - static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - const int SW_NORMAL = 1; - const int SW_MAXIMIZE = 3; - const int SW_MINIMIZE = 6; - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - ShowWindow(hwnd, ${ - state === "maximize" - ? "SW_MAXIMIZE" - : state === "minimize" - ? "SW_MINIMIZE" - : "SW_NORMAL" - }); - } - } - } - `; - - await quickcommand.runCsharp(script); + const args = [ + "-type", + "state", + "-method", + method, + "-window", + value, + "-value", + state, + ]; + await runCsharpFeature("window", args); } /** @@ -167,32 +89,8 @@ async function setWindowState(method, value, state) { * @param {string} value 查找值(handle时为数字) */ async function closeWindow(method, value) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - using System.Diagnostics; - using System.Management; - - public class Program { - [DllImport("user32.dll")] - static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - const uint WM_CLOSE = 0x0010; - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - PostMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); - } - } - } - `; - - await quickcommand.runCsharp(script); + const args = ["-type", "close", "-method", method, "-window", value]; + await runCsharpFeature("window", args); } /** @@ -201,30 +99,8 @@ async function closeWindow(method, value) { * @param {string} value 查找值(handle时为数字) */ async function setFocus(method, value) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - using System.Diagnostics; - using System.Management; - - public class Program { - [DllImport("user32.dll")] - static extern bool SetForegroundWindow(IntPtr hWnd); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - SetForegroundWindow(hwnd); - } - } - } - `; - - await quickcommand.runCsharp(script); + const args = ["-type", "focus", "-method", method, "-window", value]; + await runCsharpFeature("window", args); } /** @@ -234,44 +110,17 @@ async function setFocus(method, value) { * @param {boolean} hasBorder 是否显示边框 */ async function setBorder(method, value, hasBorder) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - using System.Diagnostics; - using System.Management; - - public class Program { - [DllImport("user32.dll")] - static extern int GetWindowLong(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll")] - static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - const int GWL_STYLE = -16; - const int WS_BORDER = 0x00800000; - const int WS_DLGFRAME = 0x00400000; - const int WS_CAPTION = WS_BORDER | WS_DLGFRAME; - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - int style = GetWindowLong(hwnd, GWL_STYLE); - if (${hasBorder}) { - style |= WS_CAPTION; - } else { - style &= ~WS_CAPTION; - } - SetWindowLong(hwnd, GWL_STYLE, style); - } - } - } - `; - - await quickcommand.runCsharp(script); + const args = [ + "-type", + "border", + "-method", + method, + "-window", + value, + "-value", + hasBorder.toString(), + ]; + await runCsharpFeature("window", args); } /** @@ -281,44 +130,17 @@ async function setBorder(method, value, hasBorder) { * @param {boolean} isTransparent 是否点击穿透 */ async function setClickThrough(method, value, isTransparent) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - using System.Diagnostics; - using System.Management; - - public class Program { - [DllImport("user32.dll")] - static extern int GetWindowLong(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll")] - static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - const int GWL_EXSTYLE = -20; - const int WS_EX_TRANSPARENT = 0x00000020; - const int WS_EX_LAYERED = 0x80000; - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); - exStyle |= WS_EX_LAYERED; - if (${isTransparent}) { - exStyle |= WS_EX_TRANSPARENT; - } else { - exStyle &= ~WS_EX_TRANSPARENT; - } - SetWindowLong(hwnd, GWL_EXSTYLE, exStyle); - } - } - } - `; - - await quickcommand.runCsharp(script); + const args = [ + "-type", + "clickthrough", + "-method", + method, + "-window", + value, + "-value", + isTransparent.toString(), + ]; + await runCsharpFeature("window", args); } /** @@ -328,167 +150,8 @@ async function setClickThrough(method, value, isTransparent) { * @returns {Object} 窗口信息 */ async function getWindowInfo(method, value) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - using System.Diagnostics; - using System.Web.Script.Serialization; - - public class Program { - [DllImport("user32.dll")] - static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); - - [DllImport("user32.dll")] - static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - [DllImport("user32.dll")] - static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); - - [DllImport("user32.dll")] - static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); - - [DllImport("user32.dll")] - static extern bool IsWindowVisible(IntPtr hWnd); - - [DllImport("user32.dll")] - static extern bool IsIconic(IntPtr hWnd); - - [DllImport("user32.dll")] - static extern bool IsZoomed(IntPtr hWnd); - - [DllImport("user32.dll")] - static extern IntPtr GetForegroundWindow(); - - [DllImport("user32.dll")] - static extern int GetWindowLong(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll")] - static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); - - [StructLayout(LayoutKind.Sequential)] - public struct RECT { - public int Left; - public int Top; - public int Right; - public int Bottom; - } - - const int GWL_STYLE = -16; - const int GWL_EXSTYLE = -20; - const int WS_BORDER = 0x00800000; - const int WS_CAPTION = 0x00C00000; - const int WS_CHILD = 0x40000000; - const int WS_POPUP = unchecked((int)0x80000000); - const int WS_SYSMENU = 0x00080000; - const int WS_MINIMIZEBOX = 0x00020000; - const int WS_MAXIMIZEBOX = 0x00010000; - const int WS_EX_TOPMOST = 0x00000008; - const int WS_EX_TRANSPARENT = 0x00000020; - const int WS_EX_TOOLWINDOW = 0x00000080; - const int WS_EX_LAYERED = 0x00080000; - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - var windowRect = new RECT(); - GetWindowRect(hwnd, out windowRect); - - var clientRect = new RECT(); - GetClientRect(hwnd, out clientRect); - - var titleText = new StringBuilder(256); - GetWindowText(hwnd, titleText, 256); - - var className = new StringBuilder(256); - GetClassName(hwnd, className, 256); - - uint processId = 0; - GetWindowThreadProcessId(hwnd, out processId); - - string processName = ""; - string processPath = ""; - try { - Process process = Process.GetProcessById((int)processId); - processName = process.ProcessName; - - var startInfo = new ProcessStartInfo { - FileName = "wmic", - Arguments = string.Format("process where ProcessId={0} get ExecutablePath /value", processId), - UseShellExecute = false, - RedirectStandardOutput = true, - CreateNoWindow = true - }; - using (var proc = Process.Start(startInfo)) { - string output = proc.StandardOutput.ReadToEnd(); - if (!string.IsNullOrEmpty(output)) { - string[] lines = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); - foreach (string line in lines) { - if (line.StartsWith("ExecutablePath=")) { - processPath = line.Substring("ExecutablePath=".Length); - break; - } - } - } - } - } catch {} - - int style = GetWindowLong(hwnd, GWL_STYLE); - int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); - - var data = new { - handle = hwnd.ToInt64(), - processId = processId, - process = new { - name = processName, - path = processPath - }, - title = titleText.ToString(), - className = className.ToString(), - window = new { - x = windowRect.Left, - y = windowRect.Top, - width = windowRect.Right - windowRect.Left, - height = windowRect.Bottom - windowRect.Top - }, - client = new { - width = clientRect.Right - clientRect.Left, - height = clientRect.Bottom - clientRect.Top - }, - state = new { - visible = IsWindowVisible(hwnd), - minimized = IsIconic(hwnd), - maximized = IsZoomed(hwnd), - focused = GetForegroundWindow() == hwnd - }, - style = new { - border = (style & WS_BORDER) != 0, - caption = (style & WS_CAPTION) != 0, - child = (style & WS_CHILD) != 0, - popup = (style & WS_POPUP) != 0, - sysmenu = (style & WS_SYSMENU) != 0, - minimizeBox = (style & WS_MINIMIZEBOX) != 0, - maximizeBox = (style & WS_MAXIMIZEBOX) != 0 - }, - exStyle = new { - topmost = (exStyle & WS_EX_TOPMOST) != 0, - transparent = (exStyle & WS_EX_TRANSPARENT) != 0, - toolWindow = (exStyle & WS_EX_TOOLWINDOW) != 0, - layered = (exStyle & WS_EX_LAYERED) != 0 - } - }; - - var serializer = new JavaScriptSerializer(); - Console.WriteLine(serializer.Serialize(data)); - } - } - } - `; - - const result = await quickcommand.runCsharp(script); + const args = ["-type", "info", "-method", method, "-window", value]; + const result = await runCsharpFeature("window", args); try { return JSON.parse(result); } catch (error) { @@ -503,50 +166,17 @@ async function getWindowInfo(method, value) { * @param {boolean} visible 是否可见 */ async function setVisible(method, value, visible) { - const script = ` - using System; - using System.Runtime.InteropServices; - using System.Text; - using System.Diagnostics; - using System.Management; - - public class Program { - [DllImport("user32.dll")] - static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); - - [DllImport("user32.dll")] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - const int SW_HIDE = 0; - const int SW_SHOW = 5; - - public static void Main() { - ${findWindowByMethod(method, value)} - if (hwnd != IntPtr.Zero) { - ShowWindow(hwnd, ${visible ? "SW_SHOW" : "SW_HIDE"}); - } - } - } - `; - - await quickcommand.runCsharp(script); -} - -/** - * 根据不同方式查找窗口 - * @param {string} method 查找方式:title/handle/active - * @param {string} value 查找值(handle时为数字) - * @returns {string} C#代码片段 - */ -function findWindowByMethod(method, value) { - switch (method) { - case "handle": - return `IntPtr hwnd = new IntPtr(${value});`; - case "active": - return `IntPtr hwnd = GetForegroundWindow();`; - default: // title - return `IntPtr hwnd = FindWindow(null, "${value}");`; - } + const args = [ + "-type", + "visible", + "-method", + method, + "-window", + value, + "-value", + visible.toString(), + ]; + await runCsharpFeature("window", args); } module.exports = { diff --git a/plugin/lib/systemDialog.js b/plugin/lib/systemDialog.js index 6c36ffc..d4a60f7 100644 --- a/plugin/lib/systemDialog.js +++ b/plugin/lib/systemDialog.js @@ -2,12 +2,7 @@ const fs = require("fs"); const path = require("path"); const { exec } = require("child_process"); const { getQuickcommandFolderFile } = require("./getQuickcommandFile"); - -// 读取 dialog.cs 模板 -const dialogTemplate = fs.readFileSync( - path.join(__dirname, "csharp", "dialog.cs"), - "utf8" -); +const { runCsharpFeature } = require("./csharp"); // 辅助函数 const execCommand = (cmd) => { @@ -70,8 +65,7 @@ const showSystemMessageBox = async function (content, title = "") { args.push("-iconpath", iconPath.replace(/\\/g, "\\\\")); } - const csharpCode = dialogTemplate; - const result = await this.runCsharp(csharpCode, args); + const result = await runCsharpFeature("dialog", args); if (result && result.startsWith("Error:")) { throw new Error(result.substring(7)); } @@ -149,8 +143,7 @@ const showSystemInputBox = async function (placeholders, title = "") { args.push("-iconpath", iconPath.replace(/\\/g, "\\\\")); } - const csharpCode = dialogTemplate; - const result = await this.runCsharp(csharpCode, args); + const result = await runCsharpFeature("dialog", args); return result ? JSON.parse(result) : []; } else if (window.utools.isLinux()) { if (!(await checkZenity())) return null; @@ -200,8 +193,7 @@ const showSystemConfirmBox = async function (content, title = "") { args.push("-iconpath", iconPath.replace(/\\/g, "\\\\")); } - const csharpCode = dialogTemplate; - const result = await this.runCsharp(csharpCode, args); + const result = await runCsharpFeature("dialog", args); return result === "true"; } else if (window.utools.isLinux()) { if (!(await checkZenity())) return false; @@ -244,8 +236,7 @@ const showSystemButtonBox = async function (buttons, title = "") { args.push("-iconpath", iconPath.replace(/\\/g, "\\\\")); } - const csharpCode = dialogTemplate; - const result = await this.runCsharp(csharpCode, args); + const result = await runCsharpFeature("dialog", args); if (result) { return JSON.parse(result); } @@ -288,8 +279,7 @@ const showSystemTextArea = async function (defaultText = "", title = "") { args.push("-iconpath", iconPath.replace(/\\/g, "\\\\")); } - const csharpCode = dialogTemplate; - const result = await this.runCsharp(csharpCode, args); + const result = await runCsharpFeature("dialog", args); return result || null; } else if (window.utools.isLinux()) { if (!(await checkZenity())) return null; diff --git a/src/js/composer/commands/uiCommands.js b/src/js/composer/commands/uiCommands.js index da6887b..ec4d9aa 100644 --- a/src/js/composer/commands/uiCommands.js +++ b/src/js/composer/commands/uiCommands.js @@ -108,6 +108,115 @@ export const uiCommands = { icon: "web", defaultOpened: false, commands: [ + { + value: "quickcommand.showMessageBox", + label: "消息提示", + desc: "显示一个自动消失的提示框", + isAsync: true, + config: [ + { + label: "提示内容", + component: "VariableInput", + icon: "info", + defaultValue: newVarInputVal("str", "这是一条提示消息"), + width: 12, + }, + ], + subCommands: [ + { + value: "quickcommand.showMessageBox", + icon: "call_to_action", + label: "插件内弹窗", + config: [ + { + label: "图标类型", + component: "q-select", + defaultValue: "success", + icon: "lightbulb", + width: 6, + options: [ + { label: "成功", value: "success" }, + { label: "错误", value: "error" }, + { label: "警告", value: "warning" }, + { label: "信息", value: "info" }, + ], + }, + { + label: "显示时间(ms)", + component: "NumberInput", + min: 0, + step: 100, + width: 6, + placeholder: "0为手动关闭,留空按文本长度调整", + }, + ], + }, + { + value: "quickcommand.showSystemMessageBox", + icon: "report", + label: "系统弹窗", + config: [ + { + label: "标题", + component: "VariableInput", + defaultValue: newVarInputVal("str", "提示"), + width: 12, + }, + ], + }, + ], + }, + { + value: "quickcommand.showConfirmBox", + label: "确认框", + desc: "显示一个确认框,返回是否点击了确认", + isAsync: true, + outputVariable: "confirmed", + saveOutput: true, + config: [ + { + label: "提示内容", + component: "VariableInput", + defaultValue: newVarInputVal("str", "确认要执行此操作吗?"), + width: 12, + }, + { + label: "标题", + component: "VariableInput", + defaultValue: newVarInputVal("str", "提示"), + width: 12, + }, + ], + subCommands: [ + { + value: "quickcommand.showConfirmBox", + icon: "call_to_action", + label: "插件内弹窗", + config: [ + { + label: "支持HTML", + component: "CheckButton", + defaultValue: false, + width: 6, + }, + { + label: "宽度", + component: "NumberInput", + min: 0, + step: 100, + defaultValue: 450, + width: 6, + placeholder: "对话框宽度", + }, + ], + }, + { + value: "quickcommand.showSystemConfirmBox", + icon: "report", + label: "系统弹窗", + }, + ], + }, { value: "quickcommand.showButtonBox", label: "按钮组", @@ -253,115 +362,6 @@ export const uiCommands = { }, ], }, - { - value: "quickcommand.showMessageBox", - label: "消息提示", - desc: "显示一个自动消失的提示框", - isAsync: true, - config: [ - { - label: "提示内容", - component: "VariableInput", - icon: "info", - defaultValue: newVarInputVal("str", "这是一条提示消息"), - width: 12, - }, - ], - subCommands: [ - { - value: "quickcommand.showMessageBox", - icon: "call_to_action", - label: "插件内弹窗", - config: [ - { - label: "图标类型", - component: "q-select", - defaultValue: "success", - icon: "lightbulb", - width: 6, - options: [ - { label: "成功", value: "success" }, - { label: "错误", value: "error" }, - { label: "警告", value: "warning" }, - { label: "信息", value: "info" }, - ], - }, - { - label: "显示时间(ms)", - component: "NumberInput", - min: 0, - step: 100, - width: 6, - placeholder: "0为手动关闭,留空按文本长度调整", - }, - ], - }, - { - value: "quickcommand.showSystemMessageBox", - icon: "report", - label: "系统弹窗", - config: [ - { - label: "标题", - component: "VariableInput", - defaultValue: newVarInputVal("str", "提示"), - width: 12, - }, - ], - }, - ], - }, - { - value: "quickcommand.showConfirmBox", - label: "确认框", - desc: "显示一个确认框,返回是否点击了确认", - isAsync: true, - outputVariable: "confirmed", - saveOutput: true, - config: [ - { - label: "提示内容", - component: "VariableInput", - defaultValue: newVarInputVal("str", "确认要执行此操作吗?"), - width: 12, - }, - { - label: "标题", - component: "VariableInput", - defaultValue: newVarInputVal("str", "提示"), - width: 12, - }, - ], - subCommands: [ - { - value: "quickcommand.showConfirmBox", - icon: "call_to_action", - label: "插件内弹窗", - config: [ - { - label: "支持HTML", - component: "CheckButton", - defaultValue: false, - width: 6, - }, - { - label: "宽度", - component: "NumberInput", - min: 0, - step: 100, - defaultValue: 450, - width: 6, - placeholder: "对话框宽度", - }, - ], - }, - { - value: "quickcommand.showSystemConfirmBox", - icon: "report", - label: "系统弹窗", - }, - ], - }, { value: "utools.showOpenDialog", label: "文件选择框", diff --git a/src/js/composer/commands/windowsCommands.js b/src/js/composer/commands/windowsCommands.js index 48924f3..1d288ce 100644 --- a/src/js/composer/commands/windowsCommands.js +++ b/src/js/composer/commands/windowsCommands.js @@ -51,7 +51,7 @@ export const windowsCommands = { defaultOpened: false, commands: [ { - value: "quickcomposer.windows.window.setTopMost", + value: "quickcomposer.windows.window.getWindowInfo", label: "窗口控制", desc: "Windows窗口操作", icon: "window", @@ -79,6 +79,13 @@ export const windowsCommands = { }, ], subCommands: [ + { + value: "quickcomposer.windows.window.getWindowInfo", + label: "窗口信息", + icon: "info", + outputVariable: "windowInfo", + saveOutput: true, + }, { value: "quickcomposer.windows.window.setTopMost", label: "窗口置顶", @@ -238,19 +245,12 @@ export const windowsCommands = { }, ], }, - { - value: "quickcomposer.windows.window.getWindowInfo", - label: "窗口信息", - icon: "info", - outputVariable: "windowInfo", - saveOutput: true, - }, ], isAsync: true, }, { - value: "quickcomposer.windows.automation.inspectWindow", - label: "界面自动化", + value: "quickcomposer.windows.sendmessage.inspectWindow", + label: "界面自动化(sendmessage)", desc: "Windows界面自动化操作", icon: "smart_button", isAsync: true, @@ -279,7 +279,7 @@ export const windowsCommands = { ], subCommands: [ { - value: "quickcomposer.windows.automation.inspectWindow", + value: "quickcomposer.windows.sendmessage.inspectWindow", label: "获取控件树", icon: "account_tree", outputVariable: "controlsTree", @@ -314,7 +314,7 @@ export const windowsCommands = { ], }, { - value: "quickcomposer.windows.automation.click", + value: "quickcomposer.windows.sendmessage.click", label: "点击控件", icon: "mouse", config: [ @@ -372,7 +372,7 @@ export const windowsCommands = { ], }, { - value: "quickcomposer.windows.automation.sendText", + value: "quickcomposer.windows.sendmessage.sendText", label: "发送文本", icon: "keyboard", config: [ @@ -413,7 +413,7 @@ export const windowsCommands = { ], }, { - value: "quickcomposer.windows.automation.sendKeys", + value: "quickcomposer.windows.sendmessage.sendKeys", label: "发送按键", icon: "keyboard_alt", config: [