2026/06/16(火)WSL2の中からPowershellでOSへ通知トーストを投げる
PowerShellはWSL2の中から叩けるため、WSL2の中から通知を出したいときに使える。
PowerShellなのでホスト側のWindowsからも使える。
確認環境
PowerShell 7では動かないので注意。
| Env | Ver |
|---|---|
| OS | Windows 11 Pro 25H2 (OSビルド 26200.8655) |
| PowerShell | 5.1.26100.8655 |
やり方
この内容を
toast.ps1など適当な名前で保存する。文字コードはUTF-8 BOM, 改行コードはLFにしておくparam ( [String]$subject = "WSL Notice", [String]$title = "たいとるですー", [String]$message = "お知らせでーす", [String]$icon = "C:/env/1e1b9fdf82a6a544.png", [switch]$keep ) [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null $template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastImageAndText04) $xml = New-Object Windows.Data.Xml.Dom.XmlDocument $xml.LoadXml($template.GetXml()) $toastTextElements = $xml.GetElementsByTagName("text") $toastTextElements.Item(0).AppendChild($xml.CreateTextNode($title)) > $null $toastTextElements.Item(1).AppendChild($xml.CreateTextNode($message)) > $null $toastImageElements = $xml.GetElementsByTagName("image") $toastImageElements.Item(0).SetAttribute("src", $icon) > $null if ($keep) { $xml.DocumentElement.SetAttribute("scenario", "reminder") > $null $actions = $xml.CreateElement("actions") $action = $xml.CreateElement("action") $action.SetAttribute("content", "閉じる") > $null $action.SetAttribute("arguments", "dismiss") > $null $action.SetAttribute("activationType", "background") > $null $actions.AppendChild($action) > $null $xml.DocumentElement.AppendChild($actions) > $null } $toast = [Windows.UI.Notifications.ToastNotification]::new($xml) $appId = $subject $notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($appId) $notifier.Show($toast)- 次の書式で叩くと通知トーストが出る
powershell.exe -File 'C:/path/to/toast.ps1' -subject hoge -title fuga -message piyo -icon C:/path/to/icon.png -keep
このスクリプトのオプション
| オプション | 役割 |
|---|---|
-subject |
通知の表題。ここを変えると別の通知として扱われる |
-title |
通知のタイトル |
-message |
メッセージ本文。一行のみ |
-icon |
アイコン。Windowsホストの絶対パスで指定 |
-keep |
このフラグを立てると通知が消えなくなる |
-subjectを変えると別の通知扱いになるため、通知を別々に貯めることができるようになる。
Windows側から叩く方法
powershell 'C:/path/to/toast.ps1' -subject hoge -title fuga -message piyo -icon C:/path/to/icon.png -keep
Windows側から叩く場合、-Fileは省略できる。
参考情報
- ToastTemplateType 列挙型 (Windows.UI.Notifications) - Windows apps | Microsoft Learn
- ここの内容とググった情報からXMLの構造をエスパーして実装している
あとがき
Claude Codeの確認と終了のイベントで通知が出ると便利かなと思って作ってみたが、まだ試せていない。
取りあえずWSL2の中と、Windowsホスト側から叩いたときに通知が出ることは確認している。
PowerShell 7で動かそうと思ったらエラーまみれで動かず、PowerShell 7の場合、NuGetパッケージを取得するか、DLLのパスを直に指定するか、サードパーティの通知ライブラリを使うかということで、諦めた。
2026/06/16(火)Microsoft Edge rounded cornersが潰され、Edgeのクライアント領域に角丸のフレームが出るようになった問題を解消する
投稿日:
前回の対処ではMicrosoft Edge rounded cornersを設定して回避していたが、これが潰されたので回避方法を残す。
確認環境
- Microsoft Edge バージョン 149.0.4022.69, 149.0.4022.98
- Windows 11 Pro
やり方
- スタートにピン止めしているEdgeを右クリックして「ファイルの場所を開く」

- 開いた場所にあるEdgeを右クリックして「プロパティ (R)」

- Microsoft Edgeのプロパティが出るので、「リンク先(T)」の入力欄の末尾に
--enable-features=msForceNoRoundedCornerAndMarginを付け足す

- 「OK」を押して保存する
- Edgeを終了し、スタートのピン止めから起動すれば角丸が消える
端的に言うとこのコマンドで起動すれば消える。
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --enable-features=msForceNoRoundedCornerAndMargin
あとがき
レスポンシブシミュレーションの画面でも角丸が出るためWeb開発にも支障が出ると思うが、マイクロソフトはなぜこんな変更をしたのだろうか…。
余談だが、Bring back the "Microsoft Edge rounded corners" optionにフィードバックを送ると改善する可能性があるので直してほしい人は送るといいかも?私は送った。
現時点で625の投票と205個のフィードバックがついている。6月8日に見たときは391票と130コメントだったので、だいぶ増えている。
2025/03/31(月)自作ルーターを作っていくのにR86S U1を買ったのでOSのインストールをした
投稿日:
昨年フレッツ光クロス、10Gbps対応に関する覚書を書いてしばらく経つが、いよいよ10GbE対応のための環境を作ろうと思ったので、その記録を残していく。
第一弾はR86S U1を買ったので、その購入録とOSのセットアップまでのログを書いていく。
買ったもの
今回購入したのは中華性の怪しい10GbE自作ルーターマシンとして名高いR86S U1だ。もう話題になって数年経っているので旬は過ぎていると思うが、依然として10GbEルーターとして安価な選択肢だと思う。
買った後で気が付いたが、U2のほうがスペックが上で値段同じなのでU2を買ったほうがいい。
セットアップ時にあるといいもの
- HDMI to Micro HDMI変換アダプタ
- SDカード or USBメモリ
- rufusやbalenaEtcherなどのイメージを焼く手段
- MSYS2
初回起動
私が購入したものはeMMC内にOSが上手く入っていないのかgrubが表示されるだけで、マニュアル操作でも起動イメージが見当たらずmOSを起動することができなかった。
どの道プリインストールされているOSは中国語で役に立たないという話だったのでOSのセットアップを行うことにした。
試験起動
汎用PCへのインストール手順は公式情報である、[OpenWrt Wiki] OpenWrt on x86 hardware (PC / VM / server)が参考になる。
- リリース一覧を開き最新の安定板を辿り、x86→64に進む
generic-ext4-combined-efi.img.gzをダウンロードするsha256sum openwrt-24.10.0-x86-64-generic-ext4-combined-efi.img.gzでハッシュを確認gunzip openwrt-24.10.0-x86-64-generic-ext4-combined-efi.img.gzで展開する- Explzhだと上手く解凍できなかったのでMSYS2からgunzipを叩いて対処した
- 展開して出てきたimgファイルをSDカードかUSBメモリに焼く
- imgファイルを焼いたメディアをR86Sに差し込む
- R86Sの電源を入れPOST画面が出たらDeleteを叩き、BIOSに入る
- 通電時に勝手に電源が入るため一回落とした方がいい
- 起動順序を差し込んだメディアに変更する
eMMCへのOSインストール
Ubuntuのインストールディスクの中にOpenWrtのイメージをバンドルする方法がわからず、SDカードにimgを焼いてもマウントできなかったのでネットワークを経由してインストールしている。
事前準備
- OpenWrtのイメージファイルを入力しやすい短いファイル名にしてHTTPが疎通するどこかに置いておく
- R86S U1に前述のイメージと疎通可能なLAN線を刺す
インストール手順
- Ubuntu Serverのインストールイメージを落とす
- 日本語版サイトから落とすとEFIイメージでないものが落ちてきたので本家から落としてきたほうがいい
- rufusを使って何かしらのメディアに焼く
- R86S U1を起動し、POST画面でDeleteを叩き、BIOSを開く
- 起動順序をUbuntuを焼いたメディアにする
- USBの場合はUSB Key
- Ubuntuを起動し、GrubでTry or Installを選ぶ

- キーマッピングを日本語にするところまでインストールウィザードを進める
- 右上のヘルプを開き、Enter shellする


- wgetで事前準備で用意した起動イメージを落とす
- eMMCにイメージを焼く
dd if=openwrt-efi.img bs=1M of=/dev/mmcblk0 shutdownコマンドを叩く- 再起動でBIOSに入り起動順序をeMMCに変更
- GrubにOpenWrtが出て起動することを確認
- passwdコマンドでパスワードを設定する
2025年8月4日追記
この続きはR86SとOpenWrt 24.10でOCNバーチャルコネクトに接続したときのメモに書いている。
開梱の儀
梱包状態。安い中華製品にしてはなかなか丁寧だ。
箱もしっかりしている。
横の小さな箱にはMicro HDMI -> HDMIケーブルが付属していた。これは親切だ。
開梱すると本体とACアダプタが見えた。やはり梱包が丁寧だ。
箱の底にはマニュアルと検査証、六角が入っていた。この六角は本体を開けるためのものだが、なめてしまい役に立たなかった。
ネットワークインターフェースはSFP+が2口、2.5GbEイーサーが3口。他に電源用USB-C、USB3.0x2、USB2.0x1、SDカード、Micro HDMIといった感じだ。
表面にはケースファンと冷却用のフィンがついている。デザインも悪くない。
裏面と片側面にはゴム足がついており横置きにも縦置きにも対応している感じだ
分解
付属の六角がなめてしまい役に立たなかったのでちゃんとしたのを買ってきた。対応するのは1.5mmだった。
表のふたを開けるとNVMeSSDスロットが見える。ネジ穴的に一番長い奴しか無理だろう。
本体をパカっと二つに。どうやらマザーボードは三枚くらいに分割されているようだった。
あとがき
EFIイメージかBIOSイメージかは好みで選んでいいという記事を何個か見たが、BIOSイメージだと起動しなかったため、EFIイメージのほうがいいかもしれない。
参考までに手持ちのAMD64マシンにBIOSイメージを刺したところ、そもそも認識すらしなかったためダメなのかもしれない。24.10固有の問題なのかどうかはわからないが、今時はUEFIが推奨される環境であると思われるため、EFIイメージで問題ないと思われる。
ひとまずこれで10GbE環境への一歩を踏み出せたと思う。LANが構築でき、現状の環境でWAN込みで安定稼働させられたら実際に10GbE契約もしていきたいところだ。
しかしイメージを焼いたSDをマウントできないのは想定外だった。FAT32でフォーマットしたはずなのでマウントできそうなものだが…。正直焼いてマウントして取り出すより、アップしてwgetしたほうが楽なので別にいいのだが。
2025/03/05(水)Microsoft EdgeとGoogle Chromeの個人的な比較
投稿日:
ChromeからEdgeに乗り換えて一年半くらい経ったので、個人的にEdgeとChromeに思うところの比較をしてみた。これは別に優劣をつけるものではなく単なる感想。
| 項目 | Edge | Chrome |
|---|---|---|
| Ad Block | ✅ | ❌ |
| ダウンロード結果の保持 | ✅ | ❌ |
| マウスジェスチャ | ✅ | ❌ |
| UIがころころ変わらない | ✅ | ❌ |
| クライアント領域の広さ | ✅ | ❌ |
| Chrome Webストアから消えた拡張の維持 | ✅ | ❌ |
| 他端末とのタブ共有 | ✅ | ✅ |
| 閉じたウィンドウを開き直す | ✅ | ⚠️ |
| 垂直タブバー | ✅ | ⚠️ |
| 設定同期 | ⚠️ | ✅ |
| 設定の単純さ | ❌ | ✅ |
| ブラウザベンダーの広告 | ❌ | ✅ |
Ad Block
Edgeには標準でAd Blockが導入されており、Chromeのようにサードパーティ製の胡散臭い拡張機能に依存する必要がない。
参考として個人的にはChromeの場合、uBlock Originを広告ブロッカーとして利用していた。これはAd Blockよりも強力だと思う。
ダウンロード結果の保持
Edgeではダウンロード結果を保持することができる。以下の画像の右側で「ダウンロード」と出ている垂直バーだ。
これが出ているとzipなどの書庫をダウンロードしたときに展開してフォルダに遷移がスムーズにできて便利だし、ダウンロード完了直後にアクション出来なかった場合も対応しやすいので非常に助かる。
Chromeにはこの機能がないのでダウンロードが完了した直後にクリックしようとしてもできないことがあるし、仮にできても展開先を開くには再表示しないとならず手間だ。ダウンロード中にクリックしておくとアクションの予約もできるが、上手く動かないことも多い。これは多分タイムアウトがかかってるのだと思う。
マウスジェスチャ
Edgeには標準でマウスジェスチャが導入されており、サードパーティ製の拡張機能に依存する必要がない。
ChromeのマウスジェスチャといえばcrxMouse Chrome™ Gesturesが有名だと思うが、この拡張機能は過去に公開停止されており、個人的にあまり信頼していない。
Edge標準のマウスジェスチャはcrxMouseと比べると貧弱だが、一般的なパターンと、必要最低限の割り当てができ、特定Webサイトでは機能しないようにするブロックリストもあるため、十分使える。何よりファーストパーティなので安心しやすい。
UIがころころ変わらない
Chromeはコンテキストメニューがスクロール方式になったり、ブックマークバーや各種メニューのボタンがある日突如、肥大化したり、ユーザーを使って大胆なABテストをしてくるので使いづらく感じることがしばしばあった。
Edgeを使っていて、このような破壊的変更を感じることはなく、全体的に落ち着いている印象だ。これは質実剛健なマイクロソフトと、柔軟に対応するGoogleとの会社文化の差としてみることもできそうだ。
クライアント領域の広さ
左がEdge、右がChromeの画面上部のUI部分だが、Edgeのほうが少しだけUIが狭い分、クライアント領域が広い。
Chrome Webストアから消えた拡張の維持
EdgeではChrome Webストアから拡張機能が消えても維持されるが、Chromeだと強制的に削除される。強制的に削除されると設定ごと吹き飛ぶため、Tampermonkeyのようにユーザー定義が大きな拡張はバックアップがないとマニュアルで再導入するのも厳しい。
但しEdgeであってもインストール元が消えているため、ブラウザの再インストール時には消えると思われる。
他端末とのタブ共有
Edgeを利用している他の端末が現在開いているタブを共有できる。これは最後に開いていた状態を持っているため、電源が落ちている端末のタブも見れる。
この機能は端末を多く持っている人ほど恩恵があるだろう。Chromeにも同様の機能があるようだが、内容は確認していない。
閉じたウィンドウを開き直す
Edgeでは誤ってウィンドウを閉じたときでも、閉じたウィンドウを復元できる機能がある。
最近閉じた項目にウィンドウが閉じた履歴が出るので、ここから復帰できる。
もちろん閉じたウィンドウの中身は展開でき、何を閉じたかも確認できる。
Chromeにもあるが、履歴に存在せずショートカットキーで出しづらいのと、何を閉じたのかが一目でわからないのが微妙に感じる。
垂直タブバー
Edgeには垂直タブバーがあり、多数のタブを開いているときに便利なケースがある。しかし個人的にはChromeのタブリストの方が必要な時にだけ画面上に被さるように出てくるため使いやすいと感じている。Edgeのは画面が狭くなるし、タブバーを開いている間は本来のタブが消えてしまうので操作性が悪い。
Edgeの垂直タブバー
垂直タブバーを表示すると元々のタブが消え操作性が変わってしまう上、能動的に非表示にしないと画面を占有して邪魔なので私はあまり好きではない。
Chromeの同等機能
Edgeと比べてUIに破壊的変化がなく、フォーカスを失えば勝手に消えるので便利だ。
設定同期
Edgeの設定同期には問題がある。それは設定の大半が同期されないことだ。Edgeにはマイクロソフトによるお節介機能が多くあり、これを無効化するための設定が多くあるのだが、これらは全く同期されない。無数に設定がある割に不親切だ。マイクロソフトの広告系の機能ならまだしも、マウスジェスチャすら同期されないのはいくら何でも酷いと思う。
一方でChromeは、設定画面にあるものであれば、ほとんどすべての設定が同期される。標準ダウンロード方式以外恐らくすべて同期されているのではなかろうか?
設定の単純さ
Edgeにはマイクロソフトの利益に繋がる広告機能や、Copilotなどの本質的にブラウザとして不要な機能が山のようにあり、これらの有効無効を切り替える設定が数多くある。これは多くの人間にとっては複雑なことだと思う。
一方でChromeの設定も多いとはいえ、Edgeと比べると単純だ。設定することもさほどないので導入が圧倒的に楽である。
ブラウザベンダーの広告
Edgeはひたすらマイクロソフトのサービスに誘導するように色々と邪魔くさく仕向けてくるが、Chromeではそんなことはない。
但しこの広告は設定で消す事ができるため、一度消してしまえば気になることはない。
2024/05/29(水)HTTPリクエストを投げるときにHostヘッダは省かないほうがいい
HTTPヘッダを持たないHTTPリクエストはあり得るのか?というのを検証しているときに気づいた話。
RFC 7230ではHostヘッダを持たないHTTPリクエストは禁止されており、これを受けたサーバーは400応答を返すことを必須としている。
RFC 7230:Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and RoutingのHostより
A client MUST send a Host header field in an HTTP/1.1 request even if
the request-target is in the absolute-form, since this allows the
Host information to be forwarded through ancient HTTP/1.0 proxies
that might not have implemented Host.
A server MUST respond with a 400 (Bad Request) status code to any
HTTP/1.1 request message that lacks a Host header field and to any
request message that contains more than one Host header field or a
Host header field with an invalid field-value.
なお、Node.jsのHTTPサーバー機能ではHostヘッダーのない要求を受け入れることができる。
http.createServer([options][, requestListener])を見ると、以下のようにrequireHostHeader: falseを渡すことで実現可能だ。規定値はtrueであるため、基本的にはHostヘッダーなしの要求は400応答が返される。
import http from 'node:http';
http
.createServer({requireHostHeader: false}, (req, res) => {
console.log(req.headers);
res.statusCode = 200;
res.end();
})
.listen(3000);
nginxにおいてもHostヘッダーなしの要求は以下の応答が返されたため同様と思われる。
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.26.0</center>
</body>
</html>
但し、nginxにおいてHostなしの要求を許容する方法は見つからなかった。Server namesによるとserver_name "";とすることで出来そうに見えたが、これは機能させることができず、400応答が返された。























