在Visual Studio扩展中包括外部.dll [英] Include external .dll in Visual Studio Extension
问题描述
使用外部库进行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:
- 使用Assets包含来自他们的包裹位置。这将在解决方案中创建两个项目,这些项目的 Include in VSIX属性均设置为true,这不起作用
- 包括项目,然后添加BuiltProjectOutputGroup; BuiltProjectOutputGroupDependencies; GetCopyToOutputDirectoryItems; SatelliteDllsProjectOutputGroup ;引用的不包含在VSIX中的其他组属性
- 使用资产将库作为项目包括在内,不起作用
所以现在我快要结束了,因为似乎没有什么工作...。
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屋!