2012-06-15 122 views
4

是否可以使用C#在GAC中枚舉程序集的所有已安裝版本?例如,我有名爲「My.Assembly」的程序集。該程序集可能有各種版本(「1.0.0.0」,「2.3.4.5」,「0.1.2.4」,...),並可能針對各種平臺(x86,x64,任何CPU)進行編譯。枚舉程序集的所有已安裝版本(在GAC中)

現在我需要一種方法來確定安裝了哪些版本/平臺。

我知道我可以枚舉GAC中的目錄,但這似乎是錯誤的。應該有更好的方法來做到這一點。

背景 我有一個啓動應用程序,其中用戶選擇一個DLL。啓動程序從DLL中檢索一些信息(不加載它),然後必須啓動正確的託管C#應用程序來處理DLL。該DLL可以編譯爲Win32或者x64,使得暴露總是相同的(與平臺無關的)接口。我使用LoadLibrary函數在C#應用程序中加載DLL。唯一的問題是該進程必須具有匹配的格式(x86或x64)。 C#應用程序可以並且應該爲x86,x64和任何CPU編譯。

+1

您可以使用Fusion api,CreateAssemblyEnum()和IAssemblyEnum + IAssemblyName執行此操作。這不是在.NET框架中公開的,但它包含了它的代碼。 ILSpy或Reflector將會很方便。 –

+0

@HansPassant融合似乎正是我所期待的。這似乎很難使用。如果有管理/內置的支持這種事情會很好。非常感謝! – Korexio

回答

3

使用managed wrapperUnmanaged Fusion API一個能夠做正是我想做的事:

class Program 
{ 

    static IEnumerable<AssemblyName> GetInstalledVersions(string name) 
    { 
     int result; 

     IAssemblyName assemblyName; 
     result = Utils.CreateAssemblyNameObject(out assemblyName, name, CreateAssemblyNameObjectFlags.CANOF_DEFAULT, IntPtr.Zero); 
     if ((result != 0) || (assemblyName == null)) 
      throw new Exception("CreateAssemblyNameObject failed."); 

     IAssemblyEnum enumerator; 
     result = Utils.CreateAssemblyEnum(out enumerator, IntPtr.Zero, assemblyName, AssemblyCacheFlags.GAC, IntPtr.Zero); 
     if ((result != 0) || (enumerator == null)) 
      throw new Exception("CreateAssemblyEnum failed."); 

     while ((enumerator.GetNextAssembly(IntPtr.Zero, out assemblyName, 0) == 0) && (assemblyName != null)) 
     { 
      StringBuilder displayName = new StringBuilder(1024); 
      int displayNameLength = displayName.Capacity; 
      assemblyName.GetDisplayName(displayName, ref displayNameLength, (int)AssemblyNameDisplayFlags.ALL); 
      yield return new AssemblyName(displayName.ToString()); 
     } 

    } 

    static void Main(string[] args) 
    { 
     foreach (AssemblyName assemblyName in GetInstalledVersions("System.Data")) 
      Console.WriteLine("{0} V{1}, {2}", 
       assemblyName.Name, assemblyName.Version.ToString(), assemblyName.ProcessorArchitecture); 
    } 
} 

運行上面的程序給我下面的輸出:

System.Data V2.0.0.0, Amd64 
System.Data V2.0.0.0, X86 
System.Data V4.0.0.0, Amd64 
System.Data V4.0.0.0, X86 

感謝漢斯帕桑特誰指出我在正確的方向!

+0

備註:如果融合包裝器是爲Framework 2.0編譯的,它將不會返回CLR版本4的全局程序集緩存中存在的結果。 –

相關問題