2009-04-14 53 views
2

阿羅哈列出所有的DLL從GAC實現特定接口

給出一個插件架構(C#/。NET 3.5)與存儲在GAC插件,我怎麼能列出/加載所有DLL的包含實現我的特定界面的類型?換句話說,我想通過查看GAC來調查我的應用程序的哪些插件安裝在計算機上。

-Edoode

+0

小的更正:DLL(程序集)不實現接口 - 但它們可能包含可執行的類。 – 2009-04-14 14:59:01

+1

請原諒我的無知,但是插件dll屬於gac嗎?不在應用程序的應用程序文件夾中? – 2009-04-14 15:08:41

+0

一般來說,沒有。插件應該與他們正在加載的應用一起使用。但是,如果這些是多應用程序插件,那麼我可以明白爲什麼有人希望將它們放入GAC。如果你這樣做,我會有配置來加載它們,而不是隻加載來自GAC的所有配置。 – 2009-04-14 15:25:01

回答

3

首先一點澄清:一個DLL無法實現一個接口。該DLL包含可以實現特定接口的類型。這裏是fusion.dll的.NET wrapper,它允許你枚舉GAC中的所有程序集。一旦您已加載的程序集與Assembly.Load你可以嘗試找到所有實現特定接口類型:

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 2009-04-15 07:30:25

3

海關總署真的只是你的機器就像任何其他的目錄中。這裏是典型的故障:

c:\windows\assembly\GAC 

        \GAC_32 

        \GAC_MSIL 

也許一些其他..

在每一個這些文件夾,你會發現在實際dll的存儲子文件夾。你首先需要編寫一個遞歸方法來獲得所有在\ assembly \下找到的dll,(如果你自己不熟悉這些,你可以很容易地在網上找到它們)。一旦你有了dll的列表,你可以繼續使用Assembly.LoadFile來加載程序集並檢查所有的類型以查看它們是否實現了給定的接口。

我唯一的建議是將這些DLL加載到單獨的應用程序域中,這樣就不會允許任何潛在的有害DLL被加載到您的應用程序中。

一些鏈接:

Searching Directories.

Loading Assemblies and checking for a given interface.

Creating new AppDomain.

+0

我無法誇大使用另一個AppDomain的重要性。事實上,這可能是一個更好的選擇,以積極的方式回收AppDomain,因爲隨着您加載的每個程序集,內存消耗都會增加。 – 2009-04-14 15:07:49

1

你應該看看在企業圖書館Type Selector Tool。這可能不是你想要的,但它可以完成你所描述的內容,你也許可以借用一些實現。

4

要添加到BFree的答案,我建議你可以load the assemblies for reflection only。如果沒有應用程序域和靈活性(可以加載適用於不同體系結構的程序集),這會增強安全性(程序集根本無法執行)。

0

首先,我建議不是這樣做。爲此,您必須從GAC加載所有程序集。我建議你讓你的用戶(或者管理員,或者別的什麼)告訴你要裝載什麼程序集(儘管爲此,你可能需要一個所有選項的列表,這可能是你問這個問題的原因。 ..)

這就是說,這可能工作,但它是拋出錯誤的幾個組件,它應該工作,我不知道爲什麼....此外,我不知道如何檢測GAC是 - C:\ WINDOWS \裝配是默認的,但我不知道哪裏有真正的價值存儲

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)); 

與好運(註冊?)。

相關問題