Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Проверка наличия библиотеки в GAC


Автор: Hmm3 25.9.2008, 12:09
Создаю библиотеку. Создаю ей ключ (sn), далее добавляю ее с GAC c помощью gacutil.

К проекту добавляю библиотеку через Add Reference\Browse. 

Вопрос: как проверить существует ли еще библиотека при запуске программы (проекта)? И в случае отсутствия выдавать ошибку.

Автор: source777 25.9.2008, 22:34
Ну так если CLR не найдёт твою dll, то кинет FileNotFoundException... его и лови.

Автор: Rockie 26.9.2008, 16:30
Hmm3, GAC - это C:\Windows\assembly. Правда по сути это не простая папка; если ее просмотреть, например, под FAR-ом, в ней будет совсем не то что видно в windows explorer-е. В любом случае - думаю если будете искать рекурсивно свою dll-ину в папке и подпапках C:\Windows\assembly, решите проблему.

Автор: Rockie 26.9.2008, 16:47
Немного покопался, так как самому стало интересно. Добавлю еще вот это:
Цитата

Чтобы общая сборка автоматически включалась в GAC в процессе установки, проще всего воспользоваться программой установки с поддержкой GAC — например, последней версией пакета Microsoft Installer (MSI). Описание этой программы выходит за рамки книги, но мы укажем, что эту программу можно бесплатно загрузить с сайта MSDN (http://msdn.microsoft.com).
http://www.realcoding.net/teach/vbnet/gl13/gl13_2.html

Автор: Hmm3 1.10.2008, 15:31
Цитата(Rockie @ 26.9.2008,  16:30)
GAC - это C:\Windows\assembly. Правда по сути это не простая папка; если ее просмотреть, например, под FAR-ом, в ней будет совсем не то что видно в windows explorer-е. В любом случае - думаю если будете искать рекурсивно свою dll-ину в папке и подпапках C:\Windows\assembly, решите проблему.

Угу.У меня в папке "assembly" 6 папок:
  • GAC
  • GAC_32
  • GAC_MSIL
  • NativeImages_v2.0.50727_32
  • temp
  • tmp
Библиотека записывается в GAC_MSIL. Далее путь строится так

assembly\GAC_MSIL\[имя]\[версия]__[ключ(?)]\[имя].dll 
Так, для моей библиотеки полный путь таков
c:\WINDOWS\assembly\GAC_MSIL\TestLibrary\1.0.0.0__f45871145e1b89fd\TestLibrary.dll
Зная имя, версию и ключ(?) можно генерировать имя и проверять файл на наличие.

Второй путь. В реестре по адресу
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion\GACChangeNotification\Default 
Находится куча значений. Туда добавляется и значение с именем, версией, и ключом библиотеки. Можно брать все имена значений. В цикле их перебирать -- искать имя своей библиотеки. Потом из найденного вытаскивать версию и ключ. 
Так для моей библиотеки двоичный параметр
Имя:  TestLibrary,1.0.0.0,,f45871145e1b89fd,MSIL
Значение 53 E3 DB 42 B8 23 C9 01

Т.е Имя формируется по принципу [имя],[версия],,[ключ],[MSIL]

Просто была надежда что есть какие-то встроенные средства для таких проверок. Тем более что GAC -- не посторонняя технология. И неизвестно что и куда будет писаться в следующих версиях Windows.

P.S. Ошибка которая возникает при отсутствии библиотеки try- catch' ом не ловится



Автор: Rockie 1.10.2008, 15:44
Цитата(Hmm3 @  1.10.2008,  15:31 Найти цитируемый пост)
Библиотека записывается в GAC_MSIL. Далее путь строится такassembly\GAC_MSIL\[имя]\[версия]__[ключ(?)]\[имя].dll Так, для моей библиотеки полный путь таковc:\WINDOWS\assembly\GAC_MSIL\TestLibrary\1.0.0.0__f45871145e1b89fd\TestLibrary.dllЗная имя, версию и ключ(?) можно генерировать имя и проверять файл на наличие.

Hmm3, проще smile
Код

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ViewGAC
{
    class Program
    {
        static void Main(string[] args)
        {
            string myPath = @"C:\WINDOWS\assembly";

            DirectoryInfo dirArray = new DirectoryInfo(@myPath);

            FileInfo[] filesArray = dirArray.GetFiles("*.dll", SearchOption.AllDirectories);

            foreach (FileInfo f in filesArray)
            {
                System.Console.WriteLine(f.Name);
            }

        }
    }
}


Автор: XenoCode 1.10.2008, 16:18
Можно через API сделать.
Вот например http://www.eggheadcafe.com/software/aspnet/32079348/determine-if-assembly-is.aspx.

Автор: Hmm3 1.10.2008, 16:27
Цитата(Rockie @ 1.10.2008,  15:44)
Hmm3, проще smile
Код

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ViewGAC
{
    class Program
    {
        static void Main(string[] args)
        {
            string myPath = @"C:\WINDOWS\assembly";

            DirectoryInfo dirArray = new DirectoryInfo(@myPath);

            FileInfo[] filesArray = dirArray.GetFiles("*.dll", SearchOption.AllDirectories);

            foreach (FileInfo f in filesArray)
            {
                System.Console.WriteLine(f.Name);
            }

        }
    }
}




Только в том случае если библиотека единственная и неповторимая. А их может быть несколько. (Это же представляется как один из плюсов GAC'a).

Автор: Rockie 1.10.2008, 18:06
Цитата(Hmm3 @  1.10.2008,  16:27 Найти цитируемый пост)
Только в том случае если библиотека единственная и неповторимая.

Уверены? У вас есть в GAC-е дублирующаяся dll-ka "Microsoft.Interop.Security.AzRoles.dll"?
Введите
Код

FileInfo[] filesArray = dirArray.GetFiles("*AZroles*.dll", SearchOption.AllDirectories);

и в цикле
Код

System.Console.WriteLine(f.FullName);

Что у вас выводится?

Автор: Hmm3 1.10.2008, 18:23
Цитата(XenoCode @ 1.10.2008,  16:18)
Можно через API сделать.
Вот например http://www.eggheadcafe.com/software/aspnet/32079348/determine-if-assembly-is.aspx.


Спасибо. Вот и третий способ

Цитата(Rockie @ 1.10.2008,  18:06)
Цитата(Hmm3 @  1.10.2008,  16:27 Найти цитируемый пост)
Только в том случае если библиотека единственная и неповторимая.

Уверены? У вас есть в GAC-е дублирующаяся dll-ka "Microsoft.Interop.Security.AzRoles.dll"?
Введите
Код

FileInfo[] filesArray = dirArray.GetFiles("*AZroles*.dll", SearchOption.AllDirectories);

и в цикле
Код

System.Console.WriteLine(f.FullName);

Что у вас выводится?

 Хм. У меня ничего. Пусто. filesArray пустой. 

Автор: Rockie 2.10.2008, 10:37
Hmm3, на месте AzRoles.dll может быть любой другой файл - это пример dll-ки, несколько экземпляров которой лежит в GAC:
Цитата
C:\Windows\assembly\GAC\Microsoft.Interop.Security.AzRoles\1.2.0.0__31bf3856ad364e35\Microsoft.Interop.Security.AzRoles.dll
C:\Windows\assembly\GAC\Microsoft.Interop.Security.AzRoles\1.0.0.0__31bf3856ad364e35\Microsoft.Interop.Security.AzRoles.dll

Автор: Hmm3 14.10.2008, 16:18
Цитата(Rockie @ 2.10.2008,  10:37)
Hmm3, на месте AzRoles.dll может быть любой другой файл - это пример dll-ки, несколько экземпляров которой лежит в GAC:
Цитата
C:\Windows\assembly\GAC\Microsoft.Interop.Security.AzRoles\1.2.0.0__31bf3856ad364e35\Microsoft.Interop.Security.AzRoles.dll
C:\Windows\assembly\GAC\Microsoft.Interop.Security.AzRoles\1.0.0.0__31bf3856ad364e35\Microsoft.Interop.Security.AzRoles.dll

Я не спорю, но так заодно можно проверить версию библиотеку. (Если это, конечно необходимо).
Если нет, то больше подходит такой способ. Будем считать его четвертым.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)