1
1

拡張機能で社内フォルダへのリンクを開けるようにしたい_NativeMessaging

Posted at

社内で使用しているwebシステムで、社内の別フォルダへのリンクを記載しておく。という事をよくします。
でも通常ブラウザからローカルリンクはセキュリティ的に開けないです。
今回の場合は、社内のローカルサーバーで管理されたサイトに書いている社内のローカル共有フォルダへのリンクなので、リンクから飛びたくなりました。
ということで拡張機能のNativeMessagingを試してみました。

似たことをリンク先でしています。

つくった拡張機能

コンテンツ

  • 内容入力する時に、毎回aタグを書いてリンクにするのが手間なので、後からURLにaタグをつける処理を入れる
  • NativeMessaging経由で開きたいのでhref='javascript:void(0)としてそのままでは開かないようにする
  • リンククリック時にbackground.jsへURLを渡す
  • 呼び出し先でエラーとかがあれば、アラートを出す
contents.js
// 元のサイトではURLを入力してもテキストのままなのでリンクに変更する
// hrefでの遷移はしないようにする NativeMessaging経由にするため
const qs = document.querySelectorAll(".Reference, .multiple-lines");
const exp = /((\\\\)[^\<\>"\n\r]*)/gi;
for (let i = 0; i < qs.length; i++) {
  const r = qs
    .item(i)
    .textContent.replace(exp, "<a href='javascript:void(0)'>$1</a>");
  qs.item(i).innerHTML = r;
}

// 指定のaタグにクリックイベントを追加
// 実行するのは192.168.xxx.xxだけと限定しておく
document.querySelectorAll("a").forEach((e) => {
  if (e.text.startsWith("\\\\192.168.xxx.xx")) {
    e.addEventListener("click", NativeMessagingPath);
  }
});
// アプリを呼び出すためbackgroundへ値を渡す処理
function NativeMessagingPath(e) {
  // 処理中はマウスアイコンをぐるぐるに変更
  document.body.style.cursor = "wait";
  chrome.runtime.sendMessage(
    e.target.text, // backgroundに渡すデータ
    function (response) {
      // 処理が終わったらマウスアイコンを戻す
      document.body.style.cursor = "auto";
      // クライアント処理結果
      if (response.return) {
        // 返された文字がerrorならアラート
        if (response.msg.startsWith("error")) {
          alert(response.msg);
        }
      } else {
        alert("NG" + response.msg);
      }
    }
  );
}

バックグラウンド

  • contents.jsから呼ばれたら、ネイティブアプリnativeexcuteへその値を渡して実行する
  • ネイティブアプリからの出力は、contents.jsへ返す
  • エラーならcontents.jsの方でアラートを出す
background.js
// contents.jsからの呼び出し時の処理
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  try {
    // 外部アプリを呼ぶ
    chrome.runtime.sendNativeMessage(
      "nativeexcute",  // この名前をマニフェストで設定した呼び出すアプリ名にする
      { value: request },
      function (response) {
        // contents.jsに値を返す
        sendResponse({
          return: true,
          msg: response.value,
        });
      }
    );
  } catch (error) {
    // エラー時
    sendResponse({
      return: false,
      msg: "error",
    });
  }
  return true;
});

拡張機能のマニフェスト

manifest.json
{
  "name": "linklink",
  "description": "リンクを開く",
  "version": "1.0",
  "manifest_version": 3,
  "permissions": [
    "alarms",
    "tabs",
    "nativeMessaging"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": [
        "http://192.168.xxx.xx"
      ],
      "js": [
        "contents.js"
      ],
      "run_at": "document_end",
      "all_frames": true
    }
  ]
}

ネイティブアプリ設定のマニフェスト

nativemanifest.json
{
    "name": "nativeexcute",
    "description": "NativeExcute",
    "path": "C:\\Users\\xxxx\\NativeMessagingExcute.exe",
    "type": "stdio",
    "allowed_origins": [
        "chrome-extension://xxxx拡張機能のIDxxxxx/"
    ]
}

レジストリへの登録

エクスポートでレジストリへの登録する時は、下の所に空の2行が無いと上手くいかないようです。

native_user.reg
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Edge\NativeMessagingHosts\nativeexcute]
@="C:\\Users\\ネイティブアプリ設定のマニフェスト保存場所のパス\\nativemanifest.json"


マニフェストの設定など

拡張機能のマニフェストとネイティブアプリを呼び出すためのマニフェストの設定をどこでするかがややこしいので注意必要です。

下記サイトの下らへんに、エラー時に確認するポイントがあるので、その当たりも参考にする。
https://learn.microsoft.com/ja-jp/microsoft-edge/extensions-chromium/developer-guide/native-messaging?tabs=v3%2Cwindows

つくったネイティブアプリ

.net コンソールアプリでつくりました。
主とした処理は、拡張機能から渡された値でProcess.Startするだけです。
こちらに置いています。

参考

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1