浏览器唤起桌面端应用(进阶篇)

------------基于自定义协议的桌面端版本控制方案

基础篇中,我们已经实现了:

  • 通过 Windows 自定义协议(XXXX://open)
  • 从浏览器直接唤起本地桌面程序

本篇作为 进阶版,核心目标不再只是「能唤起」,而是:

在多版本桌面程序共存的情况下,实现"可控、可扩展、可演进"的版本选择机制


为什么需要"桌面端版本控制"?

在工程软件企业内部工具中,常见问题包括:

  • 多个版本并行安装1.0、2.0、3.0、...
  • 不同项目、不同数据依赖特定版本
  • 浏览器 / Web 系统需要精确控制启动的版本

如果只是简单写死一个 exe 路径,会带来:

  • ❌ 无法指定版本
  • ❌ Web 侧与桌面侧强耦合
  • ❌ 后期升级成本高

因此我们需要一个 "启动代理层(Launcher)", 接下来我们以NX为案例去实现一个对于不同版本控制的唤起。


整体架构设计思路

text 复制代码
浏览器
  |
  | nx://open?version=12
  v
Windows 协议注册(nx)
  |
  v
NxLauncher(bat / ps1)
  |
  | 解析参数 + 版本选择
  v
具体 NX 版本 exe

核心思想

❗ 浏览器永远只关心"意图",

❗ 桌面端 Launcher 决定"如何执行"。

NxLauncher:启动代理的职责划分

NxLauncher 需要做什么?

  1. 接收并解析 URL
  • nx://open
  • nx://open?version=11
  • nx://open?version=12
  1. 清洗参数
  • 去掉协议前缀
  • 去掉不可见字符 / 空格
  • 保证解析稳定性
  1. 版本 → 可执行文件映射
  • version = 11 → NX 11 路径
  • version = 12 → NX 12 路径
  1. 兜底策略
  • 未指定 version → 启动最新版本
  • 指定版本不存在 → fallback
  1. 真正启动程序

落地方案

1. 注册表实现

新建文本,复制如下文字

scss 复制代码
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\nx]
@="URL:NX Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\nx\shell\open\command]
;ps1 使用的代码
;@="powershell -NoProfile -ExecutionPolicy Bypass -File \"D:\\Desktop\\NxLauncher.ps1\" \"%1\""
;bat 使用代码
@="\"D:\\Desktop\\NxLauncher.bat\" \"%1\""

将文件后缀改为reg, 命名为nx.reg

然后根据使用的脚本做修改, 双击注册

⚠️ 注意;请根据你本机NxLauncher的实际位置修改 @= 后的路径。

注册表原则

❌ 不判断版本,只做转发,不做逻辑

❌ 不写死 exe

✅ 只负责把 URL 原样交给 Launcher

2. NxLauncher实现

2.1 BAT 方案(轻量、零依赖)

适合

  • 环境受限
  • 不方便修改 PowerShell 策略
  • 希望注册表直接调用

特点

  • 使用 PowerShell 作为辅助解析
  • 控制力略弱,但稳定可靠
c# 复制代码
@echo off
setlocal EnableDelayedExpansion

:: ==================================================
:: NxLauncher.bat
:: 功能:
:: 1. 解析 nx://open?version=xx
:: 2. 去掉空格和不可见字符
:: 3. 输出调试信息
:: 4. 根据 version 打开对应 NX
:: ==================================================

:: 获取浏览器传来的 URL,去掉两端引号
set RAW_URL=%~1

:: ---------------------------
:: 去掉协议前缀 nx://open 或 nx://open/
:: ---------------------------
set PARAMS=%RAW_URL:nx://open/=% 
set PARAMS=%PARAMS:nx://open?=% 

:: 去掉开头的 ?(如果有)
if defined PARAMS if "%PARAMS:~0,1%"=="?" set PARAMS=%PARAMS:~1%

:: ---------------------------
:: 提取 version
:: ---------------------------
set VERSION=[]

:: 调用 PowerShell 去解析并 trim
for /f %%V in ('powershell -NoProfile -Command ^
    "$p='%PARAMS%'; if ($p -match 'version=(.+)') { ($matches[1]).Trim() }"') do set VERSION=%%V

:: ---------------------------
:: 输出调试信息
:: ---------------------------
:: echo RAW_URL=%RAW_URL%
:: echo PARAMS=%PARAMS%
:: echo VERSION=[%VERSION%]
:: pause

:: ---------------------------
:: NX 安装路径
:: ---------------------------
set NX12=D:\Program Files\Siemens\NX 12.0\NXBIN\ugraf.exe
set NX11=D:\NX\NX 11.0\NXBIN\ugraf.exe

:: ---------------------------
:: 根据 version 选择 NX
:: ---------------------------
set NX_EXE=

if /i "%VERSION%"=="12" if exist "%NX12%" set NX_EXE="%NX12%"
if /i "%VERSION%"=="11" if exist "%NX11%" set NX_EXE="%NX11%"

:: 默认最新
if not defined NX_EXE (
    if exist "%NX12%" set NX_EXE="%NX12%"
    if not defined NX_EXE if exist "%NX11%" set NX_EXE="%NX11%"
)

:: ---------------------------
:: 找不到 NX
:: ---------------------------
if not defined NX_EXE (
    echo NX not found!
    pause
    exit /b 1
)

:: ---------------------------
:: 启动 NX
:: ---------------------------
start "" %NX_EXE%

exit /b 0

将文件后缀改为bat, 命名为NxLauncher.bat

然后根据使用的脚本做修改

⚠️ 注意;请根据你本机Nx的实际位置修改路径。

设计重点

  • 不在 bat 中硬解析 URL(太脆弱)
  • 利用 PowerShell 做字符串清洗
  • bat 只负责"调度"

2.2 PowerShell 方案(推荐 / 可扩展)

新建文本,粘贴以下文本

c# 复制代码
# NxLauncher.ps1
# ==================================================
# 功能:
# 1. 解析 nx://open?version=xx
# 2. 有 version → 打开指定 NX 版本
# 3. 无 version → 默认打开最新版本
# 4. 调试输出并暂停,方便查看解析过程
# ==================================================

param (
    [string]$RawUrl
)

# ---------------------------
# 1. 清理 URL
# ---------------------------
$RawUrl = $RawUrl.Trim('"')  # 去掉可能的引号
Write-Host "RawUrl: $RawUrl"

# 去掉协议前缀 nx://open 或 nx://open/
$paramString = $RawUrl -replace '^nx://open/?', ''
Write-Host "Param string: $paramString"

# ---------------------------
# 2. 解析 version
# ---------------------------
Add-Type -AssemblyName System.Web
$query = [System.Web.HttpUtility]::ParseQueryString($paramString)

$version = $query['version']
Write-Host "Parsed version: [$version]"

# ---------------------------
# 3. NX 安装路径配置
# ---------------------------
$nx12 = 'D:\Program Files\Siemens\NX 12.0\NXBIN\ugraf.exe'
$nx11 = 'D:\NX\NX 11.0\NXBIN\ugraf.exe'

$nxExe = $null

# ---------------------------
# 4. 根据 version 选择 NX
# ---------------------------
switch ($version) {
    '12' { if (Test-Path $nx12) { $nxExe = $nx12 } }
    '11' { if (Test-Path $nx11) { $nxExe = $nx11 } }
}

# 默认最新
if (-not $nxExe) {
    if (Test-Path $nx12) { $nxExe = $nx12 }
    elseif (Test-Path $nx11) { $nxExe = $nx11 }
}

# ---------------------------
# 5. 检查 NX 是否存在
# ---------------------------
if (-not $nxExe) {
    Write-Host "NX not found!"
    Read-Host "Press Enter to exit..."
    exit 1
}

Write-Host "Using NX: $nxExe"

# ---------------------------
# 6. 启动 NX
# ---------------------------
Start-Process -FilePath $nxExe

# ---------------------------
# 7. 暂停查看输出
# ---------------------------
# Read-Host "Press Enter to exit..."

将文件后缀改为ps1, 命名为NxLauncher.ps1

然后根据使用的脚本做修改

⚠️ 注意;请根据你本机Nx的实际位置修改路径。

适合

  • 长期维护
  • 复杂参数
  • 后续扩展(license / workspace / project)

优势

  • 原生 QueryString 解析
  • 逻辑清晰
  • 可维护性极高

3. 浏览器实现

html 复制代码
    <button id="openNX11">唤起NX11</button>
    <button id="openNX12">唤起NX12</button>
    <button id="openNXAuto">自动选择最新版本</button>
    <script>
        document.getElementById('openNX11').addEventListener('click', () => {
            openNX('11');
        })
        document.getElementById('openNX12').addEventListener('click', () => {
            openNX('12');
        })
        document.getElementById('openNXAuto').addEventListener('click', () => {
            openNX();
        })

        function openNX(version = '') {
            let url = 'nx://open';
            const params = [];
            if (version) params.push(`version=${version}`);

            if (params.length > 0) {
                url += '?' + params.join('&');
            }

            window.location.href = url;
        }
    </script>

好处

  • 前端逻辑极简

  • 参数可自由扩展:

    • nx://open?version=12&project=A
    • nx://open?workspace=xxx

成果展示

可继续演进的方向

📦 JSON 配置驱动版本映射

🧠 自动检测已安装版本

🧩 NxLauncher → 通用 Desktop Launcher

🌐 Web 平台统一调度本地能力

✅ 总结

基础篇解决"能不能唤起"

进阶篇解决"唤起谁、如何唤起、以后怎么扩展"

这套思路本质上是:

用 Web 参数驱动桌面能力,用 Launcher 隔离不确定性。

相关推荐
Lefan3 小时前
UniApp 隐私合规神器!一键搞定应用市场审核难题 - lf-auth 隐私合规助手
前端
Jing_Rainbow3 小时前
【Vue-2/Lesson62(2025-12-10)】模块化与 Node.js HTTP 服务器开发详解🧩
前端·vue.js·node.js
风度前端4 小时前
用了都说好的 uniapp 路由框架
前端
冴羽4 小时前
2026 年 Web 前端开发的 8 个趋势!
前端·javascript·vue.js
码银4 小时前
ruoyi的前端(vue)新增的时候给字典设置默认值 但不能正常
前端
凌览5 小时前
别再死磕 Nginx!http-proxy-middleware 低配置起飞
前端·后端
EndingCoder5 小时前
类的继承和多态
linux·运维·前端·javascript·ubuntu·typescript
用户47949283569155 小时前
React 终于出手了:彻底终结 useEffect 的"闭包陷阱"
前端·javascript·react.js
程序员猫哥6 小时前
前端开发,一句话生成网站
前端