やりたいこと
PowerShellで以下実行すると、
- Edgeが起動し、
- c:\Users\user\todo.html を表示
- URLの引数を受け取ることができること
Start-Process "todo://?task=買い物&due=2025-10-05"
問題点
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"
後片付け
- HKEY_CURRENT_USER\Software\Classes\todo\
を削除


