VSPackage 能从 Visual Studio 集成开发环境 (ide) 导入设置 (IDE)。 IDE 使用 IVsUserSettings 接口的 VSPackage 中实现确定 VSPackage 的配置方式进行检索。
备注
托管包框架 (MPF)提供一组托管类实现 Visual Studio 扩展的创建。使用 MPF,若要执行此任务,请参见 如何:使用托管包结构的导入设置。
实现在 VSPackage 中设置导入
基本的实现用于 Visual Studio 设置 framework 支持。
为支持设置结构的 VSPackage 通过定义一个或多个自定义下落点注册。
有关更多信息,请参见 保留的设置。
声明 VSPackage 实现 IVsUserSettings 接口,如:
public class MyPackage : IVsPackage, IVsUserSettings, IVsUserSettingsQuery
确保 QueryInterface 方法的 VSPackage 中实现提供一 IVsUserSettings 接口,在调用与 IID_IVsUserSettings。 例如:
STDMETHODIMP MyPackage::QueryInterface(THIS_ REFIID riid, LPVOID FAR* ppvObj) { if (ppvObj == NULL) return E_POINTER; *ppvObj = NULL; if (riid == IID_IUnknown) *ppvObj = (LPVOID)(IUnknown *)(IClassFactory*)this; else if (riid == IID_IClassFactory) *ppvObj = (LPVOID)(IClassFactory *)this; else if (riid == IID_IVsPackage) *ppvObj = (LPVOID)(IVsPackage *)this; else if (riid == IID_IVsPersistSolutionOpts) *ppvObj = (LPVOID)(IVsPersistSolutionOpts *)this; else if (riid == IID_IVsPersistSolutionProps) *ppvObj = (LPVOID)(IVsPersistSolutionProps *)this; else if (riid == IID_IVsComponentSelectorProvider) *ppvObj = (LPVOID)(IVsComponentSelectorProvider *)this; else if (riid == IID_IVsUserSettings) *ppvObj = (LPVOID)(IVsUserSettings *)this; else if (riid == IID_IVsUserSettingsQuery) *ppvObj = (LPVOID)(IVsUserSettingsQuery *)this; if (*ppvObj) { AddRef(); return NOERROR; } return E_NOINTERFACE; }
检索安装信息。
若要支持检索安装信息, VSPackage 必须执行 ImportSettings 方法。
若要读取数据, IVsUserSettings 接口的 VSPackage 的实现必须使用 IDE 传递的最后两个参数:该自定义下落点的类别 GUID 和 IVsSettingsReader 接口。
ImportSettings 方法的 VSPackage 的实现必须检查传递的类别 GUID 和为检索的状态选择正确的结构。
在下面的示例中, ImportSettings 调用方法以检索的命令栏状态不同的实现用于检索该键绑定的状态相关。
VSPackage 必须使用所提供的 IVsSettingsReader 接口检索数据。设置文件。
备注
作为 Visual Studio 版本功能,如果设置信息更改, ImportSettings 方法的 VSPackage 的实现必须在读取数据之前使用 ReadFileVersion 方法检查 IDE 版本。
接口用于读取不同数据类型的方法从设置文件。
interface IVsSettingsReader : IUnknown
{
HRESULT ReadSettingString(WCHAR *pszSettingName, BSTR *pbstrSettingValue);
HRESULT ReadSettingLong(WCHAR *pszSettingName, long *plSettingValue);
HRESULT ReadSettingBoolean(WCHAR *pszSettingName, BOOL *pfSettingValue);
HRESULT ReadSettingAttribute(LPCOLESTR pszSettingName,LPCOLESTR pszAttributeName, BSTR *pbstrSettingValue); //Internal use only
HRESULT ReadSettingBytes(WCHAR *pszSettingName, BYTE *pSettingValue, long *plDataLength, long lDataMax);
HRESULT ReadVersion(int *pnMajor, int *pnMinor, int *pnBuild);
HRESULT ReportError(WCHAR *pszError);
};
设置文件支持随机数据访问,因此,读取和写入设置操作的顺序并不重要。
这在导出的和导入的命令栏状态 (ExportSettings_CommandBar 和 ImportSettings_CommandBar) 来说明在下面的示例中的实现。
validate 检索的数据。
设置信息在 XML 文件中,可以手动编辑。
![]() |
---|
设置信息就可能被破坏在磁盘上,可以包含特定于版本的设置,并且可能用作通信工具恶意攻击。应验证 IVsSettingsReader 方法返回的每个数据项有效性。 |
若要验证支持 Visual Studio 的版本使用生成检索的设置,调用 ReadFileVersion 方法检索的版本。
若要使 IDE 通知用户导入的数据元素不验证, VSPackage 调用 ReportError 方法。
将设置信息。
ImportSettings 方法的实现必须尊重 IDE 传递给它的第三个参数的值。 支持的值是 __UserSettingsFlags 枚举的成员。 有关更多信息,请参见 __UserSettingsFlags。
在下面的示例中,导入的命令栏设置 (ImportSettings_Commandbar) 实现是否使用该参数的值确定应用设置复盖现有值或附加更新其。
,在应用导入的设置时,必须实现直写缓存方法。
,在设置应用于 IDE 的同时,在注册表或文件系统的状态信息必须更新。 这样可确保配置一致性并支持多个 IDE 方案。
警报 IDE 如何处理设置导入。
,如果需要重新启动应用导入的设置,请使用 ImportSettings 方法的返回 pfRestartRequired 参数建议 IDE。
如果 ImportSettings 方法的 VSPackage 中实现返回 true,提示用户重新启动 IDE。
示例
此示例演示如何导入和导出设置数据。
static const WCHAR c_szFirstSettingName[] = L"FirstSettingName";
static const WCHAR c_szRandomTrashBytes[] = L"RandomTrashBytes";
static const WCHAR c_szRandomTrashLength[] = L"RandomTrashLength";
static const WCHAR c_szBreakPointWindow[] = L"Breakpoints Window";
// --------------------------------------------------------------------------
// IVsUserSettings methods used for configuration export and import
// Delegate to the right shell object based on the category GUID
// --------------------------------------------------------------------------
static const WCHAR c_szFirstSettingName[] = L"FirstSettingName";
static const WCHAR c_szRandomTrashBytes[] = L"RandomTrashBytes";
static const WCHAR c_szRandomTrashLength[] = L"RandomTrashLength";
static const WCHAR c_szBreakPointWindow[] = L"Breakpoints Window";
// Export Settings.
STDMETHOD(NeedExport)(WCHAR* pszCategoryGUID, BOOL *pfNeedExport)
{
if (!pfNeedExport)
return E_INVALIDARG;
CLSID clsidCategory;
HRESULT hr= S_OK;
hr = CLSIDFromString(pszCategoryGUID, &clsidCategory);
IfFailGo(hr);
if (GUID_Profiles_CommandBars == clsidCategory) {
*pfNeedExport = TRUE; //Always export Command Bar Configuration
}else if (GUID_Profiles_KeyBindings == clsidCategory) {
*pfNeedExport = FALSE; //By Default don't export key bindings
if (m_fMake_Permanent)
*pfNeedExport = TRUE; //Export if user wants current configuration saved.
}else{
hr = E_UNEXPECTED;
}
Error:
return hr;
}
STDMETHOD(ExportSettings)(WCHAR *pszCategoryGUID, IVsSettingsWriter *pSettings)
{
CLSID clsidCategory;
HRESULT hr;
hr = CLSIDFromString(pszCategoryGUID, &clsidCategory);
IfFailGo(hr);
// Delegate to the right internal implementation based on the requested category.
if (GUID_Profiles_CommandBars == clsidCategory) {
hr = ExportSettings_CommandBars(pSettings);
}else if (GUID_Profiles_KeyBindings == clsidCategory) {
hr = ExportSettings_KeyBindings(pSettings);
}else{
hr = E_UNEXPECTED;
}
Error:
return hr;
};
HRESULT ExportSettings_CommandBars(IVsSettingsWriter *pSettings)
{
if (!pSettings)
return E_INVALIDARG;
hr = pSettings->WriteSettingString(c_szFirstSettingName, L"Value1");
IfFailGo(hr);
int cRandomTrash = 12345;
BYTE *pRandomTrash = (BYTE *)VSAlloc(cRandomTrash);
if (pRandomTrash){
hr = pSettings->WriteSettingBytes(c_szRandomTrashBytes, pRandomTrash, cRandomTrash);
IfFailGo(hr);
hr = pSettings->WriteSettingLong(c_szRandomTrashLength, cRandomTrash);
IfFailGo(hr);
}
Error:
return hr;
};
HRESULT ExportSettings_KeyBindings(IVsSettingsWriter *pSettings)
{
if (!pSettings)
return E_INVALIDARG;
hr = pSettings->WriteSettingString(c_szBreakPointWindow, L"Ctrl + Alt + B");
IfFailGo(hr);
Error:
return hr;
};
STDMETHOD(ImportSettings)(WCHAR *pszCategoryGUID, IVsSettingsReader *pSettings, UserSettingsFlags flags, BOOL *pfRestartRequired)
{
CLSID clsidCategory;
HRESULT hr;
hr = CLSIDFromString(pszCategoryGUID, &clsidCategory);
IfFailGo(hr);
// Delegate to the right internal implementation based on the requested category.
if (GUID_Profiles_CommandBars == clsidCategory)
{
hr = ImportSettings_CommandBars(, pSettings, flags, pfRestartRequired);
}
else if (GUID_Profiles_KeyBindings == clsidCategory)
{
hr = ImportSettings_KeyBindings( pSettings, flags, pfRestartRequired);
}
else
{
hr = E_UNEXPECTED;
}
Error:
return hr;
};
// Import Settings.
HRESULT ImportSettings_CommandBars(IVsSettingsReader *pSettings, UserSettingsFlags flags, BOOL *pfRestartRequired)
{
if (!pSettings)
return E_INVALIDARG;
if (pfRestartRequired)
{
*pfRestartRequired = FALSE; //Nobody should require a restart!!
}
CComBSTR bstrFirstSettingName;
long lTrashLength = 0;
BYTE *pTrashBytes = NULL;
// Determines whether to import as an additive operation, or a reset all settings operation.
BOOL fResetCompletely = FALSE;
if (flags & USF_ResetOnImport)
fResetCompletely = TRUE;
hr = pSettings->ReadSettingString(c_szFirstSettingName, &bstrFirstSettingName);
IfFailGo(hr);
hr = pSettings->ReadSettingLong(c_szRandomTrashLength, &lTrashLength);
IfFailGo(hr);
if (lTrashLength > 0)
{
pTrashBytes = (BYTE*)VSAlloc(lTrashLength);
IfNullMemGo(pTrashBytes);
long lDataRead = 0;
hr = pSettings->ReadSettingBytes(c_szRandomTrashLength, pTrashBytes, &lDataRead, lTrashLength);
IfFailGo(hr);
if (lDataRead != lTrashLength)
{
hr = E_UNEXPECTED;
goto Error;
}
}
// Note: before returning these settings should immediately be applied to your personal
// settings store, whether in the registry or the file system.
// This write-thru cache methodology is essential to work in multi-instance IDE scenarios.
hr = UpdateState_CommandBar(bstrFirstSettingName,lTrashLength,pTrashBytes,lDataRead);
Error:
return hr;
};
HRESULT ImportSettings_KeyBindings(IVsSettingsReader *pSettings, UserSettingsFlags flags, BOOL *pfRestartRequired)
{
if (!pSettings)
return E_INVALIDARG;
if (pfRestartRequired)
{
*pfRestartRequired = FALSE; //Nobody should require a restart!!
}
CComBSTR bstrBreakPointWindow;
// Determines whether to import as an additive operation or a reset all settings operation.
BOOL fResetCompletely = FALSE;
if (flags & USF_ResetOnImport)
fResetCompletely = TRUE;
hr = pSettings->ReadSettingString(c_szBreakPointWindow, &bstrBreakPointWindow);
IfFailGo(hr);
// Note: before returning these settings should immediately be applied to your personal
// settings store, whether in the registry or the file system.
// This write-thru cache methodology is essential to work in multi-instance IDE scenarios.
hr = UpdateState_KeyBindings(bstrBreakPointWindow);
Error:
return hr;
}