需求:外部應用 (郵件、報表、Web頁面) 點擊鏈接 rcp://claim=25222,啟動/喚醒 RCP 應用並打開對應業務對象 (如費用申請單)。
整體流程 (9步):
rcp://claim=25222 鏈接HKEY_CLASSES_ROOT\rcp 映射到批處理文件reg add HKCR\rcp /ve /d "URL:RCP Protocol"
reg add HKCR\rcp /v "URL Protocol"
reg add HKCR\rcp\Shell\Open\Command /ve /d "C:\path\launch_rcp.bat %%1"
```
%%1 傳遞完整 URL 給批處理。Linux/Mac 需配置桌面環境 MIME 類型關聯。
2. 批處理啟動 TCP 客戶端
@echo off
set JAVA_BIN=C:\Program Files\Java\jre\bin
cd RCP_CLIENT_DIR
%JAVA_BIN%\java.exe com.company.uri.URIClient %1
EXIT
3. TCP 客戶端/服務器通信協議
- 客戶端連接 localhost:PORT
- 服務器發送
sendAction 提示
- 客戶端回傳
claim=25222
- 雙方關閉連接
核心類:URIClient、URIServer、URIServerThread、URIConstants。
4. RCP 插件啟動內嵌服務器
public void start(BundleContext context) throws Exception {
super.start(context);
new URIServer().start(); // 獨立線程監聽
}
5. UI 線程安全執行業務邏輯
// URIServerThread 中
Display.getDefault().asyncExec(() -> {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
shell.setActive(); shell.setMaximized(true); shell.setVisible(true); shell.setFocus();
// 打開業務編輯器/視圖: claim=25222
openBusinessObject("claim", "25222");
});
必須用 Display.asyncExec() 切換到 UI 線程,否則拋 SWTException: ERROR_THREAD_INVALID_ACCESS。
已知問題與優化方向
- 瀏覽器窗口殘留:無法自動關閉,可嘗試
start /b 或協議處理器直接調用 exe
- 錯誤處理:TCP 通信需完善 try-catch、超時、參數驗證、防注入
- 單實例保障:若 RCP 未運行,批處理應直接啟動 RCP 並傳參數,而非報錯
- 跨平台:Linux 用
.desktop + MIME,Mac 用 CFBundleURLTypes
