2009-10-21 43 views
11

Làm cách nào để liệt kê tất cả các assembly có sẵn trong GAC trong C#?liệt kê các hội đồng trong GAC

Thực ra tôi đang gặp vấn đề với mã ngu ngốc - assembly được gọi là Telerik.Web.UI.dll được giới thiệu và sử dụng trong dự án - DLL cụ thể này không có trong thư mục BIN. Và ứng dụng đang hoạt động tốt trên máy chủ - nhưng trên máy tính của tôi, rõ ràng là trình biên dịch đưa ra lỗi. Ex-Developer khẳng định rằng nó không có trong GAC trên máy chủ và 'nó là cái gì'. Bây giờ tôi cần phải kiểm tra xem DLL này được đăng ký trong GAC hay không.

Trợ giúp sẽ được đánh giá cao.

Ngày tốt lành;

+0

@effkey - bạn có quản lý để giải quyết vấn đề này không? – Kev

+0

nop; Tôi không đủ thẩm quyền để; thay vì tôi đã tải xuống các tệp .dll từ torrents (cùng một phiên bản) và chúng hoạt động. Tôi vẫn không hiểu từ nơi ASP .NET được chọn lên DLLz nếu họ không có trong GAC. – effkay

Trả lời

10

Nếu bạn có quyền truy cập hạn chế đến máy chủ thì đây có thể làm việc:

// List of all the different types of GAC folders for both 32bit and 64bit 
// environments. 
List<string> gacFolders = new List<string>() { 
    "GAC", "GAC_32", "GAC_64", "GAC_MSIL", 
    "NativeImages_v2.0.50727_32", 
    "NativeImages_v2.0.50727_64", 
    "NativeImages_v4.0.30319_32", 
    "NativeImages_v4.0.30319_64" 
}; 

foreach (string folder in gacFolders) 
{ 
    string path = Path.Combine(
     Environment.ExpandEnvironmentVariables(@"%systemroot%\assembly"), 
     folder); 

    if(Directory.Exists(path)) 
    { 
     Response.Write("<hr/>" + folder + "<hr/>"); 

     string[] assemblyFolders = Directory.GetDirectories(path); 
     foreach (string assemblyFolder in assemblyFolders) 
     { 
      Response.Write(assemblyFolder + "<br/>"); 
     } 
    } 
} 

Nó cơ bản liệt kê các thư mục GAC thô. Nó hoạt động trên DiscountASP chia sẻ lưu trữ để có thể làm việc cho môi trường lưu trữ của bạn.

Nó có thể được tô điểm bằng cách liệt kê sâu hơn vào mỗi thư mục của hội đồng để lấy ra số phiên bản và mã thông báo khóa công khai.

4

Kiểm tra điều này codeproject GAC API Interface bài viết. Điều này sử dụng fusion.dll không có giấy tờ để liệt kê GAC. Nhưng tác giả tuyên bố rằng

Mã này được biết là hoạt động với .NET 1.1 và 2.0. Xin lưu ý rằng DLL fusion.dll khác nhau trong 1,1 và 2.0. Vì vậy, nếu bạn có cả hai khung được cài đặt, hãy đảm bảo trỏ mã đến đúng DLL. Nếu không, hầu hết cuộc gọi API sẽ không thành công. Triển khai thực hiện mặc định sử dụng số được tìm thấy trong thư mục WINDOWS.

+0

cảm ơn - sẽ kiểm tra; nhưng tôi sợ nó có thể tạo ra một vấn đề với các điều khoản; vì tôi có quyền truy cập hạn chế vào máy chủ - và tôi nghi ngờ chức năng của nó trong ASP NET User. nhưng vẫn cảm ơn; Tôi đã nhìn thấy nó sớm hơn, nhưng loại trừ coz nghi ngờ ở trên. Nhưng hãy thử xem. – effkay

+1

Nó không phải là không có giấy tờ. Ít nhất không còn nữa. https://support.microsoft.com/kb/317540 hoặc http://msdn.microsoft.com/en-us/library/ms404523.aspx –

4

Bạn không thực sự cần viết gì đó trong C# để tìm hiểu xem tệp dll cụ thể này có trong gac hay không. Bạn có thể sử dụng gacutil.exe với tùy chọn/l từ dòng lệnh để liệt kê các nội dung của GAC.

+0

muốn tôi có thể - Tôi có quyền truy cập hạn chế vào máy chủ - tức là, FTP chỉ :) nhưng vẫn cảm ơn nhận xét – effkay

+0

@effkay - xin lỗi nó không hữu ích. Nếu bạn có quyền truy cập hạn chế vào máy chủ thì giải pháp mã sẽ giúp ích như thế nào? –

+0

@MikeTwo Âm thanh như anh dự định tải lên một trang web sẽ liệt kê những gì các hội đồng trong GAC. – BrainSlugs83

-3

Có thể bạn cần GAC xem một cái gì đó như thế này:

alt text

Video: How to use Add GAC References Dialog

Hope this helps

s

+0

Điều đó sẽ không giúp ích gì khi anh ta nói rằng anh ta chỉ có quyền truy cập FTP vào máy chủ. Anh ta muốn có thể liệt kê GAC bằng cách sử dụng mã C# được thực thi trong một môi trường tin cậy chưa đầy đủ. – BrainSlugs83

3

Nếu đó là đồng bằng-jane ASP.NET trang web, và assembly không nằm trong thư mục bin của trang web hoặc trong GAC của máy chủ (và không có gì có nhiều fishy trong web.config), có lẽ trang web là một trang con của một số loại và một trong những trang cao hơn có chứa tham chiếu trong thư mục bin (hoặc một cái gì đó có nhiều trong web.config của nó, vì các trang con/thư mục kế thừa web.configs của bố mẹ chúng) ?

Bây giờ, nếu bạn có môi trường nơi tệp đang được tải chính xác (và có vẻ như bạn đang làm), bạn có thể chỉ cần hỏi .NET ở đâu.dll đến từ và hiển thị mà thay vào đó, ví dụ:

Assembly a = Assembly.Load("Microsoft.VisualStudio.Shell, Version=2.0.0.0, " 
      + "PublicKeyToken=b03f5f7f11d50a3a, Culture=Neutral"); 

Console.WriteLine(a.Location); 

sẽ nạp một assembly và hiển thị vị trí trên đĩa của nó, đầu ra của tôi là: C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.Shell\2.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Shell.dll

Nếu đó là dưới "C: \ Windows \ lắp ráp \ "bạn biết nó trong GAC. Bạn cũng có thể thực hiện việc này mà không cần một cuộc gọi Assembly.Load nếu bạn đã tham chiếu đến assembly, bạn có thể liệt kê các assembly được nạp vào app.domain hiện tại và chỉ cần in ra (hoặc trả về một điều khiển theo nghĩa đen, hoặc Response.Write, vv ...) thuộc tính .Location của chúng là gì.

Edit: Mã cho rằng trông giống như sau:

foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) 
{ 
    Console.WriteLine(a.GetName().FullName); 
    Console.WriteLine(a.Location); 
    Console.WriteLine(); 
} 

Edit: Trên một môi trường tin tưởng đầy đủ, mã (giao diện điều khiển ứng dụng) sau đây sẽ liệt kê GAC và viết ra mỗi hội đồng, cần phải dễ dàng sửa đổi nó thành ứng dụng ASP.NET, nhưng tôi không chắc liệu nó có hoạt động trong môi trường ít tin cậy hơn không (chỉ đoán ở đây, bạn có thể may mắn):

static void ProcessFile(string file) 
{ 
    try 
    { 
     Assembly a = Assembly.LoadFile(file); 

     Console.WriteLine(a.GetName().FullName); 
    } 
    catch { /* do nothing */ } 
} 

static void ProcessFolder(string folder) 
{ 
    foreach (string file in Directory.GetFiles(folder)) 
    { 
     ProcessFile(file); 
    } 

    foreach (string subFolder in Directory.GetDirectories(folder)) 
    { 
     ProcessFolder(subFolder); 
    } 
} 

static void Main(string[] args) 
{ 
    ProcessFolder(@"C:\Windows\Assembly"); 
} 
3

một phương pháp đơn giản để liệt kê các file dll trong một thư mục

public static string[] GetGlobalAssemblyCacheFiles(string path) 
{ 
    List<string> files = new List<string>(); 

    DirectoryInfo di = new DirectoryInfo(path); 

    foreach (FileInfo fi in di.GetFiles("*.dll")) 
    { 
     files.Add(fi.FullName); 
    } 

    foreach (DirectoryInfo diChild in di.GetDirectories()) 
    { 
     var files2 = GetGlobalAssemblyCacheFiles(diChild.FullName); 
     files.AddRange(files2); 
    } 

    return files.ToArray(); 
} 

và bạn có thể nhận được tất cả các file

string gacPath = Environment.GetFolderPath(System.Environment.SpecialFolder.Windows) + "\\assembly"; 
var files = GetGlobalAssemblyCacheFiles(gacPath); 

Nếu bạn cần phải tải từng lắp ráp, Bạn nhận được một ngoại lệ cho nhau thời gian chạy phiên bản. Vì lý do này bạn có thể tải lắp ráp với Assembly.ReflectionOnlyLoadFrom để tải hội trong chỉ phản ánh. Sau đó, Assembly không tải trong AppDomain của bạn và không ném ngoại lệ.

1

Hình i cũng có thể ném vào giải pháp dựa trên LINQ của tôi (thuận tiện nếu bạn chỉ tìm kiếm một tập tin duy nhất và không muốn liệt kê qua từng tập tin)

chức năng để tìm các tập tin:

public static IEnumerable<string> FindFiles (string path, string filter = "", int depth = int.MaxValue) { 
     DirectoryInfo di = new DirectoryInfo(path); 

     IEnumerable<string> results = (! string.IsNullOrEmpty(filter) ? di.GetFiles(filter) : di.GetFiles()).Select(f => f.FullName); 
     if (depth > 0) { 
      results = results.Concat(di.GetDirectories().SelectMany(d => FindFiles(d.FullName, filter, depth - 1))); 
     } 

     return results; 
    } 

Và để gọi số (tôi đã không có Environment.SpecialFolder.Windows nên được sử dụng thay vì Environment.SpecialFolder.System)

string path = Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\..\\assembly"; 
foreach (string s in FindFiles(path, "*.dll")) { 
    Console.WriteLine(s); 
} 

Hơn nữa, như một FYI phương pháp enume này đánh giá toàn bộ GAC và bạn có thể tìm thấy các tệp DLL trùng lặp trong tmp/và temp /, Tmp được sử dụng để cài đặt và Temp được sử dụng để gỡ cài đặt.

Các vấn đề liên quan