17

私の質問はこれと非常に似ていますが、答えと回避策がうまく機能していないという点だけです。また、私はVisualStudio2012にいます。

他のdllに依存している別のプロジェクトを参照しているVSPackageがあります。パッケージをデバッグで実行するたびに、他のdllが見つからないという例外が発生します。それらは出力ディレクトリにあり、署名されています。

VSPackageプロジェクトで直接参照してみましたが無駄でした。

考え?

4

1 に答える 1

42

この問題は、拡張機能がこれらのアセンブリに明示的に依存していない場合、VisualStudioが拡張機能のフォルダー内のアセンブリを検索しないために発生します。たとえば、構成ファイル(IoC config)またはxamlコードで設定された依存関係。私はこの問題に対する3つの解決策を知っています:

  1. これらのアセンブリはGACに配置でき、VisualStudioによって読み込まれます。この方法は、GACで使用するために構築されたサードパーティのライブラリ(MS Enterprise Libraryなど)を使用する場合に適しています。ただし、VSIX展開パッケージではGACにアセンブリをインストールできないため、MSIインストーラーを使用できます。

  2. Visual Studio 2010/2012のVSPackagesの場合、ProvideBindingPath属性を使用できます。拡張機能が配置されているパスは、VisualStudioが依存アセンブリを検索するために使用するパスに追加されます。拡張機能にVSPackageが含まれていない場合は、この属性を任意のパブリッククラスに追加できます(ここを参照)。

    [ProvideBindingPath] 
    public class MyVsPackage : Package 
    { /* ... */ }
    
  3. アセンブリ名は手動で解決できます。これを行うには、AssemblyResolveイベントをサブスクライブし、ハンドラーから必要なアセンブリを返す必要があります。これは最も柔軟な方法です。以前の方法を使用できない場合は、これが特に適しています。

    私のIntelliDebuggerプロジェクトでは、そのためのクラスManualAssemblyResolverを作成しました。

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

このクラスは、問題のあるアセンブリを最初に呼び出す前に作成する必要があります(たとえば、Pac​​kage :: Initialize()メソッドで)

于 2012-12-07T15:15:01.470 に答える