40MB を諦めた話と、リリース準備の取捨選択 — Windows スクショツール開発記 #4
先に結論
検索でたどり着いた方向けに、要点だけ。
- 当初の 実行ファイルサイズ目標 40MB は諦めて、60〜80MB を現実値に置き直した
- 撮影方式は 新しい仕組みを諦めて、ひとまず古典的な仕組みに寄せるところから始める方針にした
- 機能としては モザイクをぼかしに寄せる / 暗号化保存は MVP から外す、など、ユーザー価値と実装コストを照らして削る判断もした
- セキュリティ原則(外部通信しない、キー入力をフックしない)は、そういう書き方をしないことを CI で機械的にチェックする形で守る
連載の他記事
- #1 Claude Code を 10 並列で動かして、PR が 7 本同時に上がった日
- #2 バーが消える / 隣のモニタにはみ出す / 撮影中に画面が固まる
- #3 「撮ったのに見えない」を構造で防ぐ — アーキテクチャの話
- #4 40MB を諦めた話と、リリース準備の取捨選択(この記事)
1. 実行ファイルのサイズ目標を 40MB から 60〜80MB に置き直した
このスクショツールは インストーラを使わず、ひとつの実行ファイルだけで配布する想定です。これだと、ユーザーが受け取ってすぐ動かせるので体験が軽い、という狙いです。
最初は「40MB に収めたい」という目標を立てていました。.NET 製の Windows アプリで、ランタイムまで全部含めて単一の実行ファイルに梱包する self-contained 構成に、PublishTrimmed で不要な型を機械的に削るオプションを足せば、40MB あたりまで持っていけるんじゃないか、というふんわりした期待です。
実際に PoC をやってみた感触と、事前に調べた範囲の情報を合わせて見ると、
- WPF はリフレクションを多用する作りなので、Trim が安全に削れる範囲が小さい
- 削りすぎると実行時に必要なものまで落ちて、起動しなくなる
- 確実に動く構成を取ると、自分の手元では 60〜80MB あたりに落ち着きそう
という見え方になってきました。なので、サイズ目標は 60〜80MB に置き直しました。
ここはちょっと悔しいポイントではあるのですが、目標値を現実に合わせる判断をしておかないと、あとあと「サイズに合わせて機能を削る」みたいな本末転倒な話になりかねないので、早めに切り替えることにしました。
2. 撮影方式は「新しい仕組み」を諦めて、古典的な方に寄せる
Windows でスクリーンショットを撮る API は、大きく分けると 2 系統あります。
- WGC (Windows Graphics Capture): 比較的新しい仕組みで、画面の合成段階に近いところで取得するやり方
- GDI 系 (BitBlt / PrintWindow): 古典的な仕組みで、Win32 時代から使われているやり方
WGC のほうは、ハードウェアアクセラを使っている画面でも黒く写らない、などの利点があります。GDI 系は、特定の条件で画像が黒くなる(いわゆる BitBlt 黒画像問題)という既知の問題がありますが、その代わり実装はシンプルで、対応範囲も広いです。
最初は「WGC を主軸、GDI を補助」で考えていました。ただ、実際に PoC を進めると、WGC 側の検証コストが MVP のスコープに対して重く、ここでつまずくとリリースが遠のきそうでした。
なので、
- MVP では GDI 系を主軸にする
PrintWindowをPW_RENDERFULLCONTENTフラグ付きで呼ぶと、黒画像問題は大部分を回避できる目処がついている- WGC を使うかどうかの判断は、MVP の次のリリース に持ち越す
という整理にしました。実装を「最小限で動くもの」に揃えてから、必要に応じて段階的に置き換える、という考え方です。
3. 機能の取捨選択
MVP のスコープは、大きく言うと「普段使いで困らない撮影体験を、最小構成で揃える」というあたりに置いています。具体的に削った / 寄せた判断をいくつか挙げると、
モザイクはぼかしに寄せる
最初は、画像の一部を隠す手段として「モザイク」と「ぼかし」の両方を実装する想定でした。ただ、ユーザーが実際にやりたいのは「ここを見せたくない」というだけのことなので、ぼかしひとつあれば多くのケースは間に合います。
エディタの機能を 1 つ減らせば、UI もテストもシンプルになるので、MVP ではぼかしだけ残すことにしました。モザイクは将来必要になったら足す形で。
自由線描画は MVP から落とす
矢印・四角・テキスト・ぼかしの 4 つは MVP に入れます。一方で「自由線で書き込む」ような機能は、需要としては「あったら便利」レベルだったのと、実装と UX の両方で深掘りが必要になるので、MVP からは外しました。
ワークスペースの暗号化保存は MVP から外す
過去のスクショを保存しておく場所(ワークスペース)を、Windows 標準の暗号化機能(DPAPI / EFS)で守るかどうか、というのも検討しました。
ただ、考えていくと、
- そもそも、ローカルディスクに置く時点で、その PC のユーザーは内容を見られる前提になる
- 攻撃モデルがはっきりしないまま暗号化を入れると、復号フローや権限管理など UX のコストが大きくなる
- 「ここまではやらない」と最初から決めておいたほうが、自分にとっては気持ちが楽でした
という整理になり、暗号化保存は MVP には入れないことにしました。「やらない」と決めるのも、ひとつの設計判断なんだろうなと思います。
4. セキュリティ原則は CI で機械的に守る
このツールの方針として、
- 外に通信しない
- キー入力を覗き見しない
- テレメトリを送らない
- 自動更新もしない
というあたりを掲げています。とはいえ、コードを書いていると「うっかり」で原則と矛盾するコードを足してしまうこともあります。
なので、
HttpClientなどの外部通信系の参照が追加されたら CI で検出するWH_KEYBOARD_LL(Windows の低レベルキーボードフック)を使うコードが入ったら CI で警告する- Dependabot を「security 即マージ / minor 週次 / major 個別判断」の 3 段階で運用する
といった機械的な仕組みを CI に仕込んで、原則からそれた書き方が「うっかり」では入らないようにする予定です。原則を口で言うだけでなく、機械的に守れる形に落とす ところまでをひと続きで考えるイメージです。
振り返り
この連載で書いてきた話は、結局のところ、
- 個人開発でも、Claude Code を並列で動かすことで、密度はかなり上げられる(#1)
- その上で出てきた機能のひとつひとつには、ちゃんと小さな葛藤がある(#2)
- それを下支えする設計は、似たバグが再発しない構造を選んでおきたい(#3)
- そして、リリースに向かっては、目標値の置き直しと「やらない」判断、それを CI で支える整備が必要(#4)
というあたりに整理できる気がします。
このスクショツールはまだ MVP の途中で、リリースまではもう少しかかりそうです。実装が落ち着いて配布できる状態まで漕ぎつけたら、続編としてリリース編を書こうと思います。
ここまでお付き合いいただきありがとうございました。