diff --git a/plugin/lib/csharp/explorer.cs b/plugin/lib/csharp/explorer.cs new file mode 100644 index 0000000..8e868f1 --- /dev/null +++ b/plugin/lib/csharp/explorer.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Web.Script.Serialization; + +public class ExplorerManager +{ + public static void Main(string[] args) + { + if (args.Length == 0 || args[0] == "-h" || args[0] == "--help") + { + ShowHelp(); + return; + } + + try + { + string type = GetArgumentValue(args, "-type"); + if (string.IsNullOrEmpty(type)) + { + throw new Exception("必须指定操作类型 (-type)"); + } + + switch (type.ToLower()) + { + case "list": + ListExplorerWindows(); + break; + + case "navigate": + string handle = GetArgumentValue(args, "-handle"); + string path = GetArgumentValue(args, "-path"); + if (string.IsNullOrEmpty(handle) || string.IsNullOrEmpty(path)) + { + throw new Exception("必须指定窗口句柄和目标路径"); + } + NavigateToPath(long.Parse(handle), path); + break; + + default: + throw new Exception(string.Format("不支持的操作类型: {0}", type)); + } + } + catch (Exception ex) + { + Console.Error.WriteLine(string.Format("Error: {0}", ex.Message)); + } + } + + private static void ListExplorerWindows() + { + var explorerWindows = new List>(); + + try + { + dynamic shellApp = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application")); + dynamic windows = shellApp.Windows(); + + foreach (dynamic window in windows) + { + try + { + string locationUrl = window.LocationURL; + if (string.IsNullOrEmpty(locationUrl)) continue; + + string path = new Uri(locationUrl).LocalPath; + explorerWindows.Add(new Dictionary + { + { "handle", window.HWND }, + { "title", window.LocationName }, + { "path", path }, + { "class", "CabinetWClass" } + }); + } + catch + { + // 忽略获取信息失败的窗口 + } + } + } + catch (Exception ex) + { + Console.Error.WriteLine(string.Format("Error: {0}", ex.Message)); + return; + } + + var serializer = new JavaScriptSerializer(); + Console.WriteLine(serializer.Serialize(explorerWindows)); + } + + private static void NavigateToPath(long handle, string path) + { + try + { + dynamic shellApp = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application")); + dynamic windows = shellApp.Windows(); + + foreach (dynamic window in windows) + { + try + { + if (window.HWND == handle) + { + window.Navigate(path); + Console.WriteLine("true"); + return; + } + } + catch + { + // 忽略单个窗口的错误 + } + } + throw new Exception("未找到指定的窗口"); + } + catch (Exception ex) + { + throw new Exception(string.Format("导航失败: {0}", ex.Message)); + } + } + + 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() + { + Console.WriteLine(@" +Windows 资源管理器工具使用说明 +========================== + +基本语法: +explorer.exe -type <操作类型> [参数...] + +操作类型: +-------- +1. list - 列出所有打开的资源管理器窗口 +2. navigate - 导航到指定路径 + 参数: + -handle 窗口句柄 + -path 目标路径 + +返回值: +------ +list: JSON格式的窗口信息数组 +navigate: true表示成功 + +使用示例: +-------- +1. 列出所有资源管理器窗口: + explorer.exe -type list +2. 导航到指定路径: + explorer.exe -type navigate -handle 12345 -path ""C:\Windows"" +"); + } +} diff --git a/plugin/lib/quickcomposer/windows/explorer.js b/plugin/lib/quickcomposer/windows/explorer.js new file mode 100644 index 0000000..9b2847a --- /dev/null +++ b/plugin/lib/quickcomposer/windows/explorer.js @@ -0,0 +1,49 @@ +const { runCsharpFeature } = require("../../csharp"); + +/** + * 执行资源管理器操作 + * @param {string} type - 操作类型, 可选值: "list"|"navigate" + * @param {Object} params - 参数对象 + * @returns {Promise} - 操作结果 + */ +async function runExplorer(type, params = {}) { + const args = ["-type", type]; + + // 添加导航相关参数 + if (type === "navigate") { + if (!params.handle || !params.path) { + throw new Error("导航操作需要指定窗口句柄和目标路径"); + } + args.push("-handle", params.handle.toString()); + args.push("-path", params.path); + } + + try { + const result = await runCsharpFeature("explorer", args); + if (result) { + if (result.trim() === "true") return true; + return JSON.parse(result); + } + } catch (err) { + console.error(err); + return type === "list" ? [] : false; + } + + return type === "list" ? [] : false; +} + +module.exports = { + /** + * 获取所有打开的资源管理器窗口信息 + * @returns {Promise} 资源管理器窗口信息数组 + */ + list: () => runExplorer("list"), + + /** + * 导航到指定路径 + * @param {number} handle - 窗口句柄 + * @param {string} path - 目标路径 + * @returns {Promise} 是否成功 + */ + navigate: (handle, path) => runExplorer("navigate", { handle, path }), +}; diff --git a/plugin/lib/quickcomposer/windows/index.js b/plugin/lib/quickcomposer/windows/index.js index 2efecb4..3e4e831 100644 --- a/plugin/lib/quickcomposer/windows/index.js +++ b/plugin/lib/quickcomposer/windows/index.js @@ -8,6 +8,7 @@ const software = require("./software"); const utils = require("./utils"); const automation = require("./automation"); const browser = require("./browser"); +const explorer = require("./explorer"); module.exports = { window, @@ -20,4 +21,5 @@ module.exports = { utils, automation, browser, + explorer, }; diff --git a/src/js/composer/commands/windowsCommands.js b/src/js/composer/commands/windowsCommands.js index 88ed67f..3aea94b 100644 --- a/src/js/composer/commands/windowsCommands.js +++ b/src/js/composer/commands/windowsCommands.js @@ -472,6 +472,70 @@ export const windowsCommands = { ], asyncMode: "await", }, + // 资源管理器 + { + value: "quickcomposer.windows.explorer.list", + label: "资源管理器操作", + icon: "folder", + asyncMode: "await", + subCommands: [ + { + value: "quickcomposer.windows.explorer.list", + label: "获取所有已打开路径", + icon: "folder", + outputs: { + label: "已打开路径列表", + suggestName: "explorerList", + structure: [ + { + handle: { label: "窗口句柄", suggestName: "windowHandle" }, + title: { label: "窗口标题", suggestName: "windowTitle" }, + path: { label: "当前路径", suggestName: "windowPath" }, + class: { label: "窗口类名", suggestName: "windowClass" }, + }, + ], + }, + }, + { + value: "quickcomposer.windows.explorer.navigate", + label: "导航到指定路径", + icon: "folder", + config: [ + { + component: "VariableInput", + label: "窗口句柄", + icon: "window", + width: 12, + placeholder: "输入要导航的窗口句柄", + defaultValue: newVarInputVal("var"), + disableToggleType: true, + width: 4, + }, + { + component: "VariableInput", + label: "路径", + icon: "folder", + options: { + dialog: { + type: "open", + options: { + title: "选择路径", + properties: ["openDirectory"], + }, + }, + }, + width: 8, + placeholder: "输入要导航的路径", + }, + ], + outputs: { + label: "是否成功", + suggestName: "isSuccess", + typeName: "布尔值", + }, + }, + ], + }, // automation { value: "quickcomposer.windows.automation.click", diff --git a/src/plugins/monaco/types/quickcomposer.d.ts b/src/plugins/monaco/types/quickcomposer.d.ts index 3002208..906f323 100644 --- a/src/plugins/monaco/types/quickcomposer.d.ts +++ b/src/plugins/monaco/types/quickcomposer.d.ts @@ -1721,6 +1721,32 @@ interface quickcomposerApi { ): Promise<{ success: boolean; error?: string }>; }; + /** + * 资源管理器操作功能 + */ + explorer: { + /** + * 获取所有打开的资源管理器窗口信息 + * @returns 资源管理器窗口信息数组 + */ + list(): Promise< + { + handle: number; // 窗口句柄 + title: string; // 窗口标题 + path: string; // 当前路径 + class: string; // 窗口类名 + }[] + >; + + /** + * 导航到指定路径 + * @param handle 窗口句柄 + * @param path 目标路径 + * @returns 是否成功 + */ + navigate(handle: number, path: string): Promise; + }; + /** * 进程管理功能 */