Skip to content

Feature/explorer address#10

Merged
lzx8589561 merged 5 commits into
ZToolsCenter:mainfrom
Particaly:feature/explorer-address
Jun 7, 2026
Merged

Feature/explorer address#10
lzx8589561 merged 5 commits into
ZToolsCenter:mainfrom
Particaly:feature/explorer-address

Conversation

@Particaly

Copy link
Copy Markdown
Contributor

提供文件夹快捷跳转的功能支持

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the WindowManager.setAddressBar and getAllExplorerWindows APIs to allow querying and navigating file explorer windows and file dialogs on both Windows and macOS. The implementation uses native C++ and Swift bindings. The review feedback highlights three key issues: a type-checking bug in index.js that unconditionally throws a TypeError on macOS when passing a window object, a COM initialization issue on Windows where RPC_E_CHANGED_MODE is incorrectly treated as a failure, and a responsiveness issue where calling Sleep on the Node.js main thread blocks the event loop during key simulation.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread index.js
Comment on lines +330 to +332
if (typeof identifier !== 'string' && typeof identifier !== 'number') {
throw new TypeError('On macOS, target must be a bundleId, pid, or window object with bundleId/pid');
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

在 macOS 平台上,如果传入的 target 是一个窗口对象(例如 WindowManager.getActiveWindow() 返回的对象),在第 317 行代码中 identifier 会被赋值为该对象本身(identifier = target)。

然而,在第 330 行的类型检查中:

if (typeof identifier !== 'string' && typeof identifier !== 'number') {
  throw new TypeError('On macOS, target must be a bundleId, pid, or window object with bundleId/pid');
}

由于 identifier 是一个对象,typeof identifier 的值为 'object',这会导致该条件始终为真,从而无条件抛出 TypeError。这使得在 macOS 上无法直接传递窗口对象给 setAddressBar

建议修正类型检查,允许 'object' 类型通过,以便 C++ 层能够正确接收并序列化该对象。

Suggested change
if (typeof identifier !== 'string' && typeof identifier !== 'number') {
throw new TypeError('On macOS, target must be a bundleId, pid, or window object with bundleId/pid');
}
if (typeof identifier !== 'string' && typeof identifier !== 'number' && typeof identifier !== 'object') {
throw new TypeError('On macOS, target must be a bundleId, pid, or window object');
}

Comment thread src/binding_windows.cpp
Comment on lines +4983 to +4985
if (FAILED(hrInit)) {
return env.Null();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

在 Node.js 或 Electron 环境中,主线程可能已经将 COM 库初始化为多线程模式(MTA)。此时调用 CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED) 会返回 RPC_E_CHANGED_MODE(0x80010106)。

虽然 RPC_E_CHANGED_MODE 表示初始化模式冲突,但它也意味着 COM 已经初始化成功并可以使用。如果直接使用 FAILED(hrInit) 拦截并返回 env.Null(),会导致在已初始化 MTA 的环境中该函数无条件失败

建议允许 RPC_E_CHANGED_MODE 继续执行,不将其视为致命错误。此问题同样存在于 GetAllExplorerWindowsNavigateExplorerWindowReadBrowserWindowUrl 中,建议一并修正。

    if (FAILED(hrInit) && hrInit != RPC_E_CHANGED_MODE) {
        return env.Null();
    }

Comment thread src/binding_windows.cpp
Comment on lines +5484 to +5489
Sleep(60);
bool success = SendFocusAddressBarShortcut();
Sleep(80);
success = SendUnicodeText(address) && success;
Sleep(30);
success = SendVirtualKeyTap(VK_RETURN) && success;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

在 Node.js 的主线程中直接调用 Sleep阻塞整个事件循环

这里为了等待窗口焦点和模拟按键,连续调用了多次 Sleep(共计 170ms),这在 Electron 等对 UI 响应要求极高的应用中会导致明显的界面卡顿。

虽然对于 Explorer 窗口(CabinetWClass)使用了非阻塞的 COM 导航,但对于普通文件对话框(#32770)依然会触发此阻塞逻辑。

建议将 SetAddressBar 整个方法改造为异步方法(例如使用 Napi::AsyncWorker),将这些带有延迟的 UI 模拟操作放到后台线程执行,避免阻塞 Node.js 主线程。

@lzx8589561 lzx8589561 merged commit 8cd9283 into ZToolsCenter:main Jun 7, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants