2011-08-05 15 views
6

Mam strukturę, która składa się z wielu klas bazowych, które można uzyskać w celu opracowania wielu aplikacji. Wśród tych klas znajduje się podklasa System.Windows.Forms.Panel, dla której napisałem własnego projektanta. Wszystko działa dobrze z Visual Studio 2005, ale coś idzie nie tak podczas próby przejścia do VS2010. Jest to znacznie uproszczona wersja tego, co robię:Gdzie Visual Studio szuka złożeń?

Mam projekt o nazwie CoreClasse która zawiera interfejs i dwie klasy:

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; 
    } 
} 

to istnieje ConfClasses projektu, który odwołuje CoreClasses i zawiera tylko jeden Klasa IConf wykonawcze:

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"; 
    } 
} 

i wreszcie jest to projekt dla kontroli, która odwołuje się tylko CoreClasses i zawiera podklasy panel i powiązanych autora:

[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(); 
    } 
} 

Teraz tworzę inne rozwiązanie, które odwołuje się do wszystkich tych bibliotek dll i zawiera pustą podklasę SimplePanel. Po dwukrotnym kliknięciu tej klasy w SolutionExplorer wykonywany jest konstruktor SimplePanelDesigner i wywoływana jest metoda LoadConf z ConfLoader. Oznacza to, że plik ConfClasses.dll jest ładowany dynamicznie i tworzona jest instancja klasy ConfClass. Wszystko jest w porządku do tej pory, ale gdy wywoływany jest InitFoo, ten wyjątek jest podnoszony:

Nie można załadować pliku lub zespołu 'CoreClasses, wersja = 1.0.0.0, Culture = neutral, PublicKeyToken = null' lub jeden z jego zależności. System nie może odnaleźć określonego pliku.

Aby zrobić coś trudniejszego, wyjątek nie jest w rzeczywistości podnoszony w tym przykładzie, ale jest to dokładnie rodzaj tego, co wykonuje moja prawdziwa aplikacja i wyjątek, który otrzymuję. Nie mam pojęcia, co się tutaj dzieje. VS wykonuje metodę IS w CoreClasses. Dlaczego próbuje ponownie go załadować? I gdzie tego szuka? Sprawdziłem również bieżącą AppDomain, ale ma CoreClasses wśród swoich załadowanych zestawów, i nie wydaje się, aby zmienić.

Aby dodać trochę więcej szczegółów, każdy projekt jest budowany we wspólnym folderze (nie jest to zwykły folder obj/debug w folderze projektu) i nie ma innej kopii moich bibliotek DLL na komputerze w momencie, gdy zaczynam mój test. Następnie kopia wszystkich odnośników jest wykonywana w serii folderów w folderze AppData \ Local \ Microsoft \ VisualStudio \ 10.0 \ ProjectAssemblies mojego profilu użytkownika, i wydaje się, że to miejsce, w którym VS szuka zestawów, gdy Assembly.Load jest wykonywany i mogę tam znaleźć kopię CoreClasses. Próbowałem oczyścić wszystkie foldery, odbudować wszystko i utrzymać różne rozwiązania otwierane/zamykane w każdej kombinacji, ale bez żadnych ulepszeń.

EDIT:

Jak sugeruje GranMasterFlush, to FusionLog generowany przez wyjątek:

=== 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). 

EDIT 2

Wystarczy dodać kilka informacji, wziąłem przyjrzeć dzienników fuzyjnych generowane przez mój prosty przykład i okazało się, że dokładnie ten sam dziennik został wygenerowany podczas próby załadowania CoreClasses, ale w jakiś sposób VisualStudio znajduje sposób, aby poradzić sobie z nim.

+0

Użyłem [procmon] (http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) do sprawdzenia, czy plik, na który się skarżył, faktycznie znalazł się w 'AppData \ Local \ Microsoft \ VisualStudio \ 11.0 \ ProjectAssembly \ '. W końcu to dlatego, że moja kontrola niestandardowa próbowała uruchomić wątek (właściwość 'DesignMode' nie działa, patrz [to rozwiązanie] (http://stackoverflow.com/questions/39648/good-way-to-debug błędy wizualno-studyjne-projektowe)). Znalazłem to, przechodząc przez [ten artykuł] (http://msdn.microsoft.com/en-us/library/ms996457.aspx) w jaki sposób debugować zachowanie w czasie projektowania. – pelesl

Odpowiedz

4

Właśnie się dowiedziałem, co się dzieje. Różnica między prostym przykładem a rzeczywistością polega na tym, że w grę wchodzi AddIn. To dość logiczna historia, ale to jest to.
Jak widać na przykładzie kodu, ładuję plik DLL ConfClasses za pomocą odbicia, aby uniknąć dodania do niego odwołania. Jest to dobre w czasie wykonywania, ale projektant skarży się, że nie jest w stanie rzucić IConf do IConf. Dzieje się tak, ponieważ CoreClasses.dll jest ładowany z AppData \ Local \ Microsoft \ VisualStudio \ 10.0 \ ProjectAssemblies, gdy projektant się uruchamia, ale ConfClasses.dll jest ładowany z mojego folderu bin, a więc są jego odniesienia, więc istnieją dwie wersje CoreClasses.dll i różne wersje IConf.
Aby ominąć problem, opracowałem AddIn, że gdy zespół jest ładowany z Assembly.Load w czasie projektowania, dodaje odniesienie do tego zespołu, a następnie czyści odniesienia, gdy ostatnie okno projektanta jest zamknięte.
Wszystko było dobrze z VS2005, ale za pomocą ProcMon.exe dowiedziałem się, że VS2010 dodał nowy folder, w którym dodatki szukają złożeń: Program Files (x86) \ Microsoft Visual Studio 10.0 \ Common7 \ IDE \ CommonExtensions \ DataDesign
Skopiowałem tam mój zespół i wszystko znów działa. Teraz jest tylko kwestia znalezienia sposobu ręcznego dodawania rzeczy.

2

Czy próbowałeś użyć Przeglądarki dziennika wiązania montażowego, aby zbadać, dlaczego to niepowodzenie ładowania złożeń?

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

Jest tu kolejny artykuł na temat używania go:

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

EDIT:

gdzie przechowywane są biblioteki DLL? Ten numer forum post opisuje podobny problem, a problem polegał na tym, że odwołanie do biblioteki DLL nie było ani w GAC, ani w katalogu wykonywalnym, ani podfolderze z katalogu wykonywalnego:

+0

Dodałem FusionLog do pytania, ale to nie ma dla mnie większego sensu ... –

+0

Wszystkie moje projekty mają jeden folder ustawiony jako Output Path, więc wszystkie biblioteki dll są w tym samym folderze, co oczywiście nie jest jeden z Visual Studio. Zespoły nie są ładowane z tego folderu, ale z kopii, która jest wykonana w podfolderach AppData \ Local \ Microsoft \ VisualStudio \ 10.0 \ ProjectAssembly, i tutaj mogę znaleźć wszystkie z nich. –

Powiązane problemy