在 VSTO 插件中存储一些数据的最佳方式是什么?
What is the best way to store some data in VSTO addin?
我开发了一个 outlook 插件,必须打开或关闭。
为此我声明了一个静态变量,如下所示,
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) 开放的前景
2) 通过单击其徽标(在功能区中)启用加载项
3) 现在关闭outlook
4) 当我再次打开 outlook 时,它必须启用
那么我该如何实现呢?
您可以使用多种技术来实现此结果。确保您的设置必须在加载项启动期间序列化为某些 storage/deserialized。
一个可能的解决方案是为此使用注册表(在这种情况下可能是 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();
}
}
此类 stored/retrieved 变量应在加载项初始化期间用于设置您的属性。所以修改可能看起来像:
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");
}
其他选项可以序列化到文件 - 一些 class 设置序列化到即隔离存储、数据库(本地或中央)等。
设置可以作为隐藏(关联)项存储在文件夹中,例如收件箱或日历文件夹。例如,Outlook 将类别列表存储为日历文件夹中的隐藏项。 POP3 邮件 ID 存储在收件箱的隐藏项中。隐藏项的优点是漫游能力——Exchange邮箱用户可以从任何一台电脑上看到数据。
您可以在 OutlookSpy 中看到隐藏的项目(我是它的作者)- 单击 IMAPIFolder 按钮,转到“相关内容”选项卡。
以编程方式,可以使用 Outlook 对象模型中的 MAPIFolder.GetStorage 访问此类项目。
2018 年更新的答案
实现此目的的推荐方法现在是使用项目属性中已配置的设置文件。创建项目时这些文件是 auto-generated :
并在单击时打开以下 window :
您可以在任何地方以编程方式访问您的设置值 Properties.Settings.Default.Properties
。
“设置”页面顶部的 header 栏包含几个控件:
同步
同步将应用程序在 运行 时间或调试期间使用的 user-scoped 设置恢复为设计时定义的默认值。要恢复数据,请从磁盘而不是项目数据中删除 run-time 生成的 application-specific 文件。
加载网络设置
加载 Web 设置显示一个登录对话框,使您能够为经过身份验证的用户或匿名用户加载设置。仅当您在“服务”页面上启用了客户端应用程序服务并指定了 Web 设置服务位置时,此按钮才可用。
查看代码
对于 C# 项目,查看代码按钮使您能够查看 Settings.cs file
中的代码。此文件定义 Settings
class,它使您能够处理设置 object 上的特定事件。在 Visual Basic 以外的语言中,您必须显式调用此包装器 class 的 Save
方法才能保留用户设置。您通常在主窗体的 Closing
事件处理程序中执行此操作。以下是调用 Save
方法的示例:
C#
Properties.Settings.Default.Save();
对于 Visual Basic 项目,查看代码按钮使您能够查看 Settings.vb 文件中的代码。此文件定义 MySettings
class,使您能够处理 My.Settings
object 上的特定事件。有关使用 My.Settings
object 访问应用程序设置的详细信息,请参阅访问应用程序设置。
有关访问应用程序设置的详细信息,请参阅 Windows 表单的应用程序设置。
访问修饰符
访问修饰符按钮指定 Properties.Settings(在 C# 中)或 My.Settings
(在 Visual Basic 中)助手 classes 的访问级别 Visual Studio 在Settings.Designer.cs
或 Settings.Designer.vb
.
对于 Visual C# 项目,访问修饰符可以是 Internal 或 Public。
对于 Visual Basic 项目,访问修饰符可以是 Friend 或 Public。
默认情况下,该设置在 C# 中为 Internal,在 Visual Basic 中为 Friend。当 Visual Studio 将助手 class 生成为 Internal 或 Friend 时,可执行 (.exe) 应用程序无法访问您已添加到 class 库(.dll 文件)的资源和设置。如果您必须从 class 库共享资源和设置,请将访问修饰符设置为 Public。
有关设置助手 classes 的详细信息,请参阅管理应用程序设置。
设置网格
设置网格用于配置应用程序设置。此网格包括以下列:
姓名
在此字段中输入应用程序设置的名称。
类型
使用drop-down列表来select设置类型。最常用的类型出现在 drop-down 列表中,例如 String、(连接字符串)和 System.Drawing.Font。您可以通过 select 在列表末尾浏览,然后从 Select 类型对话框中 selecting 一种类型来选择另一种类型。选择类型后,它会添加到 drop-down 列表中的常见类型(仅适用于当前解决方案)。
范围
Select 应用程序或用户。
Application-scoped 设置(例如连接字符串)与应用程序关联。用户无法在 运行 时间更改 application-scoped 设置。
User-scoped 设置,例如系统字体,旨在用于用户首选项。用户可以在 运行 时间更改它们。
价值
与应用程序设置关联的数据或值。例如,如果设置是字体,则其值可能是 Verdana, 9.75pt, style=Bold
.
多年来我使用了多种方法来为用户存储配置数据。
Properties.Settings.Default.Properties,所以在应用项目属性中写。它很可靠,多年来一直为数百名用户服务,从未出现过问题。
文本形式的本地配置文件,因此写入用户已知区域并提供回退。在稳定的环境下,可以为用户选择home区域,read/write到本地config文件,这样也可以在出现故障需要手动更改时提供支持。作为后备,可以写入本地临时文件夹。
注册表是我在这种情况下没有使用的选项,但它可能是一个不错的选择。
性能可能是一个关键问题,因为它会影响用户的 UI。另一个问题是开发人员的易用性。对于两者,我的选择是在应用程序的属性中设置它,其中读写非常简单并在代码中处理,而且可能非常快。
写
Properties.Settings.Default.PropertyName = propertValue;
阅读
var propertValue = Properties.Settings.Default.PropertyName;
我开发了一个 outlook 插件,必须打开或关闭。
为此我声明了一个静态变量,如下所示,
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) 开放的前景
2) 通过单击其徽标(在功能区中)启用加载项
3) 现在关闭outlook
4) 当我再次打开 outlook 时,它必须启用
那么我该如何实现呢?
您可以使用多种技术来实现此结果。确保您的设置必须在加载项启动期间序列化为某些 storage/deserialized。
一个可能的解决方案是为此使用注册表(在这种情况下可能是 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();
}
}
此类 stored/retrieved 变量应在加载项初始化期间用于设置您的属性。所以修改可能看起来像:
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");
}
其他选项可以序列化到文件 - 一些 class 设置序列化到即隔离存储、数据库(本地或中央)等。
设置可以作为隐藏(关联)项存储在文件夹中,例如收件箱或日历文件夹。例如,Outlook 将类别列表存储为日历文件夹中的隐藏项。 POP3 邮件 ID 存储在收件箱的隐藏项中。隐藏项的优点是漫游能力——Exchange邮箱用户可以从任何一台电脑上看到数据。
您可以在 OutlookSpy 中看到隐藏的项目(我是它的作者)- 单击 IMAPIFolder 按钮,转到“相关内容”选项卡。
以编程方式,可以使用 Outlook 对象模型中的 MAPIFolder.GetStorage 访问此类项目。
2018 年更新的答案
实现此目的的推荐方法现在是使用项目属性中已配置的设置文件。创建项目时这些文件是 auto-generated :
并在单击时打开以下 window :
您可以在任何地方以编程方式访问您的设置值 Properties.Settings.Default.Properties
。
“设置”页面顶部的 header 栏包含几个控件:
同步
同步将应用程序在 运行 时间或调试期间使用的 user-scoped 设置恢复为设计时定义的默认值。要恢复数据,请从磁盘而不是项目数据中删除 run-time 生成的 application-specific 文件。
加载网络设置
加载 Web 设置显示一个登录对话框,使您能够为经过身份验证的用户或匿名用户加载设置。仅当您在“服务”页面上启用了客户端应用程序服务并指定了 Web 设置服务位置时,此按钮才可用。
查看代码
对于 C# 项目,查看代码按钮使您能够查看 Settings.cs file
中的代码。此文件定义 Settings
class,它使您能够处理设置 object 上的特定事件。在 Visual Basic 以外的语言中,您必须显式调用此包装器 class 的 Save
方法才能保留用户设置。您通常在主窗体的 Closing
事件处理程序中执行此操作。以下是调用 Save
方法的示例:
C#
Properties.Settings.Default.Save();
对于 Visual Basic 项目,查看代码按钮使您能够查看 Settings.vb 文件中的代码。此文件定义 MySettings
class,使您能够处理 My.Settings
object 上的特定事件。有关使用 My.Settings
object 访问应用程序设置的详细信息,请参阅访问应用程序设置。
有关访问应用程序设置的详细信息,请参阅 Windows 表单的应用程序设置。
访问修饰符
访问修饰符按钮指定 Properties.Settings(在 C# 中)或 My.Settings
(在 Visual Basic 中)助手 classes 的访问级别 Visual Studio 在Settings.Designer.cs
或 Settings.Designer.vb
.
对于 Visual C# 项目,访问修饰符可以是 Internal 或 Public。
对于 Visual Basic 项目,访问修饰符可以是 Friend 或 Public。
默认情况下,该设置在 C# 中为 Internal,在 Visual Basic 中为 Friend。当 Visual Studio 将助手 class 生成为 Internal 或 Friend 时,可执行 (.exe) 应用程序无法访问您已添加到 class 库(.dll 文件)的资源和设置。如果您必须从 class 库共享资源和设置,请将访问修饰符设置为 Public。
有关设置助手 classes 的详细信息,请参阅管理应用程序设置。
设置网格
设置网格用于配置应用程序设置。此网格包括以下列:
姓名
在此字段中输入应用程序设置的名称。
类型
使用drop-down列表来select设置类型。最常用的类型出现在 drop-down 列表中,例如 String、(连接字符串)和 System.Drawing.Font。您可以通过 select 在列表末尾浏览,然后从 Select 类型对话框中 selecting 一种类型来选择另一种类型。选择类型后,它会添加到 drop-down 列表中的常见类型(仅适用于当前解决方案)。
范围
Select 应用程序或用户。
Application-scoped 设置(例如连接字符串)与应用程序关联。用户无法在 运行 时间更改 application-scoped 设置。
User-scoped 设置,例如系统字体,旨在用于用户首选项。用户可以在 运行 时间更改它们。
价值
与应用程序设置关联的数据或值。例如,如果设置是字体,则其值可能是 Verdana, 9.75pt, style=Bold
.
多年来我使用了多种方法来为用户存储配置数据。
Properties.Settings.Default.Properties,所以在应用项目属性中写。它很可靠,多年来一直为数百名用户服务,从未出现过问题。
文本形式的本地配置文件,因此写入用户已知区域并提供回退。在稳定的环境下,可以为用户选择home区域,read/write到本地config文件,这样也可以在出现故障需要手动更改时提供支持。作为后备,可以写入本地临时文件夹。
注册表是我在这种情况下没有使用的选项,但它可能是一个不错的选择。
性能可能是一个关键问题,因为它会影响用户的 UI。另一个问题是开发人员的易用性。对于两者,我的选择是在应用程序的属性中设置它,其中读写非常简单并在代码中处理,而且可能非常快。
写
Properties.Settings.Default.PropertyName = propertValue;
阅读
var propertValue = Properties.Settings.Default.PropertyName;