1

C# で記述されたユーザーのタスク バーにある UI アプリケーションがあります。ツールの EXE は、それを使用する多くのプロジェクトのソース管理システムにチェックインされているため、更新された EXE をチェックインすることで、実行するバージョンを更新できます。

問題は、ユーザーが exe の最新リビジョンを取得すると、プログラムが頻繁に実行され、マシンで同期が失敗することです。プログラムが実行時にexeと依存DLLをロックしないように修正して、プログラムをシャットダウンせずに同期できるようにします。

現在、実行可能ファイルをパラメーターとして受け取り、事前にアセンブリの内容をメモリに読み込んでメモリから起動するプログラムがあります。残念ながら、プログラムが必要とする DLL に関しては、これは完全に失敗します。

私が今持っているコードは次のようになります。

public class ExecuteFromMemory
{
    public static void Main(string[] args)
    {
        //Figure out the name of the EXE to launch and the arguments to forward to it
        string fileName = args[0];
        string[] realArgs = new string[args.Length - 1];
        Array.Copy(args, 1, realArgs, 0, args.Length - 1);

        //Read the assembly from the disk
        byte[] binary = File.ReadAllBytes(fileName);

        //Execute the loaded assembly using reflection
        Assembly memoryAssembly = null;
        try
        {
            memoryAssembly = Assembly.Load(binary);
        }
        catch (Exception ex)
        {
            //Print error message and exit
        }

        MethodInfo method = memoryAssembly.EntryPoint;
        if (method != null && method.IsStatic)
        {
            try
            {
                method.Invoke(null, new object[] { realArgs });
            }
            catch(Exception ex)
            {
                //Print error message and exit
            }
        }
        else
        {
            //Print error message and exit
        }
    }
}

私の質問は、私はまったくばかげたことをしているのでしょうか? これを処理するより良い方法はありますか?そうでない場合、外部依存関係の処理をサポートするにはどうすればよいですか?

たとえば、上記のコードは、「Bar.dll」の関数を使用する「Foo.exe」を実行しようとすると、依存ファイルのロードに失敗します。「Foo.exe」は上書き可能になりますが、「Bar.dll」は依然としてロックされ、上書きできません。

ロードされたアセンブリの 'GetReferencedAssemblies()' メソッドから参照アセンブリのリストを取得しようとしましたが、アセンブリがどこからロードされるべきかを示すものではないようです...自分でそれらを検索する必要がありますか? もしそうなら、これを行う最善の方法は何ですか?

他の人が以前にこれに遭遇した可能性があるようで、私は車輪を再発明したくありません.

- 更新: EXE がチェックインされているのは、社内ツールを使用するチームに社内ツールを配布するためです。このユースケースには最適ではありませんが、そのポリシーを変更する機会はありません。

4

3 に答える 3

4

免責事項: 私は Windows を使用していませんが、物事をロックする奇妙な方法には慣れています。

実行中にアプリケーションを更新するには、実行可能ファイル自体と、更新プロセスを完了する更新「ヘルパー」アプリケーションの 2 つのプロセスが必要になる可能性があります。アプリケーションが ProcessA.exe で、更新ヘルパーが Updater.exe であるとします。メイン プログラムは実行可能ファイルの新しいコピーをダウンロードし、ランダムな名前で保存します。次に、現在のプロセスの終了を監視するアップデータ プログラムを実行します。プロセスが終了すると、更新のステータスを示すクイック ウィンドウが表示され、新しい実行可能ファイルが古い実行可能ファイルの場所に移動され、そのプログラムが再起動されます。

POSIX ファイルシステムのセマンティクスをエミュレートし、現在実行中のプロセス ディスク イメージを削除して新しいファイルに置き換えることができればよりエレガントですが、それが Windows でも可能かどうかはわかりません。POSIX システムでは、使用中のファイルを削除できますが、残りのファイル ハンドルが閉じられるまで実際には削除されませんが、ファイル名を再利用することはできます。

このことについて言及しているCodeProjectで書かれた記事をチェックしてみてください。フォローアップ記事もあります。

幸運を!

于 2009-02-27T16:47:21.857 に答える
1

更新中にプログラムを実行し続ける必要がありますか?

通常、実行中のプログラムを更新するには、置き換えるファイルを一時フォルダーにコピーします。次に、古いインスタンスをシャットダウンして削除し、新しいファイルを正しい場所に移動してから、再起動します。

通常、最も長い部分はコピーであり、一時フォルダーが同じ論理ドライブ上にある場合、ファイルの移動は非常に高速であるため、これによりアプリケーションのダウンタイムを最小限に抑えることができます。

于 2009-02-27T16:46:47.083 に答える
0

Michael の答えはこれを行う 1 つの方法ですが、デスクトップにインストールされているものを明示的に管理するためのツールが世の中に存在します。

ソース管理にチェックインされている exe で行っていることは正常ではありません。Windows ドメイン コントローラを使用している場合は、グループ ポリシーを使用してプログラムをクライアントにプッシュできます。または、Altiris などを使用して処理することもできます。

進むべき道を歩み続けなければならない場合、選択肢は 2 つあります。1 つ目は、起動時にバージョン チェックを行うヘルパー/ローダー アプリを使用することです。これは、Firefox の動作に似ています。

2 つ目の方法は、メモリ内に常駐し、頻繁に更新をポーリングするヘルパー サービスを構築することです。これは、Google Chrome、Adobe などの仕組みです。

于 2009-02-27T17:53:00.777 に答える