2009-11-25 3 views
1

Есть ли способ использовать визуальную студию «добавить ссылку на ссылку на сборку» (или что-то подобное) в моем собственном приложении? Мне это нужно для генерации и компиляции динамического кода.добавить диалог ссылки на сборку

Это не просто OpenFileDialog, так как он дополнительно смотрит в GAC и т. Д., Поэтому, я думаю, будет очень сложно сделать это самостоятельно.

Если это невозможно, как я могу получить список всех сборок из GAC?

ответ

1

Вы не хотите, чтобы ваше приложение, чтобы быть , что медленно, не так: P

Источник доступен для CR_QuickAddReference.

+0

Медленно, как? Если использование открывает диалог добавления ссылок, это нормально, если он должен подождать несколько секунд. – codymanix

+0

Это общепринятая вещь, которую я слышал от сотен источников, таких как http://weblogs.asp.net/scottgu/archive/2009/10/29/add-reference-dialog-improvements-vs-2010-and- нетто-4-0-series.aspx. Но смайлик предназначен для того, чтобы признать, что вы хотите аналогичную функциональность и что это совершенно разумная цель. –

2

Лучший способ получить все сборки из GAC является использование Fusion

первый Approch: Следующий фрагмент кода показывает, как достичь своей цели:

internal class GacApi 
{ 
    [DllImport("fusion.dll")] 
    internal static extern IntPtr CreateAssemblyCache(
    out IAssemblyCache ppAsmCache, 
    int reserved); 
} 

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")] 
internal interface IAssemblyCache 
{ 
    int Dummy1(); 
    [PreserveSig()] 
    IntPtr QueryAssemblyInfo(int flags, [MarshalAs(UnmanagedType.LPWStr)] String assemblyName, ref ASSEMBLY_INFO assemblyInfo); int Dummy2(); int Dummy3(); int Dummy4(); 
} 

[StructLayout(LayoutKind.Sequential)] 
internal struct ASSEMBLY_INFO 
{ 
    public int  cbAssemblyInfo; 
    public int  assemblyFlags; 
    public long  assemblySizeInKB; 
    [MarshalAs(UnmanagedType.LPWStr)] 
    public String currentAssemblyPath; 
    public int  cchBuf; 
} 
class Program 
{ 
    static void Main() 
    { 
     try 
     { 
      Console.WriteLine(QueryAssemblyInfo("System")); 
     } 
     catch(System.IO.FileNotFoundException e) 
     { 
      Console.WriteLine(e.Message); 
     } 
    } 


    public static String QueryAssemblyInfo(String assemblyName) 
    { 
     ASSEMBLY_INFO assembyInfo = new ASSEMBLY_INFO(); 
     assembyInfo.cchBuf = 512; 
     assembyInfo.currentAssemblyPath = new String('\0', assembyInfo.cchBuf) ; 
     IAssemblyCache assemblyCache = null; 
     IntPtr hr = GacApi.CreateAssemblyCache(out assemblyCache, 0); 
     if (hr == IntPtr.Zero) 
     { 
      hr = assemblyCache.QueryAssemblyInfo(1, assemblyName, ref assembyInfo); 
      if(hr != IntPtr.Zero) 
      Marshal.ThrowExceptionForHR(hr.ToInt32()); 
     } 
     else 
     Marshal.ThrowExceptionForHR(hr.ToInt32()); 
     return assembyInfo.currentAssemblyPath; 
    } 
} 

второй подход: Каталог GAC (% systemroot% \ assembly для установок по умолчанию) является стандартным каталогом, как и любой другой каталог, и вы должны иметь возможность прокручивать каталог, загружать сборки и извлекать информацию о типе всех типов в сборке.

Edit: Код для простого способа:

  List<string> dirs = new List<string>() { 
       "GAC", "GAC_32", "GAC_64", "GAC_MSIL", 
       "NativeImages_v2.0.50727_32", 
       "NativeImages_v2.0.50727_64", 
       "NativeImages_v4.0.50727_32", 
       "NativeImages_v4.0.50727_64" 
      }; 

     string baseDir = @"c:\windows\assembly"; 

     int i = 0; 
     foreach (string dir in dirs) 
      if (Directory.Exists(Path.Combine(baseDir, dir))) 
       foreach (string assemblyDir in Directory.GetFiles(Path.Combine(baseDir, dir), "*.dll", SearchOption.AllDirectories)) 
        Console.WriteLine(assemblyDir); 

Более подробной информации о Fusion.dll можно найти по адресу:

http://support.microsoft.com/kb/317540

Позвольте мне знать, если у вас есть другие вопросы

s

Смежные вопросы