2009-06-17 16 views
6

Windowsターゲット展開でMicrosoft Visual Studio 2008を使用しています。どのようにしてファイルを「自分自身を更新する」ようにしますか?私はすでに "ネットワーク経由での送信"を行っていますが、実行可能ファイルを自分自身に書き込むにはどうすればいいですか?ファイルを自己更新する方法(ネイティブC++)

基本的には、自動アップデータも含まれているディレクトリの自動アップデータを作成したいのですが、アップデータはディレクトリ内のすべてを更新する必要があります。

ファイルのロックが解除されるまで、ファイルへの変更を保留する方法が役立つかもしれません。もし私がそれをやろうとすれば、私はおそらくそれをホットパッチで追跡するだろう。

+0

可能なデュープ:http://stackoverflow.com/questions/250175/writing-my-own-auto-updater – crashmstr

+1

ないだまされやすい人は、これは特にNATIVE C++です。 –

答えて

5

新しい実行ファイルを作成し、古いファイルのコピーを削除または保存してください。ネットワーク経由でdiffを送信して、更新プログラムや更新プログラムなどを適用して適用することができます。それは、アップデートが利用可能であることを認識したときにリモートアプリケーションから開始できる小さなスクリプトにすぎません。アップデータは$ UPDATER_OLD_VERSIONなどに名前を変更して、適切な名前の更新されたコピーを作成し、新しいアップデータが実行されると、$ UPDATER_OLD_VERSIONという名前のファイルがアプリディレクトリにあるかどうかを確認して削除できます。その他のファイルはすべて更新/上書きできます。

+0

その解決策は私にとってはあまりにも面倒です。私はむしろ "一時的なデータ"を浮かべていないだろう。途中でコンピュータがクラッシュした場合はどうなりますか? –

+3

@wowus - 実際のexeファイルを上書きするより一時的なデータを書き込むほうがはるかに優れています。さらに、修正は簡単です:一時ファイルに書き込み、MoveFileを呼び出して最終的な場所に配置します。同じボリューム上では、MoveFileはアトミックなので、クラッシュが矛盾した状態になることはありません。 – Michael

+0

SoloBoldの提案は、この種のことが一般にどのように行われるかです。更新しているアプリケーションは更新できません。あなたが言うように、コンピュータが途中でクラッシュするとどうなりますか? –

2

私はInnoSetup setup.exeを使ってこれを行います。これはサイレントモードで起動し、新しいファイルのインストールを開始する前にアプリケーションをシャットダウンします。カスタムPascal [Code]セクションを追加して、すべてがシャットダウンされるようにしなければならなかったが、それは仕事だった。

+0

デバイスドライバを作成したり、OSをハッキングしたりするのに手間がかからないので、このようなスキームが唯一の方法だと思います。 Windows上で実行可能ファイルを実行すると、OSはそのファイルを開いたままにしてロックを保持します。 –

3

通常、アプリが実行中に変更することはできません。 は、元のプログラムを閉じて別の場所から変更する必要があります。

2

実行中にファイルを上書きすることはできませんが、名前を変更することはできます。私のアップデータでは、既存のexeファイルの名前を意味のあるもの(oldname_dateandtime)に変更し、新しいコピーを書き込みます。その後、システムを自動的にシャットダウンし、サービスから再起動します。アプリが起動すると、新しいバージョンが実行されます。

+0

私は同じことをし、起動時に古いバージョンを削除します。 –

+0

私たちはフィールドサービスエンジニアが問題の場合に元に戻すことができるように、古いものを迂回します。もちろん、私たちはフィールドサービスエンジニアの贅沢を持っています:-)。古いバージョンは次回のアップグレード時に削除されます。 –

0

私がアップデータを作ったとき、私はいくつかのプログラムを分けなければなりません。主な理由は、あなたがしたいこととまったく同じでした。 Bはターゲットアプリケーションを更新します。 AとAはBを更新します。 別の方法を見つけようとしましたが、私がやったのは、より小さなシンプルなアップデータでした。 :(

0

私は、ファイルのバージョンとアップデータについて話していると思います。 あなたはあなたがあなたのインストールディレクトリを監視し、サーバとディスク上のファイルのバージョンを比較してサービスを作成する必要がautoupdater.Soを必要と言ったように。

サーバから最新のデータを尋ねることができます。置き換えようとしているファイルが使用中の場合は、次回の再起動時に削除/登録解除にマークを付けてレジストリを使用して記入する必要があります。キャッシュ内のすべてのファイルは再起動時にコピーされ、インストールディレクトリにコピーされます。

4

これは私が最近した方法です。実行中の古いプログラムと新しいプログラムの実行が少し重なっています。それは、あなたが現在の実行可能ファイルの名前を変更して、古いファイルをシャットダウンする前に新しいファイルをその場所に持っていくことができるというトリックを利用します。これは100%のフェイルセーフではありませんが、CopyFileが失敗した場合にアプリケーションが「レンガ」する可能性がある唯一の方法です。

#include <windows.h> 
#include <iostream> 
#include <fstream> 

void UpgradeService::UpgradeSelf() { 

    std::string temp = root   + "\\myprogram_tmp.exe"; 
    remove(temp.c_str()); // ignore return code 

    std::string src = upgradeFolder + "\\myprogram.exe"; 
    std::string dst = root   + "\\myprogram.exe"; 


    rename(dst.c_str(),temp.c_str()); 
    CopyFile(src.c_str(),dst.c_str(),false); 
    static char buffer[512]; 
    strcpy(buffer,dst.c_str()); 

    /* CreateProcess API initialization */ 
    STARTUPINFO siStartupInfo; 
    PROCESS_INFORMATION piProcessInfo; 
    memset(&siStartupInfo, 0, sizeof(siStartupInfo)); 
    memset(&piProcessInfo, 0, sizeof(piProcessInfo)); 
    siStartupInfo.cb = sizeof(siStartupInfo); 

    ::CreateProcess(buffer, // application name/path 
    NULL, // command line (optional) 
    NULL, // no process attributes (default) 
    NULL, // default security attributes 
    false, 
    CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE, 
    NULL, // default env 
    NULL, // default working dir 
    &siStartupInfo, 
    &piProcessInfo); 


    ::TerminateProcess(GetCurrentProcess(),0); 
    ::ExitProcess(0); // exit this process 

    // this does not return. 
} 
関連する問題