web-dev-qa-db-ja.com

C ++バイナリはどのようにそれ自体を置き換えることができますか?

この質問をしました 以前のより一般的な設計コンテキストで。それでは、具体的な内容についてお話したいと思います。

_app.exe_を実行していると想像してください。 _update.exe_を同じフォルダにダウンロードします。 _app.exe_は_update.exe_の内容を_app.exe_にどのようにコピーしますか?私は特にC++のコンテキストで質問しています。ある種の3番目のメディエーターアプリが必要ですか?ファイルロックについて心配する必要がありますか?バイナリ更新自体への最も堅牢なアプローチは何ですか(極端なファイル権限を持つ不快なITスタッフを除く)?理想的には、ポータブルソリューション(Linux + OSX)が欲しいのですが、Windowsが主なターゲットです。

29
TheBuzzSaw
  1. 実行中のapp.exeapp_old.exeに移動/名前変更します
  2. ダウンロードしたupdate.exeapp.exeに移動/名前変更します
  3. アプリケーションの次回の起動時に、更新が使用されます

実行中の名前の変更、つまりロックされたdll/exeは、Windowsでは問題になりません。

42
nabulke

これはオペレーティングシステムの機能であり、C++の機能ではありません。
どのOSを使用していますか?

Windowsでは MoveFileEx() 関数を参照してください。Linuxでは実行中のアプリを上書きするだけです( Linuxで実行中の実行可能ファイルを置き換える

9
Martin Beckett

Linuxでは、実行中のプログラムの実行可能ファイルを削除することができます。したがって、次のようになります。

  • ダウンロードapp.exe~
  • 実行中の削除app.exe
  • 名前の変更app.exe~からapp.exe

Windowsでは、実行中のプログラムの実行可能ファイルを削除することはできませんが、名前を変更することはできます。

  • ダウンロードapp.exe~
  • 実行中の名前を変更しますapp.exeからapp.exe.old
  • 名前の変更app.exe~からapp.exe
  • 再起動時にremoveapp.exe.old
9

Windowsでは、少なくとも実行中のアプリケーションが、独自の.exeファイルと静的にリンクされたすべての.dllファイルをロックしています。これにより、アプリケーションが直接更新されるのを防ぎます。再起動を防止したい場合は、リードで(再起動がOKの場合、アプリはMOVEFILE_DELAY_UNTIL_REBOOTフラグをMoveFileExに渡すことができ、独自の「上書き」を自由に行うことができます。とにかく遅れているように、.exe)。これが、通常、アプリケーションが独自の.exeで更新をチェックしない理由ですが、更新をチェックするシムを起動してから、「実際の」アプリケーションを起動します。実際、「シム」は、適切に構成されたマニフェストファイルのおかげで、OS自体によっても実行できます。 Visual Studioで構築されたアプリケーションは、これをプレハブウィザードパッケージツールとして取得します。 Visual C++アプリケーションのClickOnceデプロイメント を参照してください。

OSにはさまざまな種類があるため、一般的なLinuxアプリはそれ自体を更新しません。ほとんどのアプリはソースとして配布され、あるバージョンのauto-hellを介して実行され、自己構成してビルドされ、make installを介してインストールされます(これらはすべてパッケージの背後で自動化できます)。 Linuxの特定のフレーバーのバイナリとして配布されているアプリでさえ、自分自身をコピーするのではなく、新しいバージョンを並べてインストールしてから、 symbolic link を 'に更新します。新しいバージョンをアクティブ化します(ここでも、パッケージ管理ソフトウェアがこれを非表示にする場合があります)。

OS Xアプリは、Posixフレーバーの場合はLinuxバケットに分類されるか、最近では更新を処理するMacAppStoreアプリバケットに分類されます。

独自の自己更新をローリングしても、これらのテクノロジ(ClickOnce、RPM、AppStore)のいずれも洗練されたものにはならず、検出、アップグレード、およびアンインストールに対して期待される動作をユーザーに提供できると思います。私はフローに沿って、それぞれのプラットフォームでこれらのテクノロジーを使用します。

2
Remus Rusanu

「再起動」の問題を克服するための単なるアイデア。更新の必要がないプログラムを作ってみませんか。プラグイン構造に実装するだけなので、プログラムに必要なすべての機能を備えた.dllファイルをロードし、そこでメイン関数を呼び出すのは更新ホストだけです。更新を検出すると(おそらく別のスレッドで)、dllハンドルに閉じるように指示し、ファイルを置き換えて、新しいファイルをロードします。このようにして、アプリケーションはそれ自体を更新している間も実行を続けます(dllファイルのみが再ロードされますが、アプリケーションは実行を続けます)。

2
Noxoreos

他の多くのアプリと同様に、アップデーターの3番目の実行可能ファイルを使用します。

  • 新しいバージョンをダウンロードします。
  • アップデーターをスケジュールして、アプリを新しいバージョンに置き換えます。
  • メインアプリを閉じます。
  • アップデータが実行され、作業が行われます。
  • アップデータは、アプリの新しいバージョンを実行します。
  • アップデータが終了します。
0
frogatto