ターゲットアプリケーションのアセンブリをリフレクションによって解析するWPFツールを構築しています。AppDomainを使用してアセンブリを一時的にロードする
私はこれまでターゲットアセンブリをロードするのにAssembly.Load
などを使用していました。これにはいくつかの制限がありますが、ターゲットアプリケーションを再構築し、新しく作成されたアセンブリを再解析するためのツールを「リフレッシュ」できるようにしたいという点を除いて、これは問題ありません。これは、アセンブリが荷重でロックされ、ツールが終了するまで解放されないため、現在は機能しません。これにより、新しく組み立てられたアセンブリを再ロードすることも排除されます。
私は一時的なAppDomainを作成し、その中にアセンブリをロードし、やりたいと思うようにしてから、ドメインをアンロードすることができます。
私が抱えている問題は、動作させることができないということです。私は明示的に
- ロードではなく、1ロード要求されたアセンブリツールのアセンブリをロード
- エラー:私は、多くのバリエーションを試してみましたが、のような結果を得るました(?)ここで提案次たとえば
、:Create custom AppDomain and add assemblies to it
は、私はこのようにSimpleAssemblyLoader
を作成しました:「ファイルが見つかりません」例外を報告
private static AppDomain MakeDomain(string name, string targetPath, string toolPath)
{
var appDomain =
AppDomain.CreateDomain(name, AppDomain.CurrentDomain.Evidence, new AppDomainSetup
{
ApplicationBase = targetPath,
PrivateBinPath = toolPath,
LoaderOptimization = LoaderOptimization.MultiDomainHost
},
new PermissionSet(PermissionState.Unrestricted));
return appDomain;
}
/// <summary>
///
/// </summary>
/// <param name="targetPath">Location of assemblies to analyze</param>
/// <param name="toolPath">Location of this tool</param>
/// <param name="file">Filename of assembly to analyze</param>
/// <returns></returns>
public string[] Test(string targetPath, string toolPath, string file)
{
var dom = MakeDomain("TestDomain", targetPath, toolPath);
var assemblyLoader = (SimpleAssemblyLoader)dom.CreateInstanceAndUnwrap(typeof(SimpleAssemblyLoader).Assembly.FullName, typeof(SimpleAssemblyLoader).FullName);
var path = Path.Combine(targetPath, file);
var assembly = assemblyLoader.LoadFrom(path);
var types = assembly.GetTypes();
List<string> methods = new List<string>();
foreach (var type in types)
{
foreach (var method in type.GetMethods(BindingFlags.Instance|BindingFlags.Public))
{
methods.Add(method.Name);
}
}
AppDomain.Unload(dom);
return methods.ToArray();
}
...ツールアプリケーションが起動し、それはSimpleAssemblyLoaderをインスタンス化に失敗し、:
public class SimpleAssemblyLoader : MarshalByRefObject
{
public Assembly Load(string path)
{
ValidatePath(path);
return Assembly.Load(path);
}
public Assembly LoadFrom(string path)
{
ValidatePath(path);
return Assembly.LoadFrom(path);
}
public Assembly UnsafeLoadFrom(string path)
{
ValidatePath(path);
return Assembly.UnsafeLoadFrom(path);
}
private void ValidatePath(string path)
{
if (path == null) throw new ArgumentNullException(nameof(path));
if (!System.IO.File.Exists(path))
throw new ArgumentException($"path \"{path}\" does not exist");
}
}
...ので、呼び出し元のメソッドでそれを使用しますツールのアセンブリに関連付けられている - 明らかに、ツールのアセンブリを新しいドメインにロードしようとしています(?)。 私は間違っていますが、どうすれば修正できますか?
ツールパスとは何ですか?ツールを使ったディレクトリへのパス? – Evk
@エビックはい。 PrivateBinPathを使用する必要がある場合、または私がそれを悪用している場合、私には不明です。あなたの質問に答えてサンプルコードを編集しました。 –