Где Visual Studio ищет сборки? - PullRequest
6 голосов
/ 05 августа 2011

У меня есть фреймворк, который состоит из множества базовых классов, которые могут быть получены для разработки многих приложений. Среди этих классов есть подкласс System.Windows.Forms.Panel, для которого я написал свой собственный конструктор. Все отлично работает с Visual Studio 2005, но что-то идет не так, когда я пытаюсь перейти на VS2010. Это очень упрощенная версия того, что я делаю:

У меня есть проект под названием CoreClasse, который содержит интерфейс и два класса:

public interface IConf
{
    string foo { get; set; }
    void InitFoo();
}

public class SimpleClass
{
    public string foo;
}

public class ConfLoader
{
    public static IConf LoadConf()
    {
        AssemblyName anAssemblyName = new AssemblyName("ConfClasses");
        Assembly anAssembly = Assembly.Load(anAssemblyName);
        IConf result = (IConf)anAssembly.CreateInstance("ConfClasses.ConfClass");
        result.InitFoo();
        return result;
    }
}

Затем существует проект ConfClasses, который ссылается на CoreClasses и содержит только один класс, реализующий IConf:

public class ConfClass : IConf
{
    public SimpleClass confVal;

    public string foo
    {
        get { return confVal.foo; }
        set { confVal.foo = value; }
    }

    public void InitFoo()
    {
        confVal = new SimpleClass();
        confVal.foo = "bar";
    }
}

И, наконец, существует проект для элементов управления, который ссылается только на CoreClasses и содержит подкласс Panel и связанного дизайнера:

[Designer("MyControls.Design.SimplePanelDesigner", typeof(IRootDesigner))]
public class SimplePanel : Panel
{
    public SimpleClass dummy = new SimpleClass();
}

public class SimplePanelDesigner : DocumentDesigner
{
    public IConf DesignerConf;

    public SimplePanelDesigner()
        : base()
    {
        DesignerConf = ConfLoader.LoadConf();
    }
}

Теперь я создаю другое решение, которое ссылается на все эти библиотеки и содержит пустой подкласс SimplePanel. Когда я дважды щелкаю по этому классу в SolutionExplorer, выполняется конструктор SimplePanelDesigner и вызывается метод LoadConf из ConfLoader. Это означает, что ConfClasses.dll загружается динамически и создается экземпляр ConfClass. До этого момента все в порядке, но когда вызывается InitFoo, возникает исключение:

Не удалось загрузить файл или сборку 'CoreClasses, Version = 1.0.0.0, Culture = нейтральный, PublicKeyToken = null' или одну из ее зависимостей. Система не может найти указанный файл.

Чтобы усложнить ситуацию, в данном примере исключение на самом деле не возникает, но это именно то, что выполняет мое настоящее приложение, и исключение, которое я получаю. Я понятия не имею, что здесь происходит. VS выполняет метод, который есть в CoreClasses. Почему он пытается загрузить его снова? И где это ищет? Я также проверил текущий AppDomain, но у него есть CoreClasses среди загруженных сборок, и он, похоже, не меняется.

Просто, чтобы добавить больше деталей, каждый проект создается в общей папке (а не в обычной папке obj / debug внутри папки проекта), и в тот момент, когда я запускаю свой компьютер, на ПК нет другой копии моих библиотек. тестовое задание. Затем копия всех упомянутых dll-файлов делается в ряде папок в папке AppData \ Local \ Microsoft \ VisualStudio \ 10.0 \ ProjectAssemblies моего userprofile, и это, по-видимому, место, где VS ищет сборки, когда Assembly.Load выполняется, и я могу найти копию CoreClasses там. Я пытался очистить все папки, перестроить все и держать открытыми / закрытыми разные решения в каждой комбинации, но без каких-либо улучшений.

EDIT:

Как и предполагал GranMasterFlush, это FusionLog, сгенерированный исключением:

=== Pre-bind state information ===
LOG: User = FCDB\fc0107
LOG: DisplayName = XEngine.Core, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Visual Studio 10.0/Common7/IDE/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).

РЕДАКТИРОВАТЬ 2

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

Ответы [ 2 ]

4 голосов
/ 08 августа 2011

Я только что узнал, что происходит.Разница между простым примером и реальной вещью заключается в том, что в нем задействован AddIn.Это довольно логичная история, но это так.Как видно из примера кода, я загружаю ConfClasses dll с помощью отражения, чтобы избежать добавления ссылки на него.Это хорошо во время выполнения, но дизайнер жалуется, говоря, что он не может привести IConf к IConf.Это происходит из-за того, что CoreClasses.dll загружается из AppData \ Local \ Microsoft \ VisualStudio \ 10.0 \ ProjectAssemblies при запуске дизайнера, но ConfClasses.dll загружается из моей папки bin, как и его ссылки, поэтому существует две версии CoreClasses.dllи разные версии IConf.Чтобы обойти проблему, я разработал AddIn, который, когда сборка загружается с Assembly.Load во время разработки, добавляет ссылку на эту сборку, а затем очищает ссылки, когда закрывается последнее окно конструктора.С VS2005 все было в порядке, но с помощью ProcMon.exe я обнаружил, что VS2010 добавил новую папку, где надстройки ищут сборки: Program Files (x86) \ Microsoft Visual Studio 10.0 \ Common7 \ IDE \ CommonExtensions \ DataDesign Я скопировал свою сборку туда, и все снова работает.Теперь остается только найти способ добавить туда вещи вручную.

2 голосов
/ 05 августа 2011

Вы пытались использовать средство просмотра журналов привязок сборок, чтобы выяснить причину сбоя при загрузке сборок?

http://msdn.microsoft.com/en-us/library/e74a18c4%28v=vs.71%29.aspx

Здесь есть еще одна статья об использовании:

http://blogs.msdn.com/b/suzcook/archive/2003/05/29/57120.aspx

РЕДАКТИРОВАТЬ:

Где хранятся DLL? В этом сообщении на форуме подробно описана похожая проблема, и проблема заключалась в том, что ссылка на DLL отсутствует в GAC, исполняемом каталоге или подпапке из исполняемого каталога:

...