0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

カスタムスキームURL でローカルファイルに引数を渡して表示する方法

Last updated at Posted at 2025-10-01

やりたいこと

PowerShellで以下実行すると、

  • Edgeが起動し、
  • c:\Users\user\todo.html を表示
  • URLの引数を受け取ることができること
Start-Process "todo://?task=買い物&due=2025-10-05"

image.png

問題点

URLの引数を受け取ることができること

?%3Fに置き換わってしまう問題に遭遇。
#を使う(フラグメントという)方法で解決することが分かった。

全文

todo.reg

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\todo]
@="URL:Todo Protocol"
"URL Protocol"=""

[HKEY_CURRENT_USER\Software\Classes\todo\shell\open\command]
@="powershell.exe -ExecutionPolicy Bypass -File \"c:\\Users\\user\\todo-protocol.ps1\" \"%1\""

todo-protocol.ps1

param(
    [string]$uri
)

# 例: "todo://?task=買い物&due=2025-10-05"

# Uri オブジェクト化
$u = [System.Uri]$uri

# ?以降を取得(先頭の?を除去)
$queryString = $u.Query.TrimStart('?')

# ハッシュテーブルにパース
$params = @{}
foreach ($pair in $queryString -split '&') {
    if ($pair -match '=') {
        $k, $v = $pair -split '=', 2
        $params[[System.Uri]::UnescapeDataString($k)] = [System.Uri]::UnescapeDataString($v)
    }
}

# 確認用出力
Write-Host "元URI: $uri"
Write-Host "Query: $queryString"
Write-Host "Params:"
$params.GetEnumerator() | ForEach-Object {
    Write-Host "  $($_.Key) = $($_.Value)"
}

# --- ここから自由に処理 ---
# 例えばローカルHTMLに渡すなら
$localFile = "C:\Users\user\todo.html"
$localFileUrl = $localFile -replace '\\','/'

$query = ($params.GetEnumerator() | ForEach-Object {
    [System.Uri]::EscapeDataString($_.Key) + "=" + [System.Uri]::EscapeDataString($_.Value)
}) -join "&"

$fragment = if ($query) { "#$query" } else { "" }

Start-Process "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" `
    -ArgumentList "file:///$localFileUrl$fragment"

todo.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="shift-jis">
<title>Todo</title>
<style>
  table { border-collapse: collapse; margin-top: 1em; }
  th, td { border: 1px solid #333; padding: 0.3em 0.6em; }
</style>
</head>
<body>
<h1>パラメーター情報</h1>
<div id="paramTable"></div>

<script>
    // location.hash からフラグメント部分を取得
    let hash = location.hash; // 例: "#task=買い物&due=2025-10-05"
    let container = document.getElementById("paramTable");

    if(hash.length > 1) {
        // "#" を取り除き URLデコード
        let decoded = decodeURIComponent(hash.substring(1)); 
        // "&" で分割して key=value ペアにする
        let params = decoded.split("&").reduce((acc, pair) => {
            let [key, value] = pair.split("=");
            if(key) acc[key] = value || "";
            return acc;
        }, {});

        if(Object.keys(params).length > 0) {
            // テーブルを作成
            let table = document.createElement("table");
            let header = document.createElement("tr");
            header.innerHTML = "<th>パラメータ</th><th>値</th>";
            table.appendChild(header);

            for (let [k, v] of Object.entries(params)) {
                let row = document.createElement("tr");
                row.innerHTML = `<td>${k}</td><td>${v}</td>`;
                table.appendChild(row);
            }
            container.appendChild(table);
        } else {
            container.textContent = "パラメータはありません";
        }
    } else {
        container.textContent = "パラメータはありません";
    }
</script>
</body>
</html>

画面

Start-Process "todo://?hoge=fuga&piyo=pipi"
Start-Process "todo://?param1=value1"
Start-Process "todo://?task=買い物&due=2025-10-05"
Start-Process "todo://?task=買い物&due=2025-10-05"

image.png

後片付け

  • HKEY_CURRENT_USER\Software\Classes\todo\

を削除

image.png

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?