Страницы

Поиск по вопросам

воскресенье, 16 февраля 2020 г.

Узнать версию Runtime для сборки не загружая ее

#c_sharp


Мне нужно отобразить список всех сборок в GAC, а так же их RuntimeVersion.
Если делать так:

Assembly.ReflectionOnlyLoadFrom(systemAssemblyModel.Path).ImageRuntimeVersion;


то пямять забивается на лишние 80 мб и непонятно как их очистить. 
Если же загружать сборки полностью и затем выгружать ее вместе с доменом. То проиcходит
OutOfMemoryException:

internal class Program
{    
   static void Main(string[] args)
   {
       var appDomain = AppDomain.CreateDomain("TestDomain");    
       appDomain.DoCallBack(() => LoadModule());    
       var worker = (Worker) appDomain.CreateInstanceAndUnwrap(typeof (Worker).Assembly.FullName,
typeof (Worker).FullName);
       var a1 = worker.GetAssembliesFullName();

       foreach (var assemblyFullName1 in a1)
       {
           Console.WriteLine(assemblyFullName1);
       }
       Console.WriteLine();
       var a2 = AppDomain.CurrentDomain.GetAssemblies();
       foreach (var assembly1 in a2)
       {
           Console.WriteLine(assembly1.FullName);
       }
            AppDomain.Unload(appDomain);

       Console.ReadKey();
    }

    private static void LoadModule()
    {   
        foreach (var systemAssemblyModel in AssemblyLoader.LoadAssemblies())
        {
            try
            {
               var version = Assembly.Load(systemAssemblyModel.Desc.Path).ImageRuntimeVersion;
            }
            catch (Exception)
            {

            }
        }
     }    
}

class Worker : MarshalByRefObject
{
    public string[] GetAssembliesFullName()
    {
         return AppDomain.CurrentDomain.GetAssemblies().Select(a => a.FullName).ToArray();
    }
}

    


Ответы

Ответ 1



Может кому пригодится. По совету Вам поможет пакет Mono.Cecil – Pavel Mayorov Подключил библиотеку и использовал следующий код AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(assemblyDescription.Path); Console.WriteLine(assemblyDescription.Name + " " + assembly.MainModule.RuntimeVersion);

Ответ 2



У меня работает так без использования доп. библиотек, но получает только лишь версию вида 1.0.5.124: /// /// Без выполнения загрузки файла в память (актуально для сборок) возвращает версию файла Filename в переменную /// типа Version если файл существует и возможно получение номера версии. /// Если файл не существует — возвращает null. /// Если номер версии не удается получить для файла, то все поля результата будут нулевыми (0.0.0.0). /// Если имя файла не указано, то возвращает сведения для выполняемой сборки. /// /// путь к файлу для вычисления версии. /// Правильнее и надежнее использовать метод GetFileVersionInfo. public static Version GetFileVersion(string Filename = "") { if (string.IsNullOrEmpty(Filename)) { Filename = Assembly.GetExecutingAssembly().Location; } if (!File.Exists(Filename)) { return null; } Version version = new Version(); try { FileVersionInfo vi = FileVersionInfo.GetVersionInfo(Filename); version = new Version(vi.ProductVersion); } catch (ArgumentNullException) { //Не можем определить версию файла, и, перемнную для обработки ошибки не ловим, т.к. //её не обрабатываем, а делаем вид, что у файла нулевая версия. version = new Version(0, 0, 0, 0); } return version; } А вот простенький метод, возвращающий больше информации: /// /// Возвращает сведения о версии и параметрах файла в переменную класса FileVersionInfo без загрузки файла /// в память (не блокирует файл). /// Если файл не существует, то возвращает null. /// Если имя файла не указано, то возвращает сведения для выполняемой сборки. /// /// Имя файла для получения сведений о версии. /// /// Если получить версию файла невозможно (например, для файлов, отличных от EXE и DLL), то возвращает /// практически пустую структуру класса FileVersionInfo БЕЗ генерации ошибки. /// public static FileVersionInfo GetFileVersionInfo(string Filename = "") { if (string.IsNullOrEmpty(Filename)) { Filename = Assembly.GetExecutingAssembly().Location; } if (!File.Exists(Filename)) { return null; } return FileVersionInfo.GetVersionInfo(Filename); }

Комментариев нет:

Отправить комментарий