VSIX - 无法加载引用的dll的文件或程序集

时间:2012-12-02 22:47:46

标签: visual-studio-2012 vsix vspackage

我的问题与this one非常相似,只是答案和解决方法对我不起作用。我也在Visual Studio 2012中。

我有一个引用另一个项目的VSPackage,它依赖于其他dll。每次我在调试中运行我的包时,都会得到一个异常,即无法找到其他dll。它们位于输出目录中,并且已签名。

我尝试直接通过VSPackage项目引用它们无济于事。

思想?

1 个答案:

答案 0 :(得分:35)

存在此问题是因为如果扩展程序没有明确依赖于这些程序集,则Visual Studio不会在扩展文件夹中查找程序集。例如,在配置文件(IoC配置)或xaml代码中设置的依赖关系。我知道这个问题的三个解决方案:

  1. 您可以在GAC中部署这些程序集,Visual Studio将加载它们。如果您使用构建用于GAC的第三方库(例如,MS Enterprise Library),则此方法很有用。但是VSIX Deployment Package不允许在GAC中安装程序集,您可以使用MSI安装程序。

  2. 对于Visual Studio 2010/2012的VSPackages,您可以使用ProvideBindingPath属性。扩展所在的路径将添加到Visual Studio用于查找从属程序集的路径中。如果您的扩展程序不包含VSPackage,则可以将此属性添加到任何公共类(see here)。

    [ProvideBindingPath] 
    public class MyVsPackage : Package 
    { /* ... */ }
    
  3. 您可以手动解析程序集名称。为此,您需要订阅AssemblyResolve事件,并且需要从处理程序返回所需的程序集。这是最灵活的方式,如果你不能使用以前的方法,这特别适合你。

    在我的IntelliDebugger项目中,我为它写了一个类ManualAssemblyResolver:

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

    必须在第一次调用问题程序集之前创建此类(例如,在Package :: Initialize()方法中)