在Visual Studio扩展中包括外部.dll [英] Include external .dll in Visual Studio Extension

查看:145
本文介绍了在Visual Studio扩展中包括外部.dll的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用外部库进行Visual Studio扩展时遇到问题。目前,我拥有自己的NuGet服务器,用于托管我的库,现在由于我不想两次使用功能,因此我从扩展中提取了一些功能到现有的库中。

I have a problem using external libraries for my visual studio extension. Currently I have my own NuGet server on which I host my libraries, now since I dont want functionality twice I extracted some functions out of my extension into an existing library.

但是问题是,每当我想使用该程序集中的任何内容时,我都不能这样做,因为Visual Studio在.vsix程序包中不包含.dll。

The problem is however that whenever I want to use anything from that assembly I can not do so, since visual studio does not include the .dlls in the .vsix package.

到目前为止,我已经尝试过:

So far I have tried:


  1. 使用Assets包含来自他们的包裹位置。这将在解决方案中创建两个项目,这些项目的 Include in VSIX属性均设置为true,这不起作用

  2. 包括项目,然后添加BuiltProjectOutputGroup; BuiltProjectOutputGroupDependencies; GetCopyToOutputDirectoryItems; SatelliteDllsProjectOutputGroup ;引用的不包含在VSIX中的其他组属性

  3. 使用资产将库作为项目包括在内,不起作用

所以现在我快要结束了,因为似乎没有什么工作...。

So now I am at my end since there is nothing that seems to work....

我发现的解决方案已经建议了我尝试的所有步骤,但是在这一点上

The solutions I found are already suggesting all the steps I tried, but at this point

我还发现了这两个与我的问题相同的帖子,但是这些答案没有用对我来说就像我说的那样。

I also found these two post which are the same as my question but those answerts did not work for me like I said.

推荐答案

好吧,我找到了一种方法,它是两个答案的组合我在这里发现了堆栈溢出。

Okay I found a way to do it, its a combonation of two answers I found here on stack overflow.

尽管它有点怪异,但我认为这是唯一的可能。

And eventhough its a bit hacky I suppose its the only way possible.

因此,我只是简单地使用现有的ManualAssemblyResolver并将其调整为我的需要,结果是:

So I simply used the existing ManualAssemblyResolver and adjusted it to my needs, the Result being this:

public class ManualAssemblyResolver : IDisposable
{
    #region Attributes

    /// <summary>
    /// list of the known assemblies by this resolver
    /// </summary>
    private readonly List<Assembly> _assemblies;

    #endregion

    #region Properties

    /// <summary>
    /// function to be called when an unknown assembly is requested that is not yet kown
    /// </summary>
    public Func<ResolveEventArgs, Assembly> OnUnknowAssemblyRequested { get; set; }

    #endregion

    #region Constructor

    public ManualAssemblyResolver(params Assembly[] assemblies)
    {
        _assemblies = new List<Assembly>();

        if (assemblies != null)
            _assemblies.AddRange(assemblies);

        AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
    }

    #endregion

    #region Implement IDisposeable

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

    #endregion

    #region Private

    /// <summary>
    /// will be called when an unknown assembly should be resolved
    /// </summary>
    /// <param name="sender">sender of the event</param>
    /// <param name="args">event that has been sent</param>
    /// <returns>the assembly that is needed or null</returns>
    private Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
    {
        foreach (Assembly assembly in _assemblies)
            if (args.Name == assembly.FullName)
                return assembly;

        if (OnUnknowAssemblyRequested != null)
        {
            Assembly assembly = OnUnknowAssemblyRequested(args);

            if (assembly != null)
                _assemblies.Add(assembly);

            return assembly;
        }

        return null;
    }

    #endregion
}

之后我使用Addition ExtensionManager来获取扩展的安装路径。看起来像这样

After that I used an Addition ExtensionManager to get the installation path of the extension. Which looks like this

public class ExtensionManager : Singleton<ExtensionManager>
{
    #region Constructor

    /// <summary>
    /// private constructor to satisfy the singleton base class
    /// </summary>
    private ExtensionManager()
    {
        ExtensionHomePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Definitions.Constants.FolderName);

        if (!Directory.Exists(ExtensionHomePath))
            Directory.CreateDirectory(ExtensionHomePath);

        SettingsFileFullname = Path.Combine(ExtensionHomePath, Definitions.Constants.SettingsFileName);

        InstallationPath = Path.GetDirectoryName(GetType().Assembly.Location);
    }

    #endregion

    #region Properties

    /// <summary>
    /// returns the installationPath
    /// </summary>
    public string InstallationPath { get; private set; }

    /// <summary>
    /// the path to the directory where the settings file is located as well as the log file
    /// </summary>
    public string ExtensionHomePath { get; private set; }

    /// <summary>
    /// the fullpath to the settingsfile
    /// </summary>
    public string SettingsFileFullname { get; private set; }

    #endregion
}

然后在Initialize( )的Package方法,您需要创建一个ManualAssemblyResolver实例,并提供所需的程序集路径,如下所示:

Then in the Initialize() method of the Package you will need to create an instance of the ManualAssemblyResolver and provide the Path to the assemblies you need like this:

    #region Attributes

    private ManualAssemblyResolver _resolver;

    #endregion

    #region Override Microsoft.VisualStudio.Shell.Package

    /// <summary>
    /// Initialization of the package; this method is called right after the package is sited, so this is the place
    /// where you can put all the initialization code that rely on services provided by VisualStudio.
    /// </summary>
    protected override void Initialize()
    {
        _resolver = new ManualAssemblyResolver(
        Assembly.LoadFrom(Path.Combine(ExtensionManager.Instance.InstallationPath, Definitions.Constants.NameOfAssemblyA)),
        Assembly.LoadFrom(Path.Combine(ExtensionManager.Instance.InstallationPath, Definitions.Constants.NameOfAssemblyB))
        );

请注意,您需要先调用此函数,否则它甚至不会涉及引用程序集的任何内容,否则会会抛出FileNotFoundException。

Note that you will need to call this before anythingelse that even touches anything from the referenced assemblies, otherwise a FileNotFoundException will be thrown.

无论如何,这似乎现在对我有用,但我希望有一种更清洁的方法。因此,如果有人有更好的方法(实际上是从.vsix包中包含并检查程序集的方法),请发布答案。

In any case this seems to work for me now but I wish there was a cleaner way to do it. So if anybody has a better way (a way that actually includes and lloks up the assemblies from the .vsix package) then please post an answer.

编辑:
好的,现在我发现了真正的问题,这仅仅是因为这些dll是附属dll(设置了它们的汇编语言),所以它们不可见...。

Okay now I found the real issue, it was simply the fact that the dlls were satellite dll (the had their assembly culture set) so they were not visible....

但是,当它们仍然是卫​​星dll时,上述修复程序仍然有效。

However the above fix worked when they were still satillite dlls.

这篇关于在Visual Studio扩展中包括外部.dll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆