2009-04-14 2 views
2

アロハリストのすべてのDLLのは、(C#/。NET 3.5)GACに保存されているプラ​​グインは、どのように私は/負荷を一覧表示することができますし、すべてのDLLのプラグインアーキテクチャを考える

GACから特定のインターフェイスを実装しています私の特定のインターフェースを実装するタイプを含んでいますか?言い換えれば、GACを調べることで、自分のアプリケーションのどのプラグインがマシンにインストールされているかを調べたいと思います。

-Edoode

+0

小補正:のDLL(アセンブリ)は、インターフェイスを実装していない - 彼らはしかし、行うクラスが含まれていてもよいです。 –

+1

私の無知を許しますが、プラグインDLLはガックに属していますか?アプリケーションのアプリケーションフォルダにありませんか? –

+0

一般的に、いいえ。プラグインは、ロードされているアプリケーションと一緒に移動する必要があります。しかし、これらがマルチアプリケーションのプラグインである場合、私はGACにそれらを入れる欲望がなぜあるのか分かりました。しかし、GACからすべてのものを読み込むのではなく、ロードするための設定が必要です。 –

答えて

3

まず少し明確化:DLLは、インターフェイスを実装することはできません。 DLLには、特定のインターフェイスを実装できるタイプが含まれています。 GACのすべてのアセンブリを列挙できるfusion.dllの周りに.NET wrapperがあります。あなたはエンタープライズライブラリにType Selector Toolをご覧ください

foreach (var type in assembly.GetTypes()) 
{ 
    var myInterfaceType = typeof(IMyInterface); 
    if (type != myInterfaceType && myInterfaceType.IsAssignableFrom(type)) 
    { 
     Console.WriteLine("{0} implements IMyInterface", type); 
    } 
} 
+0

ありがとう、gacapi(fusion.dll)は私が必要としたものでした:)残りは私が持っていた。 – edosoft

3

GACは本当に他のどのようなあなたのマシン上のディレクトリだけです。ここでは代表的な内訳です​​:

c:\windows\assembly\GAC 

        \GAC_32 

        \GAC_MSIL 

そしておそらくいくつかの他の人がこれらのフォルダのそれぞれの中で...

、あなたは実際のdllのが格納されているサブフォルダを見つけることができます。まず、\ assembly \の下にあるすべてのdllを得るための再帰的なメソッドを書く必要があります(自分でやるのが面倒であれば、簡単にこれらのオンラインを見つけることができます)。 DLLのリストを取得したら、Assembly.LoadFileを使用してアセンブリをロードし、すべてのタイプをチェックして特定のインタフェースを実装しているかどうかを確認することができます。

私の唯一の提案は、潜在的な有害なDLLがあなたのアプリに読み込まれることを許可していないように、別のappdomainにこれらのDLLを読み込むことです。

いくつかのリンク:

Searching Directories.

Loading Assemblies and checking for a given interface.

Creating new AppDomain.

+0

別のAppDomainを使用することの重要性を誇張することはできません。実際、AppDomainをかなり積極的にリサイクルする方が良いでしょう。あなたがロードするアセンブリごとにメモリ消費量が増加するためです。 –

1

:あなたはAssembly.Loadでアセンブリをロードしたら、特定のインターフェイスを実装するすべてのタイプを見つけることを試みること。おそらくあなたが直接欲しいものではないかもしれませんが、それはあなたが何を記述しているのか、それから何らかの実装を借りることができるかもしれません。

4

BFreeの回答に追加するには、load the assemblies for reflection onlyをお勧めします。これにより、appdomainと柔軟性がなくても(アセンブリを実行することができない)セキュリティが強化されます(異なるアーキテクチャ用のアセンブリを読み込むことができます)。

+0

あなたは毎日何か新しいことを学びます。 – BFree

0

まず、ではなく、をおすすめします。これを行うには、GACからすべてのアセンブリをロードする必要があります。私はあなたのユーザ(または管理者など)に、どのアセンブリをロードしようとしているかを教えてもらうことをお勧めします(しかし、そのために、すべてのオプションのリストが必要な場合があります。 ..)

しかし、これはうまくいくかもしれませんが、いくつかのアセンブリでエラーが発生します。理由はわかりません。また、GAC - c:\ windows \ assemblyはデフォルトですが、実際の値がどこに格納されているのか分かりません(レジストリ)

var targetType = typeof(IComparable); 
var errors = new List<Exception>(); 
var c = Directory.GetFiles(@"c:\windows\assembly", "*.dll", SearchOption.AllDirectories).ToList() 
    .ConvertAll(f => Path.GetFileNameWithoutExtension(f)) 
    .Where(f => !f.EndsWith(".ni")) 
    .Distinct().ToList() 
    .ConvertAll(f => { try { return Assembly.ReflectionOnlyLoad(f); } catch (Exception ex) { errors.Add(ex); return null; } }) 
    .Where(a => a != null) 
    .SelectMany(a => { try { return a.GetTypes(); } catch (Exception ex) { errors.Add(ex); return new Type[] { }; } }) 
    .Where(t => targetType.IsAssignableFrom(t)); 

幸いです。

+0

gacapiプロジェクトは、c:\ windows \ assemblyのファイルを読み込むよりもアセンブリのリストを取得するほうがはるかに良いように聞こえるので、ダリンの答えは気にしませんでした。 –

関連する問題