2

コードの大部分が別のDLLにある自己更新アプリを作成しています。これはコマンドラインであり、最終的にはMonoで実行されます。このコードをコマンドラインのWindowsのC#で機能させようとしています。

実行中にサポートするdllを削除できるac#アプリケーションを作成するにはどうすればよいですか?

AppDomain domain = AppDomain.CreateDomain("MyDomain");
ObjectHandle instance = domain.CreateInstance( "VersionUpdater.Core", "VersionUpdater.Core.VersionInfo");
object unwrap = instance.Unwrap();
Console.WriteLine(((ICommand)unwrap).Run());
AppDomain.Unload(domain);
Console.ReadLine();

ReadLineでは、VersionUpdater.Core.dllはまだ削除からロックされています

ICommandインターフェイスはVersionUpdater.Common.dllにあり、CommandlineアプリとVersionUpdater.Core.dllの両方から参照されます。

4

4 に答える 4

6

私がこれまでに似たようなものを管理した唯一の方法は、DLLを削除しようとしているアセンブリとは別のAppDomainにDLLを配置することです。他のAppDomainをアンロードしてから、DLLをディスクから削除します。

更新を実行する方法を探している場合は、頭のてっぺんから、実際のAppDomainを生成するスタブexeを探します。次に、そのスタブexeは、更新が適用されることを検出すると、他のAppDomainを終了してから、更新マジックを実行します。

編集:アップデーターは、更新しているものとDLLを共有できません。共有しないと、それらのDLLがロックされ、削除されなくなります。これが、まだ例外が発生する理由だと思います。アップデータはスタンドアロンである必要があり、他のAppDomainが使用するものに依存してはなりません。その逆も同様です。

于 2008-10-07T17:15:33.120 に答える
1

自己更新アプリを作成したとき、スタブのアイデアを使用しましたが、スタブはアプリそのものでした。

アプリが起動し、更新を探します。更新プログラムが見つかった場合は、新しいアプリのコピーを一時ストレージにダウンロードし、「更新中です」というコマンド ライン オプションを使用して起動 (System.Diagnostics.Process.Start()) します。その後、元のexeが終了します。

生成された exe が起動し、それが更新であることを確認し、それ自体を元のアプリ ディレクトリにコピーします。次に、その新しい場所からアプリを起動します。その後、生成されたexeが終了します。

元のアプリのインストール場所から新しく開始された exe が起動し、一時ファイルを確認して削除します。その後、通常の実行を再開します。

于 2009-03-08T03:42:30.373 に答える
1

再起動時にいつでもMOVEFILE_DELAY_UNTIL_REBOOT削除できます。これは、この種のことを行うための最もハッキーな方法である可能性が最も高いです。新しいDLLをロードしたり、explorer.exeに注入したり、システムdllにパッチを適用して別のプロセスにロードしたりなど...

MoveFileEx MSDN から;

lpNewFileName [入力、オプション] ローカル コンピューター上のファイルまたはディレクトリの新しい名前。

ファイルを移動する場合、移動先を別のファイル システムまたはボリュームにすることができます。宛先が別のドライブにある場合は MOVEFILE_COPY_ALLOWED、dwFlags でフラグを設定する必要があります。

ディレクトリを移動する場合、移動先は同じドライブ上にある必要があります。

dwFlags が指定され MOVEFILE_DELAY_UNTIL_REBOOT、lpNewFileName がNULLの場合、MoveFileExは、システムの再起動時に削除さ れる lpExistingFileName ファイルを登録します。lpExistingFileName がディレクトリを参照する場合、ディレクトリが空の場合にのみ、システムは再起動時にディレクトリを削除します。

于 2009-05-29T06:48:41.040 に答える
1

Unwrap は、オブジェクトの型のアセンブリを、それを呼び出す appdomain に読み込みます。これを回避する 1 つの方法は、「ベース」アセンブリに command.run を呼び出す型を作成し、それを新しい appdomain にロードすることです。この方法では、別のアセンブリの型からオブジェクトに対して unwrap を呼び出す必要がなく、ディスク上のアセンブリを削除できます。

于 2008-10-07T17:28:07.710 に答える