Получить сборки без их наглядного представления - PullRequest
4 голосов
/ 30 марта 2012

Я пытаюсь получить все сборки в CurrentDomain, используя AppDomain.CurrentDomain.GetAssemblies(), чтобы записать их FullName в DropDownList, однако, если я их не создаю, они не будут видны в возвращенном массиве из GetAssemblies() в CurrentDomain.

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

Как решить эту проблему простым и более общим способом, вместо того, чтобы создавать его экземпляры каждый раз, когда я добавляю новую сборку и т. Д.

В соответствии с политикой компании мне необходимо запутать некоторые части изображений:

enter image description here

Все сборки указаны в справочной папке:

enter image description here

Ответы [ 3 ]

7 голосов
/ 30 марта 2012

Здесь действительно происходит что-то тонкое в дополнение к комментариям других людей.

VisualStudio на самом деле не добавляет .dll ссылки на манифест сборки информации об отражении вашей сборки, если толькоони фактически используются.

В качестве примера создайте новый проект и создайте ссылку на сборку.Я использовал nunit.framework.dll в качестве примера.

Но на самом деле не используйте его.Мой код просто:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

Но у Project есть ссылка на NUnit в VisualStudio.Теперь соберите его и откройте сборку в ildasm.exe, а верхняя часть манифеста:

// Metadata version: v4.0.30319
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 4:0:0:0
}
.assembly ConsoleApplication1
{
    ...etc...

Теперь в коде просто используйте что-нибудь из NUnit:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Assert.IsTrue(true);
        }
    }
}

Снова пересоберите и проверьте манифест сборки в ildasm.exe:

// Metadata version: v4.0.30319
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 4:0:0:0
}
.assembly extern nunit.framework
{
  .publickeytoken = (96 D0 9A 1E B7 F4 4A 77 )                         // ......Jw
  .ver 2:6:0:12051
}
.assembly ConsoleApplication1
{
    ...etc...

Обратите внимание, что теперь в IL есть внешний.Это также обеспечивает отражение, поэтому оно знает, какие зависимые сборки должны быть загружены.

В прошлом эта небольшая деталь, как уже говорили другие, во время выполнения фактически не загружает сборку, пока она не понадобится в первый раз.следовательно, ваш домен приложений не имеет загруженных сборок до тех пор, пока вы не создадите экземпляр или не используете что-то из этой сборки.


Эта деталь выше вступает в силу, когда вы начинаете пытаться использовать метод Assembly.GetReferencedAssemblies().

Итак, в VisualStudio у меня есть проект со следующими ссылками:

Microsoft.CSharp
nunit.framework
System
System.Core
System.Data
System.Xml
System.Xml.Linq

Затем у меня есть код C #:

using System;
using System.Reflection;
using NUnit.Framework;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var assemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
            foreach (var assemblyName in assemblies)
            {
                Console.WriteLine(assemblyName.FullName);
            }
            Console.ReadKey();
        }
    }
}

Обратите внимание, что у меня даже есть using NUnit.Framework; заявление!Но я на самом деле нигде не использую NUnit, поэтому не сборка, на которую ссылаются.Результат выполнения этого:

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Вот и все.Если я добавлю эту строку в мое тестовое приложение:

Assert.IsTrue(true);

Теперь что-то на самом деле использует NUnit, и вывод моей консоли будет:

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
nunit.framework, Version=2.6.0.12051, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77
3 голосов
/ 30 марта 2012

Пока вы не создадите экземпляры типов или зависимых типов, они не будут загружены.Поэтому, если ваш проект ссылается на тонну сборок, но не создает экземпляры каких-либо типов внутри них, ваше приложение не подвергнется удачной загрузке этих битов с диска.

Если вы хотите узнать, чтосборки ваших ссылок на проекты, вам придется исследовать вашу сборку, используя .NET Reflection .В частности, я предлагаю вам взглянуть на метод Assembly.GetReferencedAssemblies () .

HTH.

0 голосов
/ 30 марта 2012

Вот что я сделал и работал для меня:

Private Sub Pre_Load()
    Dim sBasePath As String = AppDomain.CurrentDomain.BaseDirectory
    Dim sAllFiles() As String = Directory.GetFiles(sBasePath)
    For Each sAssemblyFile As String In sAllFiles
        If sAssemblyFile.EndsWith(".dll") Then
            If Not Me.HasThisAssembly(sAssemblyFile) Then
                Assembly.Load(AssemblyName.GetAssemblyName(sAssemblyFile))
            End If
        End If
    Next
End Sub

Private Function HasThisAssembly(ByVal vsAssemblyName As String) As Boolean
    For Each oAssembly As Assembly In AppDomain.CurrentDomain.GetAssemblies()
        Dim oFile As New FileInfo(vsAssemblyName)
        If oFile.Name = oAssembly.GetName().Name + ".dll" Then
            Return True
            Exit Function
        End If
    Next
    Return False
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...