Imaha486 / DoNotInstaller
git clone https://github.com/Imaha486/DoNotInstaller.git
2nd · 1d ago
ゲームのインストール&実行時のフォルダアクセスやレジストリ制御を単一フォルダに閉じ込めて、ポータブル化するための支援ツール
—
stars, 24h
+34
stars, 7 days · #1,212
+34
stars, 30 days · #8,194
34
★ total · +34% this week
3
forks · 0 open issues
Star history starts 2026-10-20; the chart appears after the second daily snapshot.
LanguageC++
License—
Created2026-10-18 (3d ago)
Last push1d ago
Watchers0
OwnerUser
Links
README excerpt
# DO-NOT-INSTALLER インストーラを **ドラッグ&ドロップ** で投げ込むと、そのインストーラがシステムへ 行う変更(レジストリ書き込み・インストールフォルダ以外へのファイル書き込み)を 横取りして **1 つのフォルダの中だけ** に閉じ込め、フォルダをコピーするだけで 別 PC でも動く **ポータブル版** を自作するツールです。 - レジストリ書き込み → フォルダ内のテキストファイル `dni.reg` に保存 - フォルダ外へのファイル書き込み → フォルダ内の `files\` 以下に保存 - 実行に必要な「フックツール」もフォルダ内に配置 実行時(ポータブル版の起動時)は、`dni.reg` を一時的な退避先レジストリに復元 → アプリ起動 → 終了時に変更を `dni.reg` に書き戻して退避先を削除します。 したがって **実レジストリは最終的に汚れません**。ファイルアクセスも同様に `files\` 以下へリダイレクトされるため、`C:\ProgramData` や `C:\Program Files` を 汚しません。 > 商用の ThinApp / Cameyo / Enigma Virtual Box などと同系統の「アプリ仮想化 > (ポータブル化)」ツールです。自分で用意したインストーラを、自分の PC 用に > ポータブル化する用途を想定しています。 --- ## 仕組み [code] ### レジストリ内のインストールパスを「吸収」する(実行時) 多くのゲーム/アプリは、レジストリに記録した絶対インストールパス (例: `InstallDir="C:\Program Files (x86)\Will\…"`)を読み、そこから データファイル(`OP.DAT` 等)を開きます。ポータブル実行時にこの値を素直に 読むと実フォルダを見に行ってしまい、しかも `FindFirstFile` のように**フック していないファイルAPI**経由だとリダイレクトも効かず失敗します。 そこで実行時(run モード)に、**シャドウレジストリ内の絶対パス値のうち、 対応するファイルがパッケージ内(`files\`)に実在するものを、ポータブル上の 実際の場所に書き換え(吸収し)ます**。これにより、アプリは最初からローカルの 実パスを読むので、あらゆるファイルAPIで確実にパッケージ内を参照します。 終了時には逆変換して `dni.reg` は正規の実パスのまま保ちます(別PCへ移動しても その場所に合わせて毎回吸収し直すため)。 ### 読み書きの一貫性(書いた値は必ず読み戻せる) レジストリもファイルも、**キャプチャ中にシャドウへ捕捉した項目は、以降の 読み取りでもシャドウを優先**します。インストーラは「キーに値を書く → 開き直して その値を読んで検証/続行」という動作を多用するため、ここで実レジストリを読んで しまうと自分の書いた値を見失い、同じ処理を延々リトライして最終的にエラー終了 します。シャドウ優先の読み取りでこの不整合を防ぎます(捕捉していないシステム キー/ファイルは実体を読みます)。 ### COM/コーデック登録は実レジストリを参照(動画再生などの対応) DirectShow(ActiveMovie)で動画(例: オープニングの `OP.DAT`)を再生するアプリは、 `HKCR\Media Type` や `HKCR\CLSID` を読んで対応フィルタ/コーデックを探します。 これらをシャドウへ逸らすと実体のコーデック登録が見えず「ファイルが開けません」に なります。そこで COM/コーデック/DirectX 系のシステムキー (`CLSID` / `Media Type` / `DirectShow` / `Direct3D` / `DirectInput` ほか)は、 **明示的な書き込み以外(読み取り・`MAXIMUM_ALLOWED`)では実レジストリへ素通し** します(実ハンドルを返すのでサブキー列挙も実体を参照)。インストーラが明示的に 行う COM 登録は従来どおりシャドウへ捕捉します。 ### 「開くだけ」でキーを作らない(インストール状態の誤判定を防ぐ) `RegOpenKeyEx` は存在しないキーに対しては失敗するのが正しい挙動で、キーを 作ってはいけません(キーを作るのは `RegCreateKeyEx`)。`MAXIMUM_ALLOWED` 等で 開いた際にシャドウキーを新規作成してしまうと、**本来未インストールのソフトが 「インストール済み」に見えてしまいます**(例: AutoRun が `...\Uninstall\ ` を開いて「インストール/アンインストール」表示を切り替える 場合)。本ツールは、書き込み目的の open でも「シャドウに既にある/実キーが 存在する」場合のみシャドウを返し、どちらも無ければ実APIと同じく `FILE_NOT_FOUND` を返します(実際の作成は `RegCreateKeyEx` のフックが担当)。 ### レジストリ(シャドウキー方式) フック中の `RegCreateKeyEx` / `RegOpenKeyEx`(A/W)を捕捉し、 `HKLM\Software\...` などへの **書き込み** を `HKCU\Software\DoNotInstaller\Shadow\ \HKLM\Software\...` へ透過的に付け替えます。返すハンドルはシャドウ側の実ハンドルなので、以降の `RegSetValueEx` / `RegQueryValueEx` / `RegEnumKey` などは無改変で動作します。 書き込みのために既存キーを開いた場合は、そのキーの値をシャドウへ複製してから 渡すので(key-level copy-on-write)、「開いて読んでから書く」コードも壊れません。 取り込み終了後にホストがこのシャドウ部分木を `dni.reg`(regedit 互換・UTF-16)へ 書き出し、シャドウキー自体は削除します。 #### 書き出し時に「実レジストリと同じ値」を除外(dni.reg のノイズ削減) インストーラは、システムキー(`HKLM\Software\Microsoft\Windows\CurrentVersion`、 HKCR のファイル関連付け、IE 設定など)を**読み取り目的で `KEY_WRITE`/ `MAXIMUM_ALLOWED` 付きで開く**ことが多く、上記の copy-on-write で実レジストリの 値がシャドウへ複製されます。これらは整合性維持には必要ですが、そのまま書き出すと ゲームと無関係な大量のキーが `dni.reg` に残ってしまいます。 そこで**書き出し時に、各値を実レジストリの同名値と比較し、型・バイト列が一致する もの(=複製されただけで変更されていない)を除外**します。あわせて、実レジストリに 既存で、残す値を1つも持たない中間キーも出力しません(