VSTO插件中存储数据的最佳方法是什么?

3
我已经开发了一个Outlook插件,需要开启或关闭。
为了实现这一点,我声明了一个静态变量,如下所示:

static bool isEnabled = false;

ThisAddIn.cs

public static bool isAddInOn = false;

RibbonButton.cs

    private void btnRibbon_Click(object sender, RibbonControlEventArgs e)
    {
        if (ThisAddIn.isAddInOn )
        {

            ThisAddIn.isAddInOn = false; 
            btnRibbon.Label = "Disabled";

        }
        else
        {

            ThisAddIn.isAddInOn = true;
            btnRibbon.Label = "Enabled";


        }
    }

它正在工作。但是当我关闭 Outlook 并再次打开时,静态变量会重新设置。这意味着当我默认打开 Outlook 时,我的插件处于禁用状态。

我只想将该值存储在某个位置。这样当 Outlook 重新打开时,我可以检查该值。

情景:

1)打开 Outlook

2)通过单击其标志(位于功能区中)启用插件

3)现在关闭 Outlook

4)当我再次打开 Outlook 时,它必须启用

那么我该如何实现这一点?

4个回答

6

有几种技术可以用来实现这个结果。你的设置肯定要序列化到某个存储中/在插件启动期间反序列化。

其中一种可能的解决方案是使用注册表(在这种情况下,可能是HKCU(当前用户),然后它将对每个使用您的插件的用户私有,并且不需要特殊权限。

如果要存储变量:

    public void StoreInRegistry(string keyName, string value)
    {
        RegistryKey rootKey = Registry.CurrentUser;
        string registryPath = @"Software\YourCompanyName\YourAddInName";
        using (RegistryKey rk = rootKey.CreateSubKey(registryPath))
        {
            rk.SetValue(keyName, value, RegistryValueKind.String);
        }
    }

读取变量:

    public string ReadFromRegistry(string keyName, string defaultValue)
    {
        RegistryKey rootKey = Registry.CurrentUser;
        string registryPath = @"Software\YourCompanyName\YourAddInName";
        using (RegistryKey rk = rootKey.OpenSubKey(registryPath, false))
        {
            if (rk == null)
            {
                return defaultValue;
            }

            var res = rk.GetValue(keyName, defaultValue);
            if (res == null)
            {
                return defaultValue;
            }

            return res.ToString();
        }
    }

存储/检索的变量应该在插件初始化时使用来设置您的属性。因此,修改后可能如下所示: ThisAddin.cs
public static bool isAddInOn = ReadFromRegistry("MySetting1", "0") == "1";

RibbonButton.cs

private void btnRibbon_Click(object sender, RibbonControlEventArgs e)
{
    if (ThisAddIn.isAddInOn )
    {

        ThisAddIn.isAddInOn = false; 
        btnRibbon.Label = "Disabled";

    }
    else
    {

        ThisAddIn.isAddInOn = true;
        btnRibbon.Label = "Enabled";


    }
    StoreInRegistry("MySetting1", ThisAddIn.isAddInOn ? "1" : "0");
}

其他选项包括将设置序列化到文件中,可以使用一些类似于独立存储、数据库(本地或中央)等的序列化方案。


谢谢您的建议。但是如果用户没有管理员权限,是否仍然可以更改注册表? - Aijaz Chauhan
1
用户始终拥有对HKCU中的键的读写权限(不像HKLM),除非特定键上的权限被显式重置。 - Dmitry Streblechenko

3

多年来,我使用了几种方法来存储用户的配置数据。

  • Properties.Settings.Default.Properties,因此在应用程序项目属性中编写。它很稳定,多年来数百个用户使用未曾出现问题。

  • 本地文本配置文件,在已知区域为用户编写并进行回退。在稳定的环境中,可以选择用户的主目录,并读写本地配置文件,这也使得支持人员可以访问并在需要手动更改时进行更改。作为备选方案,可以将其写入本地临时文件夹。

  • 注册表是我在这种情况下没有使用过的选项,但很可能是一个不错的选择。

性能很可能是关键问题,因为它会影响用户界面。另一个问题是开发人员的易用性。对于这两个问题,我的选择是在应用程序的属性中设置它,其中读取和编写非常简单,并在代码内部处理,很可能非常快速。

写入

Properties.Settings.Default.PropertyName = propertValue;

阅读

var propertValue = Properties.Settings.Default.PropertyName;

2

2018年更新的答案

现在推荐实现此功能的方法是使用项目属性中已配置的设置文件。这些文件会在创建项目时自动生成:

enter image description here

并且当单击时打开以下窗口:

enter image description here

您可以在任何位置以编程方式访问您的设置值,如Properties.Settings.Default.Properties

设置页顶部的标题栏包含几个控件:

同步

同步将运行时或调试期间应用程序使用的用户范围设置恢复为其设计时定义的默认值。要恢复数据,请从磁盘中删除运行时生成的特定于应用程序的文件,而不是从项目数据中删除。

加载 Web 设置

加载 Web 设置显示一个登录对话框,可让您为经过身份验证或匿名用户加载设置。仅当您在服务页面上启用了客户端应用程序服务并指定了 Web 设置服务位置时,才会启用此按钮。

查看代码

对于 C# 项目,查看代码按钮使您可以查看 Settings.cs 文件 中的代码。此文件定义了Settings类,它使您能够处理设置对象上的特定事件。在除 Visual Basic 以外的语言中,您必须显式调用此包装器类的 Save 方法,以便持久化用户设置。通常在主窗体的 Closing 事件处理程序中执行此操作。以下是调用 Save 方法的示例: C#

Properties.Settings.Default.Save();

对于Visual Basic项目,"View Code"按钮使您可以查看Settings.vb文件中的代码。该文件定义了MySettings类,使您能够处理My.Settings对象上的特定事件。有关使用My.Settings对象访问应用程序设置的更多信息,请参阅访问应用程序设置。
有关访问应用程序设置的更多信息,请参阅Windows Forms应用程序设置。
访问修饰符按钮指定Visual Studio在Settings.Designer.cs或Settings.Designer.vb中生成的Properties.Settings(C#)或My.Settings(Visual Basic)辅助类的访问级别。
对于Visual C#项目,访问修饰符可以是Internal或Public。
对于Visual Basic项目,访问修饰符可以是Friend或Public。
默认情况下,C#中的设置为Internal,而Visual Basic中的设置为Friend。当Visual Studio生成帮助器类作为Internal或Friend时,可执行(.exe)应用程序无法访问您添加到类库(.dll文件)中的资源和设置。如果必须共享来自类库的资源和设置,请将访问修饰符设置为Public。
有关设置辅助类的更多信息,请参阅管理应用程序设置。
设置网格用于配置应用程序设置。此网格包括以下列:
名称:在此字段中输入应用程序设置的名称。
类型:使用下拉列表选择设置的类型。下拉列表中显示最常用的类型,例如String、(连接字符串)和System.Drawing.Font。您可以通过选择列表末尾的"浏览",然后从"选择类型"对话框中选择一个类型来选择另一个类型。选择类型后,它将添加到下拉列表中的常见类型中(仅适用于当前解决方案)。
范围:选择应用程序或用户。
与应用程序关联的应用程序范围设置(例如连接字符串)。用户无法在运行时更改应用程序范围设置。
用户范围设置(例如系统字体)旨在用于用户首选项。用户可以在运行时更改它们。
值:与应用程序设置相关联的数据或值。例如,如果设置是字体,则其值可以是Verdana、9.75pt、style=Bold。

文档链接

读取设置

写入设置


现在实现这一点的推荐方式是什么?由谁推荐?请记住,Outlook插件与常规应用程序不同。本地(文件或注册表)设置可用于本地数据(例如窗口大小和位置),而全局设置可以漫游 - 将设置存储为默认文件夹之一中的隐藏项使它们可以从访问该邮箱的任何机器访问(在Exchange的情况下),即使在PST存储的情况下,您的设置也将存储/配置文件特定 - 您需要记住用户可以拥有多个本地Outlook配置文件。 - Dmitry Streblechenko
由谁?由微软自己。这些设置默认嵌入在您的程序中,并根据给定文档可以是公共的或私有的。 - Treycos
是的,这就是为什么我解释了插件与其他Windows应用程序不同的原因。 - Dmitry Streblechenko

-1

设置可以作为隐藏项存储在文件夹中,例如收件箱或日历文件夹中的关联项。例如,Outlook将类别列表存储为日历文件夹中的隐藏项。POP3消息ID存储在收件箱中的隐藏项中。隐藏项的优点是漫游功能-Exchange邮箱用户可以从任何计算机上查看数据。

您可以在OutlookSpy(我是其作者)中查看隐藏项-单击IMAPIFolder按钮,转到“关联内容”选项卡。

通过编程方式,可以使用Outlook对象模型中的MAPIFolder.GetStorage访问此类项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接