2012-12-02 26 views
14

Moje pytanie jest bardzo podobne do this one, tylko że odpowiedź i obejście nie działają dla mnie. Również jestem w Visual Studio 2012.VSIX - Nie można załadować pliku lub zestawu odnośnika dll

Mam VSPackage, który odwołuje się do innego projektu, który jest zależny od innych bibliotek dll. Za każdym razem, gdy uruchamiam paczkę w debugowaniu, otrzymuję wyjątek, że innych bibliotek dll nie można znaleźć. Znajdują się w katalogu wyjściowym i są podpisane.

Próbowałem odnieść się do nich bezpośrednio w projekcie VSPackage bezskutecznie.

Myśli?

Odpowiedz

29

Ten problem występuje, ponieważ program Visual Studio nie szuka złożeń w folderze rozszerzenia, jeśli rozszerzenie nie ma wyraźnej zależności od tych złożeń. Na przykład zależność ustawiona w pliku konfiguracyjnym (konfiguracja IoC) lub w kodzie XAML. Znam trzy rozwiązania tego problemu:

  1. Możesz zainstalować te zespoły w GAC, a Visual Studio załaduje je. Ta metoda jest dobra, jeśli używasz biblioteki innej firmy, która została zbudowana do użytku w GAC (na przykład MS Enterprise Library). Ale VSIX Deployment Package nie pozwala na instalowanie złożeń w GAC, możesz użyć instalatora MSI.

  2. Dla VSPackages for Visual Studio 2010/2012 można użyć atrybutu ProvideBindingPath. Ścieżka, w której znajduje się twoje rozszerzenie, zostanie dodana do ścieżek używanych przez program Visual Studio do znajdowania zależnych zestawów. Jeśli twoje rozszerzenie nie zawiera VSPackage, możesz dodać ten atrybut do dowolnej publicznej klasy (see here).

    [ProvideBindingPath] 
    public class MyVsPackage : Package 
    { /* ... */ } 
    
  3. Można ręcznie rozwiązywać nazwy zespołów. Aby to zrobić, musisz zasubskrybować zdarzenie AssemblyResolve i musisz zwrócić wymagane zestawy z procedury obsługi. Jest to najbardziej elastyczny sposób, jeśli nie możesz skorzystać z poprzednich metod, jest to szczególnie dla Ciebie.

    W moim projekcie IntelliDebugger napisałem klasy ManualAssemblyResolver dla niego:

using System; 
using System.Reflection; 

namespace IntelliEgg.Debugger.Utility 
{ 
    public class ManualAssemblyResolver : IDisposable 
    { 
     public ManualAssemblyResolver(Assembly assembly) 
     { 
      if (assembly == null) 
       throw new ArgumentNullException("assembly"); 

      _assemblies = new[] {assembly}; 
      AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; 
     } 

     public ManualAssemblyResolver(params Assembly[] assemblies) 
     { 
      if (assemblies == null) 
       throw new ArgumentNullException("assemblies"); 

      if (assemblies.Length == 0) 
       throw new ArgumentException("Assemblies should be not empty.", "assemblies"); 

      _assemblies = assemblies; 
      AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; 
     } 

     public void Dispose() 
     { 
      AppDomain.CurrentDomain.AssemblyResolve -= OnAssemblyResolve; 
     } 

     private Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) 
     { 
      foreach (Assembly assembly in _assemblies) 
      { 
       if (args.Name == assembly.FullName) 
       { 
        return assembly; 
       } 
      } 

      return null; 
     } 

     private readonly Assembly[] _assemblies; 
    } 
} 

tej klasie muszą być utworzone przed pierwszym naborze do zespołu problem (na przykład w opakowaniu :: Initialize() metoda)

+0

Idealna. Wielkie dzięki. – Adam

+0

W jaki sposób załadowałeś zespoły, aby przejść do tej klasy narzędziowej? Raczej ... z jakiego kontekstu korzystałeś? 'Assembly.LoadFrom (nazwa pliku)'? Zastanawiam się, jak chronić tę samą wersję zespołu przed ładowaniem przez inną wtyczkę w innym kontekście? –

+1

Tak Używam 'Assembly.LoadFrom()' lub 'typeof (ClassFromMyAssembly) .Assembly' i odwołanie do' MyAssembly' w projekcie (dla 'System.Windows.Interactivity.dll'). Celem użycia 'ManualAssemblyResolver' pozwala Visual Studio załadować wszystkie zależne zespoły z dowolnego folderu i jawnie określić go w swoim kodzie. Do obsługi modularności używam MS Prism i konfiguruję ładowanie modułów w klasie 'Bootstrapper'. –