B/S 後台管理系統需啟動 C/S 繪圖客戶端並自動登入,核心挑戰在於:瀏覽器如何喚起本地 EXE、如何安全傳遞認證資訊、客戶端如何解析參數。本文提供基於 WScript.Shell 的 JavaScript 呼叫方案,搭配環境變數註冊與命令列解析器,實現無縫銜接。
Run(command) → WScript.Shell.Run 啟動 EXE。PATH 環境變數,確保命令可被找到。Main() 解析命令列參數(用戶名+加密 Token)→ 呼叫免登入 API → 進入主視窗。
function Run(command) {
window.oldOnError = window.onerror;
window._command = command;
window.onerror = function(err) {
if (err.indexOf('automation') != -1) {
alert('命令被使用者禁止!請調整 IE 安全性設定。');
return true;
}
return false;
};
try {
var wsh = new ActiveXObject('WScript.Shell');
if (wsh) wsh.Run(command);
window.onerror = window.oldOnError;
} catch (e) {
alert('找不到程式檔案,請確認已安裝客戶端。');
}
}
// 使用範例:傳遞加密身分憑證
javascript:Run('EDNMS.UI.exe -u admin -p 4f5a51484e3c639b7c0e606511fe062d5f55aa0509638b385ed179e6d7fe4e9b7342f04c7c74b625574d6aa009693f386cef7b49536c3a4bfb5372675e76bb134f746a84466b7da86703');
[RunInstaller(true)]
public class InstallAction : Installer {
public override void Install(IDictionary stateSaver) {
base.Install(stateSaver);
UpdatePathEnvironment();
}
private void UpdatePathEnvironment() {
string regKey = @"SYSTEM\ControlSet001\Control\Session Manager\Environment";
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(regKey, true)) {
string path = key.GetValue("Path").ToString();
if (!path.Contains(physicalRoot)) {
key.SetValue("Path", path + ";" + physicalRoot);
}
}
}
}
public static class CommandLine {
public static CommandArgs Parse(string[] args) {
var ca = new CommandArgs();
int i = -1;
string token = NextToken(args, ref i);
while (token != null) {
if (IsArg(token)) { // 以 - 或 \ 開頭
string arg = token.TrimStart('-', '\\').TrimEnd('=');
string value = null;
if (arg.Contains("=")) {
var parts = arg.Split(new[]{'='}, 2);
arg = parts[0]; value = parts[1];
}
while (value == null) {
string next = NextToken(args, ref i);
if (next == null || IsArg(next)) { i--; value = "true"; }
else if (next != "=") value = next.TrimStart('=');
}
ca.ArgPairs[arg] = value;
} else if (token != "") {
ca.Params.Add(token);
}
token = NextToken(args, ref i);
}
return ca;
}
// 輔助方法 IsArg, NextToken 略
}
[STAThread]
static void Main(string[] args) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if (args.Length > 0) LoginByArgs(args);
else LoginNormal(args);
}
static void LoginByArgs(string[] args) {
var cmdArgs = CommandLine.Parse(args);
string user = cmdArgs.ArgPairs.GetValueOrDefault("u");
string token = cmdArgs.ArgPairs.GetValueOrDefault("p");
if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(token)) {
if (Portal.gc.LoginByIdentity(user, token)) ShowMainDialog();
else LoginNormal(args);
}
}
使用者需在 IE「網際網路選項 → 安全性 → 自訂等級 → ActiveX 控制項與外掛程式 → 對未標示為安全的 ActiveX 控制項初始化並指令碼」選擇「啟用」或「提示」,否則 WScript.Shell 會被阻擋。
myapp://login?token=xxx)替代 ActiveX,相容性更佳且安全性更高。