在網頁上調起本機C#程式

程序设计实验室發表於2024-11-14

前言

最近開始整理筆記裡的庫存草稿,本文是 23 年 5 月建立的了(因為中途轉移到 onedrive,可能還不止)

網頁調起電腦程式是經常用到的場景,比如百度網盤下載,加入 QQ 群之類的

我之前做了個管理電影的專案部署在 NAS 上自己用,就需要實現在網頁上一鍵呼叫電腦上的 Potplayer 播放電影,這時候直接掏出 C# 寫一個客戶端就非常方便了

登錄檔操作

在 Windows 上實現就是透過登錄檔,將 Scheme 和對應的程式新增進去。其他系統暫時沒需要就還沒研究,估計也是類似的。

需要配置一下 SchemePrefix ,本文例子中是 demo

在網頁上使用 demo:// 開頭的連結就可以喚起本機的程式了~

using System.Diagnostics;
using System.Web;
using Microsoft.Win32;

const string AppName = "DemoApp";
const string SchemePrefix = "demo";

// 初始化登錄檔
void InitReg() {
    if (!OperatingSystem.IsWindows()) return;

    var path1 = AppName;
    var path2 = $@"{path1}\shell\open\command";

    // 設定協議名稱
    var key1 = Registry.ClassesRoot.OpenSubKey(path1, true);
    if (key1 == null) {
        key1 = Registry.ClassesRoot.CreateSubKey(path1);
    }

    key1.SetValue("URL Protocol", "");
    key1.SetValue(null, $"URL:{SchemePrefix}");

    var key2 = Registry.ClassesRoot.OpenSubKey(path2, true);
    if (key2 == null) {
        key2 = Registry.ClassesRoot.CreateSubKey(path2);
    }

    var exePath = Environment.ProcessPath ?? "";

    key2.SetValue(null, $"\"{exePath}\" \"%1\"");
}

引數解析

因為是隨手寫的小工具,我也沒有用命令列解析的庫

如果用第三方庫程式碼會更優雅

這裡就做了兩個命令,一個 install 另一個 open

手動執行 install 會在登錄檔裡新增配置,之後這個程式檔案就不要移動了,後續網頁調起需要執行這個程式。

open 命令是網頁調起時執行的,注意命令引數裡的字元需要 URL 轉義。

string action = "", value = "";
string[] cmdArgs = Environment.GetCommandLineArgs();
if (cmdArgs.Length > 1) {
    var arg = cmdArgs[1];
    Console.WriteLine($"cmd args: {arg}");

    if (arg.StartsWith($"{SchemePrefix}://")) {
        arg = arg.Replace($"{SchemePrefix}://", "");
    }

    if (arg.EndsWith("/")) {
        arg = arg.Substring(0, arg.Length - 1);
    }

    var split = arg.Split("//");
    action = split[0];
    value = split.Length > 1 ? split[1] : "";
    Console.WriteLine($"action: {action}, value: {value}");
}

switch (action) {
    case "install":
        Console.WriteLine("init reg...");
        InitReg();
        Console.WriteLine("init reg finished.");
        break;
    case "open":
        var path = HttpUtility.UrlDecode(value);
        Console.WriteLine($"open file/dir: {path}");
        if (OperatingSystem.IsWindows())
            Process.Start($"C:\\Windows\\explorer.exe", path);
        if (OperatingSystem.IsLinux())
            Process.Start("xdg-open", path);
        break;
    default:
        Console.WriteLine("不知道做啥~");
        break;
}

參考資料

  • 如何在網頁上開啟本地應用 - https://segmentfault.com/a/1190000040237895
  • C#進行登錄檔和鍵值操作 - https://zhuanlan.zhihu.com/p/403162888

相關文章