本文介绍了Visual Studio扩展:从任意DLL访问VS选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发我的第一个VS扩展,它需要向用户提供一些选项.遵循 https://msdn.microsoft.com/en-us/library/bb166195. aspx ,创建我自己的选项页面非常容易.但是,我还没有找到如何阅读我的选择的方法.

I'm currently developing my first VS extension, which needs to provide some options to the user. Following https://msdn.microsoft.com/en-us/library/bb166195.aspx, it was rather easy to come up with my own options page. However, I have not yet found out how to read my options.

我的扩展程序的解决方案结构如下:

The solution structure of my extension is as follows:

MySolution
  MyProject (generates a DLL from C# code)
  MyProjectVSIX

按照上面引用的教程,我在VSIX项目中添加了VS Package并按照说明进行了配置.因此,我的选项"页面及其选项显示在工具/选项"下.好的!这是我的DialogPage实现:

Following the tutorial cited above, I have added a VS Package to my VSIX project and configured it as described. As a result, my options page with my options is shown under Tools/Options. Nice! Here's my DialogPage implementation:

public class OptionPageGrid : DialogPage
{
    private bool myOption = false;

    [Category(Options.CATEGORY_NAME)]
    [DisplayName("My option")]
    [Description("Description of my option.")]
    public bool MyOption
    {
        get { return myOption; }
        set { myOption = value; }
    }
}

这是我的Package课程的负责人:

And here's the head of my Package class:

[PackageRegistration(UseManagedResourcesOnly = true)]
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]     [Guid(MyOptionsPage.PackageGuidString)]
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")]
[ProvideOptionPage(typeof(OptionPageGrid), Options.CATEGORY_NAME, Options.PAGE_NAME, 0, 0, true)]
public sealed class MyOptionsPage : Package, IOptions
{
    ...

但是,我现在想阅读这些选项,并且想从MyProject(它不依赖MyProjectVSIX)中进行操作.这就是我迷路的地方.我的第一个尝试是让我的Package实现一个IOptions接口,并通过从Package的构造函数中调用一个静态方法Options.Register(IOptions)使其进行注册.这有效(即Register()中的断点被击中),但是当我尝试读取选项时,静态IOptions实例仍然为null.我的假设是,这是由于代码是从不同的进程执行的(这超出了我的控制范围).

However, I now want to read those options, and I want to do it from MyProject (which does not have a dependency on MyProjectVSIX). And this is where I'm kind of lost. My first attempt was to let my Package implement an IOptions interface, and to let it register itself by calling a static method Options.Register(IOptions) from the Package's constructor. This works (i.e., the breakpoint in Register() is hit), but when I try to read options, the static IOptions instance is still null. My assumption is that this is due to the fact that the code is executed from different processes (which is beyond my control).

经过更多的谷歌搜索后,我尝试获取DTE对象的实例(如果我正确理解的话,该实例将允许我阅读我的选择),但是没有成功.我尝试了几种变体,包括在 https://msdn.microsoft .com/en-us/library/ee834473.aspx

After some more googling, I tried to get an instance of the DTE object (which would allow me to read my options if I correctly understood), but to no success. I've tried several variants, including the one described at https://msdn.microsoft.com/en-us/library/ee834473.aspx and

DTE Dte = Package.GetGlobalService(typeof(DTE)) as DTE;

我总是以空引用结尾.

最后,由于本教程建议通过Package实例访问选项,因此我试图弄清楚如何通过某种注册表来获取VS Package的此类实例(我可以将其转换为IOptions),但还是没有运气.

Finally, since the tutorial suggested to access the options through the instance of Package, I tried to figure out how to obtain such an instance of my VS Package through some kind of registry (which I could than cast to IOptions), but again without luck.

有人可以指出我正确的方向吗?还是不可能从非VSIX项目访问VS选项?

Can anybody please point me to the right direction? Or is it even impossible to access VS options from a non-VSIX project?

更新:我做了更多研究,但缺少一条信息:我的扩展是单元测试适配器.这似乎暗示测试发现代码和测试执行代码是从不同的进程运行的,即我的假设是正确的.

Update: I have done some more research, and one piece of information was missing: My extension is a Unit Test Adapter. This seems to imply that the test discovery code as well as the test execution code are run from different processes, i.e., my assumption was right.

在此期间,我设法访问了正在运行的VS实例的DTE对象(一旦问题解决,我将在完整的解决方案中发布该对象),但是在访问选项时仍然遇到问题.实际上,以下代码(从此处复制: https://msdn.microsoft. com/zh-CN/library/ms165641.aspx )效果很好:

I have in the meantime managed to access the DTE object of the VS instance I'm running in (I will post that with my complete solution as soon as my problem is solved), but still have problems accessing the options. In fact, the following code (copied from here: https://msdn.microsoft.com/en-us/library/ms165641.aspx) works nicely:

Properties txtEdCS = DTEProvider.DTE.get_Properties("TextEditor", "CSharp");
Property prop = null;
string msg = null;
foreach (EnvDTE.Property temp in txtEdCS)
{
    prop = temp;
    msg += ("PROP NAME: " + prop.Name + "   VALUE: " + prop.Value) + "\n";
}
MessageBox.Show(msg);

但是,如果我将上述内容更改如下:

However, if I change the above as follows:

Properties txtEdCS = DTEProvider.DTE.get_Properties(CATEGORY_NAME, PAGE_NAME);

现在代码崩溃.奇怪的是,我可以在HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0Exp_Config\AutomationProperties\My Test Adapter\General下的注册表中看到我的属性类别和页面.搜索我的属性会在HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0Exp\ApplicationPrivateSettings\MyProjectVSIX\OptionPageGrid下显示它们(之所以如此,是因为我添加了

Now the code crashes. Weirdly enough, I can see my property category and page in the registry under HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0Exp_Config\AutomationProperties\My Test Adapter\General. Searching for my properties shows them under HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0Exp\ApplicationPrivateSettings\MyProjectVSIX\OptionPageGrid (mabye because I added

OptionPageGrid Page = (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
Page.SaveSettingsToStorage();

使用PackageInitialize()方法(如Matze建议的那样),可能是因为我以前没有看过:-)).

to the Package's Initialize() method (as Matze suggested), maybe because I haven't looked there before :-) ).

那么如何读取我的属性?

So how to read my properties?

推荐答案

VS测试适配器框架恰好具有用于跨进程共享设置的API.由于根本没有记录任何文件,因此花了一些时间才弄清楚如何使用该API.有关工作示例,请参见此GitHub项目.

The VS test adapter framework happens to have API for sharing settings accross processes. Since nothing is documented at all, it took a while to figure out how to use that API. For a working example see this GitHub project.

更新: vstest 框架最近已由MS开源.

Update: The vstest framework has recently been open-sourced by MS.

这篇关于Visual Studio扩展:从任意DLL访问VS选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 09:43