Skip to content

Conversation

@Vanisper
Copy link
Member

@Vanisper Vanisper commented Nov 22, 2025

Description 描述

  • devtools 新增 Windows 平台支持

实现了一个工具函数 - findSoftwareInstallLocation,用于通过可执行程序名称查询软件安装目录:

对 mac 下做了简单但够用的支持,即直接返回可用的 Applications 路径下的 .app 后缀文件夹。

需要注意的是 “*.app” 其实是一个文件夹而不是可执行文件本身,所以 *.app 视为 InstallLocation 应该也是合理的,符合这个函数的语义。

还有就是访达中看到的 app 名称可能是 displayName,真正需要的参数应该是终端中显示的名称。

  1. 通过执行 PowerShell 指令, 查询 Uninstall 注册表(支持 32位 和 64 位),最后输出安装路径;
  2. 如果上述过程没有得到结果,说明此程序可能没有通过正常途径安装,采用兜底方案
    • 查询另外一个注册表 —— 应用兼容性助理 (Compatibility Assistant),它是一个由 Windows 自动维护的 “我最近运行过哪些程序?它们在哪里?” 的历史记录清单。
    • 即使是一个绿色软件,只要运行过,就会在这个注册表中记录。
    • 该方案来源于 hbuilderx-cli

最后真正的执行程序是上面得到的安装路径拼接上 cli.bat 字符。

Linked Issues 关联的 Issues

nothing

Additional context 额外上下文

nothing

Summary by CodeRabbit

  • New Features

    • Added automatic detection of developer tools installations on Windows and macOS to improve setup and CLI path resolution.
    • Added utilities to better locate installed software across platforms, improving reliability of tool discovery.
  • Bug Fixes

    • Updated WeChat developer tools identification on Windows for improved compatibility and detection.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 22, 2025

Walkthrough

This pull request adds cross-platform software discovery utilities (including GBK decoding and Windows uninstall-registry lookup) and integrates them into devtools logic to resolve the CLI path on Windows; also updates the Windows bundle ID for mp-weixin to "微信开发者工具".

Changes

Cohort / File(s) Summary
Windows/macOS Software Discovery Utilities
src/utils/index.ts
Added decodeGbk() to decode GBK-encoded buffers, findSoftwareInstallLocation(executableName, displayName?) to locate installs on Windows (registry/AppCompatFlags) and macOS (Applications folder), and findInUninstallRegistry(appName) which runs a PowerShell query to read uninstall registry entries. Extended imports (execSync, basename, dirname, join, parse). Exports updated to include the new functions.
DevTools Integration
src/logics/devtools.ts
Imported findSoftwareInstallLocation and used it to resolve the Windows CLI path (sets cliPath to discovered dir + cli.bat when found). Updated mp-weixin Windows bundle ID from webplusdevtools.exe to 微信开发者工具. Mac resolution unchanged.

Sequence Diagram(s)

sequenceDiagram
    participant DevTools as DevTools Logic
    participant Finder as findSoftwareInstallLocation
    participant Registry as findInUninstallRegistry
    participant PS as PowerShell
    participant FS as File System

    DevTools->>Finder: findSoftwareInstallLocation(executableName, displayName)
    alt Windows with displayName
        Finder->>Registry: findInUninstallRegistry(displayName)
        Registry->>PS: execute registry query
        PS-->>Registry: path (InstallLocation or DisplayIcon)
        Registry-->>Finder: [path, source]
    else Windows fallback
        Finder->>FS: derive path from AppCompatFlags / executable name
        FS-->>Finder: derived path
    else macOS
        Finder->>FS: check /Applications/{executableName}.app
        FS-->>Finder: app path
    end
    Finder-->>DevTools: CLI path or null
    DevTools->>FS: resolve cli.bat at discovered location
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • Review PowerShell script encoding/decoding and error handling in findInUninstallRegistry().
  • Validate path normalization and fallback logic in findSoftwareInstallLocation().
  • Confirm decodeGbk() behavior on registry output and edge cases.
  • Check the mp-weixin bundle ID update and Windows CLI path construction in devtools.ts.

Poem

🐰 I hopped through folders, registry and shell,
Searched Windows nooks and macOS dell,
Found cli.bat where it hides in the night,
Updated names, made discovery light,
🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: devtools windows support' clearly and concisely summarizes the main change: adding Windows platform support to devtools. It directly reflects the primary objective of the PR.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/logics/devtools.ts (1)

9-9: Clarify executable vs display name for Windows devtools detection

On Windows (Line 55), DEVTOOLS_BUNDLE_ID.windows['mp-weixin'] (Line 17) is used both as executableName and displayName when calling findSoftwareInstallLocation (Line 60). The helper, however, treats:

  • first parameter as the executable base name for AppCompat (<name>.exe), and
  • second as the Control Panel display name for the uninstall registry lookup.

This is only safe if the actual .exe file name exactly matches the display name (minus the extension). To make the fallback more robust and self‑documenting, consider:

  • storing separate exeName and displayName constants for Windows, or
  • passing the known executable base name as the first argument and the localized display name as the second.

Also applies to: 17-18, 55-64

src/utils/index.ts (3)

42-45: Harden decodeGbk typing and runtime compatibility

decodeGbk currently uses NonSharedBuffer and new TextDecoder('gbk'):

  • Ensure NonSharedBuffer is actually available in your type environment; otherwise this will not type‑check. A safer, more generic signature would be something like input?: Uint8Array | ArrayBuffer (or simply Buffer | Uint8Array for Node).
  • TextDecoder('gbk') will throw if the runtime’s TextDecoder doesn’t support the 'gbk' label. If you need to support a wider range of Node versions/builds, consider instantiating the decoder once in a guarded block or falling back to UTF‑8 when GBK isn’t available.

Please verify your Node.js target version supports TextDecoder with the 'gbk' label and that NonSharedBuffer is defined in your typings (e.g., by searching for a type NonSharedBuffer alias or checking tsconfig.json types settings).


53-116: Align or document findSoftwareInstallLocation return shape across platforms

On Windows, this helper returns the directory that contains the executable (either InstallLocation or dirname(DisplayIcon)), while on macOS it returns the .app bundle path (e.g. /Applications/Foo.app).

The difference is subtle but important for callers that might want to append cli.bat/Contents/MacOS/...:

  • Today, devtools.ts only uses this helper on Windows, so it’s fine.
  • Future callers might assume “installation directory” means the same thing on all platforms.

Consider either unifying the semantics (always return the directory that directly contains the main executable) or explicitly documenting the current platform‑specific behavior in the JSDoc so it’s clear how to consume the returned path.


124-180: Tighten quoting/escaping in findInUninstallRegistry PowerShell script

appName is interpolated directly into the PowerShell snippet as:

$target = "*${appName}*"
...
Where-Object { $_.DisplayName -like $target }

Even though current callers use a trusted constant, this will misbehave (or become an injection vector) if appName ever contains quotes, backticks, or wildcard characters.

To future‑proof this helper:

  • Escape appName before embedding it in the script (e.g., replace " with \" and handle backticks), or
  • Pass it as an argument and build $target inside PowerShell without string interpolation, e.g. using single quotes and -like "*$($escapedName)*".

Also, consider logging at debug level when the PowerShell call fails instead of completely swallowing errors; that will make diagnosing environment issues much easier.

Please verify whether appName might ever come from configuration or user input; if so, harden the quoting/escaping as suggested.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a72945 and ac74280.

📒 Files selected for processing (2)
  • src/logics/devtools.ts (2 hunks)
  • src/utils/index.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/logics/devtools.ts (1)
src/utils/index.ts (1)
  • findSoftwareInstallLocation (53-116)

@Vanisper
Copy link
Member Author

53-116: Align or document findSoftwareInstallLocation return shape across platforms

这个不是问题,“*.app” 其实是一个文件夹而不是可执行文件本身,所以 *.app 视为 InstallLocation 应该也是合理的,符合这个函数的语义。
@coderabbitai

@coderabbitai
Copy link

coderabbitai bot commented Nov 22, 2025

Tip

For best results, initiate chat on the files or code changes.

@Vanisper, thank you for the clarification! You're absolutely right — on macOS, .app bundles are indeed directories (application bundles) rather than single executable files, so returning the .app path as the installation location is semantically correct and aligns perfectly with the function's purpose. I appreciate you explaining this design decision.


✏️ Learnings added
Learnt from: Vanisper
URL: https://github.com/uni-helper/unh/pull/12

Timestamp: 2025-11-22T16:55:44.671Z
Learning: On macOS, `.app` bundles are directories (application bundles), not single executable files. In functions like `findSoftwareInstallLocation`, returning the `.app` path as the installation location is semantically correct and appropriate.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Copy link
Member Author

@Vanisper Vanisper left a comment

Choose a reason for hiding this comment

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

ok

@FliPPeDround
Copy link
Member

ok

非常感谢🙏,我最近有点忙,可能要之后才能合并。
谢谢 ;)

@Vanisper
Copy link
Member Author

好的哈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants