Skip to content

About

ゲームのインストール&実行時のフォルダアクセスやレジストリ制御を単一フォルダに閉じ込めて、ポータブル化するための支援ツール

Resources

Stars

35 stars

Watchers

0 watching

Forks

Repository files navigation

DO-NOT-INSTALLER

インストーラを ドラッグ&ドロップ で投げ込むと、そのインストーラがシステムへ 行う変更(レジストリ書き込み・インストールフォルダ以外へのファイル書き込み)を 横取りして 1 つのフォルダの中だけ に閉じ込め、フォルダをコピーするだけで 別 PC でも動く ポータブル版 を自作するツールです。

  • レジストリ書き込み → フォルダ内のテキストファイル dni.reg に保存
  • フォルダ外へのファイル書き込み → フォルダ内の files\ 以下に保存
  • 実行に必要な「フックツール」もフォルダ内に配置

実行時(ポータブル版の起動時)は、dni.reg を一時的な退避先レジストリに復元 → アプリ起動 → 終了時に変更を dni.reg に書き戻して退避先を削除します。 したがって 実レジストリは最終的に汚れません。ファイルアクセスも同様に files\ 以下へリダイレクトされるため、C:\ProgramData や C:\Program Files を 汚しません。

商用の ThinApp / Cameyo / Enigma Virtual Box などと同系統の「アプリ仮想化 (ポータブル化)」ツールです。自分で用意したインストーラを、自分の PC 用に ポータブル化する用途を想定しています。


仕組み

┌──────────────────────┐        起動(suspended)+DLL注入
│ DoNotInstaller.exe   │ ───────────────────────────────▶  installer.exe(フック済み)
│ (ホスト本体)       │                                      │  │
└──────────────────────┘                                      │  └─ 子プロセス(msiexec等)にも自動注入
        ▲                                                     │
        │ ジョブオブジェクトでプロセス木の終了を待機          ▼
        │                                           ┌──────────────────────┐
        │                                           │ DNIHook64/32.dll      │
        │                                           │  Reg*  → シャドウキー │
        │                                           │  File* → files\ へ    │
        │                                           └──────────────────────┘
   終了後:シャドウキーを dni.reg に書き出し → シャドウキー削除 → EXE を検出

レジストリ内のインストールパスを「吸収」する(実行時)

多くのゲーム/アプリは、レジストリに記録した絶対インストールパス (例: 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\<パッケージID>\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つも持たない中間キーも出力しません(regedit はインポート時に 親キーを自動生成するため問題ありません)。結果として、dni.reg には インストーラが実際に新規作成・変更したキー/値だけが残ります。 ※新規キー(実レジストリに存在しない)や、実在値と異なる値はすべて保持します。

フックするファイル API

CreateFile(A/W)や CopyFile*・MoveFile* に加え、古い・独自系インストーラが 多用する次の API も捕捉してリダイレクトします。

  • SHFileOperation(A/W): シェル経由の一括ファイルコピー/移動。古いゲーム インストーラ等が本体ファイルの大量コピーに使うため、ここを捕捉しないと 「指定フォルダは空のまま、実フォルダへコピーされる」状態になります。
  • OpenFile: レガシーなファイル作成 API(OF_CREATE 等)。 ※ OpenFile は仕様上パス長が約 128 文字までのため、ポータブル用フォルダの パスが長いと失敗することがあります。取り込み時は短いパスの出力先 (例: C:\dni\<名前>)を選ぶと安全です。
  • レジストリも RegCreateKey/RegOpenKey(Ex なしのレガシー 2/3 引数形)を追加で 捕捉します。

ファイル

フック中の CreateFile / CreateDirectory / DeleteFile / MoveFile / CopyFile / GetFileAttributes 等(A/W)を捕捉し、パッケージフォルダの外への 書き込みを files\ 以下へリダイレクトします。

本来の書き込み先 実際の保存先
C:\ProgramData\ABC\x.ini <root>\files\ProgramData\ABC\x.ini
C:\Program Files\ABC\app.exe <root>\files\Program Files\ABC\app.exe
C:\Users\me\AppData\Roaming\ABC\.. <root>\files\Users\me\AppData\Roaming\ABC\..
D:\foo\bar.dat <root>\files\_drives\D\foo\bar.dat

仕様書の例では C:\installpath\ProgramData\ABC\ でしたが、本ツールは dni.reg / dni.ini / DLL 群と混ざらないよう仮想ファイルを files\ の下に まとめています(1 階層増えるだけで意味は同じです)。

子プロセス追従(多段インストーラ対応)

setup.exe が別の EXE を呼ぶ、msiexec.exe /i xxx.msi を起動する、といった 多段構成に追従するため、次のプロセス起動 API を捕捉し、ビットネスを判定して 対応する DLL を自動注入します(64bit ↔ 32bit のクロスビットは、もう一方の ホスト EXE を注入ヘルパとして使用)。

  • CreateProcessW / CreateProcessA / CreateProcessAsUserW
  • ShellExecuteExW(インストーラが「次の段を管理者で起動」する際によく使う)

一時フォルダ(%TEMP%)は実ディスクのまま

自己展開型インストーラ(最近の InstallShield 2010〜/v16 など、setup.exe が %TEMP% に自分を展開してからそこで動くタイプ)に対応するため、%TEMP% / %TMP% / Windows\Temp / LocalAppData\Temp への書き込みはリダイレクトせず、 実ディスクのままにしています。ここを files\ に逸らすと、展開した実行ファイルが 本物の一時フォルダに存在せず「見つからない」でクラッシュするためです。一時 フォルダはスクラッチ領域であり、アンインストールが必要な痕跡ではありません (本来の書き込み先=Program Files・レジストリ・AppData 等は従来どおり捕捉します)。

「アンインストールが必要な痕跡」を残さない

「プログラムと機能」への登録(...\Microsoft\Windows\CurrentVersion\Uninstall\)、 自動起動(...\CurrentVersion\Run)、スタートメニュー/デスクトップの ショートカット(.lnk)は、いずれも他の書き込みと同様に シャドウ側 (dni.reg / files\)へリダイレクト されます。したがって、正しく注入 できている限り実機には登録・作成されず、アンインストール作業は不要です。

また、.lnk をレガシー API(OpenFile+_lwrite 等)や長いパスで書き込む インストーラ対策として、取り込み完了時にスタートメニュー/デスクトップ等の 実フォルダを走査し、取り込み中に作られたショートカットをパッケージの files\ へ回収して実機側を削除します(取り込み開始時刻以降の *.lnk のみが対象で、 無関係な項目には触れません)。

さらに取り込み完了時に、ホストが 実機のレジストリを読み取り専用でチェック し、取り込んだ「プログラムと機能」登録・自動起動エントリと同一のものが実機に 残っていないかを照合します(フックできないプロセスが書き込んでしまった場合の 検知)。残っていた場合は、完了メッセージと dni.log に該当箇所を表示します (誤削除を避けるため自動削除はしません。表示された場所を手動で削除してください)。

16bit(古い)インストーラへの対応

64bit Windows には 16bit 実行環境(NTVDM)が無いため、Windows 3.x 時代の 16bit インストーラ(InstallShield 3〜5 世代の SETUP.EXE など)は起動できません。 そこで投入されたファイルの EXE ヘッダ(NE/PE)を判定し、16bit だった場合は 次の2段構えで取り込みます。

  1. 方式1(32bit エンジンで起動):同じフォルダに InstallShield の 32bit 起動ファイル(Setup32.exe、無ければ PE32 の setup*/install*)があれば、 それをフック下で起動して通常どおり取り込みます。32bit 起動ファイルが無くても、 InstallShield 5 系なら圧縮された 32bit エンジン INSTALL.EXE(_INST32I.EX_ 内)を展開して、16bit SETUP.EXE の代わりに起動します(同梱の IS32Setup と 同じ仕組み。tools/is32setup/ 参照)。

  2. 方式2(CAB 展開 + ルースファイル復元):方式1 が無い/何も取り込めなかった 場合、フォルダ内の InstallShield CAB(data1.cab / _sys1.cab / _user1.cab / *1.cab)を同梱の unshield で files\_extracted\ へ展開します。 さらに、CAB が索引のみで本体データを持たない配布形態(本体が配布フォルダ直下に 難読化された状態で置かれているタイプ)に対応するため、CAB の索引(ファイル名・ サイズ)を手がかりに、配布フォルダのルースファイルから実体を復元します (InstallShield 難読化は自動で解除)。これにより、CAB 展開で 0 バイトに なってしまうファイルも実体を取り出せます。この方式ではレジストリ設定は 取り込めません(ファイルのみ)。

  3. 方式3(MSI 管理インストール展開):Windows Installer(.msi)パッケージ ——例: InstallShield の MSI ブートストラッパ(Setup.ini に PackageName=xxx.msi)——は、実体の書き込みを msiexec サービス(SYSTEM) が行うため捕捉が困難です。そこで後段サポートとして、見つかった MSI に対し 管理インストール(msiexec /a <msi> /qn TARGETDIR=...)を実行し、 パッケージのファイルツリーを files\_msi\ にシステム無改変で展開します (レジストリ/サービス/COM 登録/カスタムアクションは実行しません)。 ライブ捕捉で何も取れない場合でも、少なくとも中身のファイルは取り出せます。

    MSI の注意:COM 登録・サービス・ライセンス認証・Windows Installer の 製品DB(self-heal)などシステム統合に依存する市販アプリは、展開できても ポータブルでは動かないことが多いです(DNI の不具合ではなくアプリの性質)。 「ファイルだけでも取り出したい」場合の手段と考えてください。

方式1→失敗時に方式2へ自動で切り替わり、方式2・方式3はいずれも後段サポートとして 補助的に実行されます。取り込み後、起動したい EXE を dni.ini の target に 設定してください。

「16bit インストーラ対策」チェックボックス(通常オン)

成功率をさらに上げるため、ウインドウに 「16bit インストーラ対策」 の チェックボックス(既定でオン)を用意しています。オンのまま取り込むと、 DO-NOT-INSTALLER が自動で次を行います。

  1. インストーラのフォルダ一式を書き込み可能な作業用フォルダ(%TEMP% 配下) へ丸ごとコピーします(元のメディア/フォルダは一切変更しません。CD-ROM など 読み取り専用メディアでも動くようにするためのコピーです)。
  2. コピー先を再帰的に走査し、16bit(NE 形式)の setup* / install* / inst.exe を、同梱の 32bit 版 IS32Setup.exe と同名で差し替えます (元の 16bit 版は <名前>.16.exe として隣に退避)。これにより、AutoRun や メニューのボタン、ユーザーのダブルクリックなどどの経路から setup.exe が 呼ばれても 32bit エンジンが動くようになります。
  3. 差し替え後のコピーをフック下で取り込み、終了時に作業用フォルダを自動削除します。

ユーザーが手作業で setup.exe を差し替える必要はありません(DO-NOT-INSTALLER が 自動で行います)。差し替え対象が無い場合でも、作業用フォルダへのコピーだけは行う ため、読み取り専用メディアや書き込み保護されたフォルダからの取り込みが安定します。 不要な場合はチェックを外せば、従来どおり元の場所のインストーラをそのまま取り込みます。

同梱の IS32Setup.exe は DoNotInstaller.exe と同じフォルダに置いてください (配布 zip ではすでに同梱済み)。見つからない場合は差し替えをスキップし、 作業用フォルダへのコピーのみ行います。 コマンドラインからは --capture <installer> <出力先> が既定でこの対策オン、 --capture <installer> <出力先> --no-fix16 でオフになります。

「エンジンの起動に失敗しました(エラー 193)」への対応(修正済み)

InstallShield 5 系の 32bit エンジン INSTALL.EXE は、実体は 32bit PE なのに PE ヘッダの Characteristics に IMAGE_FILE_DLL(0x2000) ビットが立った 「実行可能DLL」形式(例: 0x210E)になっていることがあります。現代の Windows は DLL フラグ付きイメージの CreateProcess を拒否し、エラー 193 (ERROR_BAD_EXE_FORMAT) を返します。本ツールはエンジン展開時に、起動対象の *.EXE に限って PE の IMAGE_FILE_DLL ビットを自動でクリアしてから起動するように しました(本物のヘルパ DLL はそのまま)。IS32Setup 経由・DNI 本体の方式1経由の どちらでも適用されます。「ゆきのかなた」等でこのエラーが出ていたケースが対象です。

注意:この年代のソフトは Windows 9x 専用の VxD ドライバ(*.DRV/*.VXD、 LE 形式) に依存していることがあります。VxD は NT 系 Windows では読み込め ないため、ポータブル化できても本来の機能が動かない場合があります。その場合は Windows 98 の仮想マシン(86Box / PCem / VirtualBox 等)が現実的です。 また、CAB が複数ボリューム構成で一部(data2.cab 等)が欠落している配布物は、 方式2でも完全には展開できません。

「16-Bit Install Shield Support\setup.exe が見つかりません」で失敗する系

32bit の InstallShield スタブが、Microsoft の 16bit 補助コンポーネント (C:\Program Files (x86)\Microsoft\16-Bit Install Shield Support\setup.exe)を 起動しようとして、x64 環境には存在しないため失敗するケースです。16bit 実行が 必要なので実行での完走は不可能ですが、この手のインストーラは自己展開の 過程で CAB を一時フォルダ(%TEMP%)に吐き出して います。DO-NOT-INSTALLER は 一時フォルダ書き込みを files\ へリダイレクトしているので、取り込み後に files\ 以下を再帰的に探して CAB を見つけ、自動で展開します(方式2 を 「失敗時のみ」ではなく常に補助的に実行)。これにより、実行が途中でコケても 中身のファイルは取り出せます。ログ(dni.log)には 16bit 補助の起動試行が 記録されます。

別プロセスのインストールエンジンへの対応(MSI / InstallShield)

多くのインストーラは、実際のレジストリ/ファイル書き込みをインストーラ本体 ではなく、別プロセスのエンジンに行わせます。これらはインストーラの子プロセス ではなく、SCM や DCOM が起動するため、プロセス起動フックでは捕捉できません。

  • MSI:msiexec /i のクライアントではなく、SYSTEM で動く **Windows Installer サービス(別の msiexec.exe)**が書き込みます。
  • InstallShield:UI の setup.exe ではなく、DCOM 起動の ikernel.exe(IS5/6 エンジン) や **IDriver.exe(IS の MSI エンジン)**が ファイルをコピーします。これを取りこぼすと、C:\Program Files などに 本物のままコピーされてしまいます(フォルダだけポータブル側に作られる、 という分裂が起きるのはこのためです)。

そこで取り込み中は、ホストがこれらのエンジンプロセス(msiexec.exe / ikernel.exe / IDriver.exe / setup.exe / install.exe 等)を監視し、出現した 時点で自動注入します。注入された DLL は、環境変数を継承しない相手でも設定を 受け取れるよう、ホストが公開する共有メモリ(Global\DoNotInstaller.Config.v1) から構成を読みます。あわせて CopyFileW/A・MoveFileExW/A などコピー系 API も フック対象に含めています。

2段式の独自インストーラ(Will/WillADV など)への対応

Setup.exe(選択UI)→ Install.exe(実コピー)のように、別名の自前 EXE を 2段で呼ぶ独自インストーラ(例: Will/WillADV の Setup.exe→Install.exe)にも 対応しました。これらはマニフェストに昇格指定が無く、ファイル名に setup/install を含むため、Windows のインストーラ検出(UAC)で昇格起動されます。すると内側の Install.exe が AppInfo サービス経由で起動され、プロセス起動フックを素通りする ことがあります。対策として、監視対象に install.exe / _install.exe を追加し、 さらに ShellExecuteExA(ANSI 版、Setup.exe が Install.exe を呼ぶ経路)も フック対象に加えました。これにより、実コピーとレジストリ書き込み(InstallDir / InstallSrc / WillInstall 等)を取りこぼさずポータブル側へ取り込みます。

このエンジン注入には管理者権限が必須です(SYSTEM / 別セッションの プロセスを開くため)。MSI・InstallShield 系は必ず 「管理者として実行」 した DoNotInstaller.exe から取り込んでください。非管理者では書き込みを 取りこぼし、本物のフォルダに入ってしまうことがあります。 また、取り込み中に別件の msiexec.exe 等が動いていると巻き込むため、 インストール中は他のインストール操作を避けてください(best-effort な方式です)。


ビルド(Visual Studio)

C++17。外部依存は同梱の MinHook(BSD-2-Clause, third_party/minhook)のみです。 x64 と Win32 の両方をビルドしてください(子プロセス追従に両方必要)。

ソリューションを開く場合(Visual Studio 2026)

  1. DoNotInstaller.sln をダブルクリックして開く。
  2. 「ソリューションの再ターゲット」ダイアログが出たら OK(プラットフォーム ツールセットと Windows SDK が、インストール済みの最新版に揃います。本 .sln は v143 を既定にしていますが、VS2026 側の v14x へ自動で引き上げられます)。
  3. 構成を Release / x64 にして「ソリューションのビルド」。続けて Release / Win32 でもビルド。
  4. 4 ファイル(DNIHook64.dll DNIHook32.dll DoNotInstaller.exe DoNotInstaller32.exe)が bin\ に揃います。そのまま使えます。

ソリューションには 2 プロジェクト(DNIHook=フックDLL、DoNotInstaller=ホスト) が含まれ、MinHook と共通コードは各プロジェクトに直接取り込んでいるので、 プロジェクト参照や別途ライブラリのビルドは不要です。 Open Folder(CMake)で開く場合は同梱の CMakePresets.json(x64 / x86)が 使えます。

CMake を使う場合(コマンドライン)

:: 64bit
cmake -S . -B build\x64 -A x64
cmake --build build\x64 --config Release

:: 32bit
cmake -S . -B build\x86 -A Win32
cmake --build build\x86 --config Release

生成物(ソリューション/CMake どちらでも同じ):

構成 生成されるファイル
x64 DNIHook64.dll, DoNotInstaller.exe
Win32 DNIHook32.dll, DoNotInstaller32.exe

この 4 ファイルを同じフォルダ に集めて使ってください(ソリューションの場合は bin\ に自動で揃います)。

MinGW-w64 を使う場合(任意)

./build_mingw.sh      # build-mingw/ に 4 ファイルを生成

本リポジトリの Linux 側では、この MinGW クロスビルドでコンパイル・リンクの 確認まで行っています。実機 Windows での動作確認は未実施 です。


使い方

1. ポータブル版を作る(取り込み)

  1. ビルドした 4 ファイルが揃ったフォルダの DoNotInstaller.exe を起動。
    • 管理者権限を要求するインストーラの場合は 「管理者として実行」 で起動。
  2. インストーラ(setup.exe / *.msi を実行する .exe 等)を指定します。
    • ウィンドウに ドラッグ&ドロップ、または
    • 「ファイルを選択...」ボタン から選択。
    • ※「管理者として実行」した場合、Windows の仕様(UIPI)で非管理者の エクスプローラからの ドラッグ&ドロップは効きません。その場合は 「ファイルを選択...」ボタンを使ってください。
  3. 出力先フォルダを選択(既定は <インストーラ名>_portable)。
  4. インストーラがいつも通り起動するので、普段どおりインストール します (インストール先はデフォルトのままで構いません。C:\Program Files\... への 書き込みも自動的に files\ へ取り込まれます)。
  5. インストーラ(と全子プロセス)が終了すると取り込み完了。フォルダに以下が 出来ます。
<root>\
├─ DoNotInstaller.exe      ← これをダブルクリックするとアプリが起動(ランチャー)
├─ DoNotInstaller32.exe
├─ DNIHook64.dll / DNIHook32.dll
├─ dni.reg                 ← 取り込んだレジストリ(テキスト)
├─ dni.ini                 ← パッケージ設定(起動するEXE等)
├─ dni.log                 ← ログ(log=1 のとき)
└─ files\                  ← 取り込んだファイル一式(仮想ファイルシステム)

2. ポータブル版を起動する

<root>\DoNotInstaller.exe を ダブルクリック。dni.ini が隣にあると ランチャーとして動作し、dni.reg を退避先へ復元してからアプリを起動します。 終了時に変更を dni.reg へ書き戻し、退避先レジストリを削除します。

別 PC へは フォルダごとコピー するだけです。

3. 起動する EXE を調整する

取り込み後、メイン EXE は自動推定して dni.ini の [launch] target に設定され ますが、外れることもあります。その場合は dni.ini をテキストエディタで開き、 [candidates] の一覧から正しいものを target= に設定してください(<root> からの相対パス)。

[launch]
target=files\Program Files\ABC\app.exe
workdir=
args=
log=0

制限事項(重要)

  • 実機 Windows での動作確認は未実施です。コンパイル・リンクの確認のみ。 まず小さな単純アプリで検証してください。
  • プロテクト/アクティベーション/DRM/アンチチートのあるソフトは対象外です。 DLL 注入・API フックを検知してブロック・誤作動する可能性が高いです。
  • API フックは advapi32 / kernel32 の公開 API レベルです。ntdll の Nt* / Zw* を直接呼ぶ特殊なインストーラ・ランタイムは捕捉できません。
  • ファイル列挙(FindFirstFile)の実/仮想マージは未実装です。アプリが ディレクトリ列挙で自分のファイルを探す場合、実体が files\ にあるので通常は 問題ありませんが、実システム側と混在して列挙する挙動は再現しません。
  • COM 登録・サービス・ドライバ・スケジュールタスク・環境変数(PATH)等の システム統合はレジストリ/ファイルの範囲でしか再現しません。これらに依存 するアプリはポータブル化できないことがあります。
  • .NET / MSIX / ストアアプリや、ランタイム(VC++ 再頒布可能パッケージ、 .NET ランタイム等)の別途インストールを前提とするアプリは、そのランタイムが コピー先 PC に無いと動きません。
  • 明示的な環境ブロックを渡す子プロセスのうち ANSI 環境ブロックのものには DNI_* 設定を注入できず、フック対象外になります(Unicode 環境ブロックは対応)。
  • DllMain 内で MinHook を初期化しているため、極めてまれにローダーロック絡みの 不具合があり得ます(注入直後はほぼ単一スレッドのため実用上は問題になりにくい)。
  • \\?\ ロングパス・UNC パス(\\server\share)はリダイレクトしません。

トラブルシュート

  • 取り込んでも空に近い → インストーラが管理者権限を要求し起動に失敗している 可能性。「管理者として実行」で再実行してください。
  • 起動するが設定が保存されない → dni.ini の target が実体と違う/files\ に書けていない可能性。dni.log(log=1)でリダイレクト先を確認してください。
  • 何が起きているか見たい → 取り込み時は既定で dni.log に詳細が残ります。 ランチャーでログを取るには dni.ini の log=1 を設定。

ライセンス

  • 本体コード: 自由に利用・改変してください(無保証)。
  • 同梱の MinHook: BSD-2-Clause(third_party/minhook/LICENSE.txt)。
  • 同梱の unshield: MIT(third_party/unshield/LICENSE)。
  • 同梱の zlib: zlib License(third_party/zlib/LICENSE)。
  • 同梱の blast(PKWare DCL 解凍, IS32Setup 用): zlib License(third_party/blast/blast.h)。

About

ゲームのインストール&実行時のフォルダアクセスやレジストリ制御を単一フォルダに閉じ込めて、ポータブル化するための支援ツール

Resources

Stars

35 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages