【问题标题】:VSIX Extension uses 3rd party DLLs unable to load one of the dependencyVSIX 扩展使用无法加载依赖项之一的第 3 方 DLL
【发布时间】:2013-11-15 12:32:58
【问题描述】:

我正在开发 VS2013 的扩展。由于它将通过 MSI 安装,因此我将使用 ProvideBindingPath 属性将基本目录更改为安装文件夹到包类。但是将在运行时加载的第 3 方 dll 引用不会从探测路径中选择 dll。它总是查看 Visual Studio devenv.exe 文件夹。有什么办法可以强制 dll 查看我的安装文件夹。

using MD=Microsoft.VisualStudio.Modeling.Shell;

MD.ProvideBindingPath(SubPath = @"")]
public sealed class AutomationCommandPanePackage : Package
    { 

     public AutomationCommandPanePackage()        
     {

        string installationPath = HelperMethods.GetInstallationPath();

        if (string.IsNullOrEmpty(HelperMethods.GetInstallationPath())) return;

        // Change default config file at runtime.
        using (AutomationConfigurationManager.Change(installationPath, "AutomationPro.config"))
        {
            // Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
        }            

        Assembly a = Assembly.GetExecutingAssembly();
        Type type = a.GetType("AutomationCommandPanePackage", true);
        System.Reflection.MemberInfo info = type;
        var attributes = info.GetCustomAttributes(true);

        foreach (var attrib in attributes)
        {
            if (attrib is MD.ProvideBindingPathAttribute)
            {
                ((MD.ProvideBindingPathAttribute)attrib).SubPath = installationPath;
                break;
            }
        }            

【问题讨论】:

  • ProvideBindingPath 属性是否已移至另一个命名空间;在 VS2012 和之前,此类型位于 Microsoft.VisualStudio.Shell。我会尽量不初始化 SubPath 属性。并且:程序集元数据是只读的;我会说在反射属性上设置SubPath 属性没有任何效果...
  • Matze,ProvideBindingPath 属性没有移动到任何其他命名空间,它来自建模类。 [链接] (msdn.microsoft.com/en-us/library/…) 在 VS2010 上运行良好。当我将代码迁移到 2013 时,问题就开始了。同一段代码不起作用。
  • 我使用 System.Runtime.InteropServices 中的 LoadLibrary() 解决了问题;因为我要加载的 dll 是 COM iterop。 public static class win32 { [DllImport("kernel32.dll")] public static extern IntPtr LoadLibrary(string dllToLoad); [DllImport("kernel32.dll")] public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); [DllImport("kernel32.dll")] public static extern bool FreeLibrary(IntPtr hModule);在 package.cs 我写了这个 win32.LoadLibrary(Path.Combine(installationPath, "apidsp_windows.dll"));
  • 有两个属性类同名,但用途不同。可以解决问题的属性类在Microsoft.VisualStudio.Shell 命名空间中声明。见:msdn.microsoft.com/en-us/library/…

标签: visual-studio-2012 dll visual-studio-extensions vsx vsix


【解决方案1】:

我已经能够使用以下代码在我的扩展中成功加载第三方 (telerik) 程序集。

在你的 Package 类构造函数中注册AssemblyResolve 事件

AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;

然后在处理程序加载包如下:

string path = Assembly.GetExecutingAssembly().Location;
path = Path.GetDirectoryName(path);

if (args.Name.ToLower().Contains("telerik.windows.controls.gridview"))
{
       path = Path.Combine(path, "telerik.windows.controls.gridview.dll");
       Assembly ret = Assembly.LoadFrom(path);
       return ret;
}

我对上述方法没有任何问题。

【讨论】:

  • 谢谢,Utkarsh,在我的情况下,dll 在执行路径中不可用。 MSI 会将它们放在安装文件夹中。
【解决方案2】:

我解决了问题 LoadLibrary() 来自

System.Runtime.InteropServices; 

因为我要加载的 dll 是一个 COM iterop dll。

public static class win32 
{ 
[DllImport("kernel32.dll")] 
public static extern IntPtr LoadLibrary(string dllToLoad); 
[DllImport("kernel32.dll")] 
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); [DllImport("kernel32.dll")] 
public static extern bool FreeLibrary(IntPtr hModule);
}

在 package.cs 我像这样加载程序集

win32.LoadLibrary(Path.Combine(installationPath, "apidsp_windows.dll")); 

【讨论】:

  • 你把上面的代码放在哪里了([DLLImport(...)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-02
  • 1970-01-01
  • 2021-08-05
  • 2011-05-23
  • 1970-01-01
相关资源
最近更新 更多