VSPackage 能从 Visual Studio 集成开发环境 (ide) 导出设置 (IDE)。 IDE 使用 IVsUserSettings 接口的 VSPackage 的实现。 如果包还提供 IVsUserSettingsQuery 界面,则 IVsUserSettingsQuery 接口用于确定 VSPackage 中配置如何将被保存。
备注
托管包框架 (MPF)提供一组托管类实现 Visual Studio 扩展的创建。使用 MPF,若要执行此任务,请参见 如何:使用托管包结构的导出设置。
实现在 VSPackage 中设置导出
基本的实现用于 Visual Studio 设置 framework 支持。
为支持设置结构的 VSPackage 通过定义一个或多个自定义下落点注册。
有关更多信息,请参见 保留的设置。
声明的 VSPackage 实现 IVsUserSettings。 如果需要, VSPackage 也可以实现 IVsUserSettingsQuery 接口。 例如:
public class MyPackage : IVsPackage, IVsUserSettings, IVsUserSettingsQuery
确保 QueryInterface 方法的 VSPackage 中实现提供一 IVsUserSettings 接口,在调用与 IID_IVsUserSettings。
或者, QueryInterface 可以提供一 IVsUserSettingsQuery 接口,在调用与 IID_IVsUserSettingsQuery 接口。
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; }
或者,警报需要的 IDE 导出特定的设置。
VSPackage 中选择有条件地保存设置自定义下落点状态定义的。 例如,因此,只有当用户显式指示要保存,的设置保存。
在这种情况下,必须实现 IVsUserSettingsQuery 接口。
如果 VSPackage 不实现 IVsUserSettingsQuery,在设置导出过程中,所有其状态信息保存。
VSPackage 中支持多个自定义下落点 (设置类别)。 NeedExport 方法的实现必须检查已提供的自定义下落点的 GUID 或设置类别参数确定是否必须保存设置的特定组。
在下面的示例中, VSPackage 始终请求其命令栏状态保存,但是,仅请求其键约束状态保存,如果设置了标志。
写入设置文件中的设置数据。
若要支持导出设置, VSPackage 必须总是执行 ExportSettings 方法。
实现必须传递 IDE 的句柄,该自定义下落点的类别 GUID 和 IVsSettingsWriter 接口。
VSPackage 中支持多个自定义下落点 (设置类别)。 在下面的示例中, ExportSettings 方法调用仍存在的命令栏状态的不同的实现与仍存在的键绑定状态相关。
VSPackage 必须使用所提供的 IVsSettingsWriter 接口访问数据保存到设置的文件。
interface IVsSettingsWriter : IUnknown
{
HRESULT WriteSettingString( LPCOLESTR pszSettingName, LPCOLESTR pszSettingValue);
HRESULT WriteSettingLong( LPCOLESTR pszSettingName, long lSettingValue);
HRESULT WriteSettingBoolean( LPCOLESTR pszSettingName, BOOL fSettingValue);
HRESULT WriteSettingBytes( LPCOLESTR pszSettingName, BYTE *pSettingValue, long lDataLength);
HRESULT WriteSettingAttribute( LPCOLESTR pszSettingName, LPCOLESTR pszAttributeName, LPCOLESTR pszSettingValue);
HRESULT WriteSettingXml( IUnknown *pIXMLDOMNode);
HRESULT WriteSettingXmlFromString( LPCOLESTR szXML);
HRESULT ReportError( LPCOLESTR pszError, VSSETTINGSERRORTYPES dwErrorType);
};
pszSettingName 参数的值提供给 IVsSettingsWriter 接口必须唯一标识在设置类别中保存的每个数据元素。
备注
,因为 IDE 使用其 GUID 和 pszSettingName 的值标识每个已保存的设置,名称必须是唯一的中自定义下落点。如果多个 IVsSettingsWriter 方法调用与 pszSettingName的值相同,则原始值在设置文件复盖。
设置文件支持随机数据访问。 因此,读取和写入设置操作的顺序并不重要。
这在导出和导入命令栏状态的实现声明 (ExportSettings_CommandBar 和 ImportSettings_CommandBar) 在下面的示例所示。
如果实现可以将数据添加到四个支持的格式之一,不会对数以及类型的限制数据进行编写。
备注
除了数据外显式编写和透明到 ExportSettings 实现,设置 API 还保存 Visual Studio 版本信息。保存的设置可以向设置导入过程中,生成它们 IDE 的版本进行比较。
示例
下面的示例演示如何导入和导出设置数据。
// --------------------------------------------------------------------------
// IVsUserSettings methods used for configuration export.
// 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 treat 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-through cache methodology is essential to 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 import can be treated 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-through cache methodology is essential to allow us
// to work in multi-instance IDE scenarios.
hr = UpdateState_KeyBindings(bstrBreakPointWindow);
Error:
return hr;
}