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

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

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

  • 通过 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 隔离不确定性。

相关推荐
前端大卫25 分钟前
Vue3 + Element-Plus 自定义虚拟表格滚动实现方案【附源码】
前端
却尘40 分钟前
Next.js 请求最佳实践 - vercel 2026一月发布指南
前端·react.js·next.js
ccnocare41 分钟前
浅浅看一下设计模式
前端
Lee川1 小时前
🎬 从标签到屏幕:揭秘现代网页构建与适配之道
前端·面试
Ticnix1 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人1 小时前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
twl1 小时前
OpenClaw 深度技术解析
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Grok API 申请及使用
前端
星光不问赶路人2 小时前
vue3使用jsx语法详解
前端·vue.js
天蓝色的鱼鱼2 小时前
shadcn/ui,给你一个真正可控的UI组件库
前端