このような多くの同様の質問があります。しかし、彼らはすべて年をとっており、今日は仕事をしていません(それ以上ですか?)。C#アセンブリをappdomainに動的にロード/アンロードする
これは私の質問です: 私は、メモリにC#アセンブリをロードし、使用したいインターフェイスに一致するタイプが含まれているかどうかを調べたいと思います。アセンブリにこのクラスの種類が含まれている場合、私は参照し、私の主なアプリケーションで使用します。そうでない場合は、dllをアンロードしてから、メインアプリケーションから、またはアプリケーションの実行中に手動でファイルを削除することができます。
私の最初の実装は、単純にappdomainのアプローチを排除しましたが、(アセンブリファイルを削除または置換することなく)機能しました。次に、さまざまな例で説明したようにアセンブリをロードしようとしました。しかし、私はディスクから不要なアセンブリファイルを削除することはできませんでした。
アプリケーションで参照されたときや、何か間違っているときに、アセンブリをアンロードして削除することはできません。 これは私が最後にしようとしたものです:
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using ESTLogViewer_V2.Formulare;
using Parent;
namespace ESTLogViewer_V2
{
static class Program
{
//<summary>
//Der Haupteinstiegspunkt für die Anwendung.
//</summary>
[STAThread]
static void Main()
{
LoadTest.Haupt(null);
}
}
}
namespace Parent
{
public class Constants
{
// adjust
public const string LIB_PATH = @"e:\PRJDOTNET4\ESTLogViewer V2\Plugins\LogFiles_Plugin.dll";
}
public interface ILoader
{
string Execute();
}
public class Loader : MarshalByRefObject, ILoader
{
public string Execute()
{
var assembly = Assembly.LoadFile(Constants.LIB_PATH);
foreach (var t in assembly.GetTypes())
{
Debug.WriteLine(t.FullName);
}
return assembly.FullName;
}
}
class LoadTest
{
public static void Haupt(string[] args)
{
var domain = AppDomain.CreateDomain("child");
var loader = (ILoader)domain.CreateInstanceAndUnwrap(typeof(Loader).Assembly.FullName, typeof(Loader).FullName);
Console.Out.WriteLine(loader.Execute());
AppDomain.Unload(domain);
domain = null;
File.Delete(Constants.LIB_PATH);
}
}
}
ので、このコードはFile.Delete
声明まで動作します。私はアセンブリファイルを削除できませんでした理由を見つけることを試みた - この質問を書きながら、私はいくつかのより多くのテストをしました、今
LogFiles_Plugin.clsSchritLogDateiSplitter
LogFiles_Plugin.clsLogFileMeldDateiSplitter
LogFiles_Plugin.clsLogFileMeldDateiSplitterNG
LogFiles_Plugin.clsAuftragsAnalyseSplitter
LogFiles_Plugin.clsAuftrag
LogFiles_Plugin.clsS_R_SignalSplitter
LogFiles_Plugin.clsLogFileGVMeldDateiSplitter
LogFiles_Plugin.clsLogFileGVTeleSplitter
LogFiles_Plugin.clsLogFileGVTeleSplitter+spalte
<PrivateImplementationDetails>{37CEBF0C-E73A-4FE7-B152-9A858E6C176D}
<PrivateImplementationDetails>{37CEBF0C-E73A-4FE7-B152-9A858E6C176D}+__StaticArrayInitTypeSize=6256
"ESTLogViewer V2.exe" (Verwaltet (v4.0.30319)): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_de_b77a5c561934e089\mscorlib.resources.dll" geladen
Eine Ausnahme (erste Chance) des Typs "System.UnauthorizedAccessException" ist in mscorlib.dll aufgetreten.
:しかし、それは例外をスローします。私は、それがビジュアルスタジオのリモートデバッガによってロックされていることを知りました。
したがって、2番目の質問は、リモートのデバッガでファイルをロックしないようにする方法です。
こんにちは@John、私は私の例のコードをあなたのコードに置き換えました。 これは、「appdomain」 - 接近のソリューションです。しかし、appdomainを使わなくても動作するはずです。 –
@WolfgangRoth両方とも動作するはずですが、[リンクされた回答](https://stackoverflow.com/a/18935973/3181933)のように、アセンブリがロードされてからアンロードすることはできませんそれはAppDomainにあります。 [MSDN同意](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/assemblies-gac/how-to-load-and-unload-assemblies) – john
私はまだしていないアセンブリの複数の負荷の影響を調べます。しかし、アセンブリロードの私の主な考えは、ユーザーが交換できる私のコードにプラグインを実装できるようにすることでした。また、ユーザがプラグインのリストを更新するたびに、新しいものを追加し、古いものをユーザに示されたリストから削除する必要があります - 実装上のみ異なるアセンブリを置き換えることはできません他のものは同じ名前空間と名前を持っています...明日これを試してみましょう。 –