使用 C++ 的 VSPackage 开发,我如何在启动时初始化我的包 visual studio
VSPackage development using C++, how do i initialize my package when start visual studio
我的包是用C++、VS2015开发的。
例如,我在项目菜单和工具栏中定义了一些命令,当我启动 VS 时,工具栏菜单是好的,但是项目菜单中的命令没有出现,然后我必须点击工具栏菜单中的任何按钮,然后项目菜单中的命令回来。
我希望我的包在启动时初始化项目菜单命令 visual studio 或打开一个项目。
我的代码是这样的
class ATL_NO_VTABLE CYHMExtensionsPackage :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CYHMExtensionsPackage, &CLSID_YHMExtensions>,
// Provides the implementation for IVsPackage to make this COM object into a VS Package.
public IVsPackageImpl<CYHMExtensionsPackage, &CLSID_YHMExtensions>,
public IOleCommandTargetImpl<CYHMExtensionsPackage>,
// Provides consumers of this object with the ability to determine which interfaces support extended error information.
public ATL::ISupportErrorInfoImpl<&__uuidof(IVsPackage)>
{
public:
// Provides a portion of the implementation of IUnknown, in particular the list of interfaces
// the CYHMExtensionsPackage object will support via QueryInterface
BEGIN_COM_MAP(CYHMExtensionsPackage)
COM_INTERFACE_ENTRY(IVsPackage)
COM_INTERFACE_ENTRY(IOleCommandTarget)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()
VSL_DECLARE_NOT_COPYABLE(CYHMExtensionsPackage)
public:
CYHMExtensionsPackage():m_dwEditorCookie(0), m_MyToolWindow(GetVsSiteCache())
{
GetYHMVSSolution();
}
~CYHMExtensionsPackage()
{
}
...
};
- 也许您不应该在 class.
的构造函数中放置初始化其他方法的代码
在你的class.h文件中实现如下方法,并在Sleep
设置断点
void PostSited(IVsPackageEnums::SetSiteResult /*result*/)
{
Sleep(2500);//initilialize will sleep for some time
}
- 请务必在您的项目 .pkgdef 文件中设置正确的自动加载注册表项,在我的例子中,它是在从向导创建 vspackage 项目之后 {f1536ef8- 92ec-443c-9ed7-fdadf150da82},然后将项目的 guid 放入其中显示 03be14ec-1a85-4c5c-a1f4-723d189c2e4c
这是一个自动加载的例子:
[$RootKey$\AutoLoadPackages\{f1536ef8-92ec-443c-9ed7-fdadf150da82}]
"{03be14ec-1a85-4c5c-a1f4-723d189c2e4c}"=dword:00000000
有关 select 的 guid 的更多信息可在此处找到:https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.uicontextguids80.aspx
现在按 F5,您应该会到达断点。您可以通过导航到
来验证注册表中的注册表项是否已正确设置
HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio.0Exp_Config\AutoLoadPackages\{f1536ef8-92ec-443c-9ed7-fdadf150da82}
(其中 {f1536ef8-92ec-443c-9ed7-fdadf150da82} 是您从第 3 步 select 编辑的 guid)并寻找您的项目的 guid [同样,在我的例子中它是 03be14ec-1a85-4c5c -a1f4-723d189c2e4c,但你的必须不同]。如果没有,您需要手动添加。
VS 包应设计为在需要时加载,而不是在启动 VS IDE (devenv.exe) 时强制加载。如果每个人都强制在 VS 启动时加载他们的包,那么您将等待很长时间才能真正启动 Visual Studio。
您应该 做的是将 AutoLoadPackages registry key, to specify which activation contexts should load your package. This is super easy with a VB or C# based package project, as all you need to do is add a ProvideAutoLoad attribute 用于您的包对象。
但是对于基于 C++ 的包,您将需要手动编辑 .pkgdef 以添加所需的条目。
综上所述,菜单命令是由您的 .VSCT 文件定义的,因此这里的问题很可能与您的 .VSCT 文件有关,以及您如何声明您尝试添加到项目中的菜单命令或为菜单命令设置父级上下文菜单。
使用 EnableVSIPLogging registry key trick,验证您是否为您感兴趣的上下文菜单确定了正确的 guid:id 对。
(提示)如果您使用的是 VS 2015,您也可以通过 Mads Kristensen's Extensibility Tools extension 进行设置。如果您正在编辑 .pkgdefs、.vsixmanifests 等,我特别推荐此方法。
我的包是用C++、VS2015开发的。 例如,我在项目菜单和工具栏中定义了一些命令,当我启动 VS 时,工具栏菜单是好的,但是项目菜单中的命令没有出现,然后我必须点击工具栏菜单中的任何按钮,然后项目菜单中的命令回来。 我希望我的包在启动时初始化项目菜单命令 visual studio 或打开一个项目。
我的代码是这样的
class ATL_NO_VTABLE CYHMExtensionsPackage :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CYHMExtensionsPackage, &CLSID_YHMExtensions>,
// Provides the implementation for IVsPackage to make this COM object into a VS Package.
public IVsPackageImpl<CYHMExtensionsPackage, &CLSID_YHMExtensions>,
public IOleCommandTargetImpl<CYHMExtensionsPackage>,
// Provides consumers of this object with the ability to determine which interfaces support extended error information.
public ATL::ISupportErrorInfoImpl<&__uuidof(IVsPackage)>
{
public:
// Provides a portion of the implementation of IUnknown, in particular the list of interfaces
// the CYHMExtensionsPackage object will support via QueryInterface
BEGIN_COM_MAP(CYHMExtensionsPackage)
COM_INTERFACE_ENTRY(IVsPackage)
COM_INTERFACE_ENTRY(IOleCommandTarget)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()
VSL_DECLARE_NOT_COPYABLE(CYHMExtensionsPackage)
public:
CYHMExtensionsPackage():m_dwEditorCookie(0), m_MyToolWindow(GetVsSiteCache())
{
GetYHMVSSolution();
}
~CYHMExtensionsPackage()
{
}
...
};
- 也许您不应该在 class. 的构造函数中放置初始化其他方法的代码
在你的class.h文件中实现如下方法,并在Sleep
设置断点void PostSited(IVsPackageEnums::SetSiteResult /*result*/)
{
Sleep(2500);//initilialize will sleep for some time
}
- 请务必在您的项目 .pkgdef 文件中设置正确的自动加载注册表项,在我的例子中,它是在从向导创建 vspackage 项目之后 {f1536ef8- 92ec-443c-9ed7-fdadf150da82},然后将项目的 guid 放入其中显示 03be14ec-1a85-4c5c-a1f4-723d189c2e4c
这是一个自动加载的例子:
[$RootKey$\AutoLoadPackages\{f1536ef8-92ec-443c-9ed7-fdadf150da82}]
"{03be14ec-1a85-4c5c-a1f4-723d189c2e4c}"=dword:00000000
有关 select 的 guid 的更多信息可在此处找到:https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.uicontextguids80.aspx
现在按 F5,您应该会到达断点。您可以通过导航到
来验证注册表中的注册表项是否已正确设置HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio.0Exp_Config\AutoLoadPackages\{f1536ef8-92ec-443c-9ed7-fdadf150da82}
(其中 {f1536ef8-92ec-443c-9ed7-fdadf150da82} 是您从第 3 步 select 编辑的 guid)并寻找您的项目的 guid [同样,在我的例子中它是 03be14ec-1a85-4c5c -a1f4-723d189c2e4c,但你的必须不同]。如果没有,您需要手动添加。
VS 包应设计为在需要时加载,而不是在启动 VS IDE (devenv.exe) 时强制加载。如果每个人都强制在 VS 启动时加载他们的包,那么您将等待很长时间才能真正启动 Visual Studio。
您应该 做的是将 AutoLoadPackages registry key, to specify which activation contexts should load your package. This is super easy with a VB or C# based package project, as all you need to do is add a ProvideAutoLoad attribute 用于您的包对象。
但是对于基于 C++ 的包,您将需要手动编辑 .pkgdef 以添加所需的条目。
综上所述,菜单命令是由您的 .VSCT 文件定义的,因此这里的问题很可能与您的 .VSCT 文件有关,以及您如何声明您尝试添加到项目中的菜单命令或为菜单命令设置父级上下文菜单。
使用 EnableVSIPLogging registry key trick,验证您是否为您感兴趣的上下文菜单确定了正确的 guid:id 对。
(提示)如果您使用的是 VS 2015,您也可以通过 Mads Kristensen's Extensibility Tools extension 进行设置。如果您正在编辑 .pkgdefs、.vsixmanifests 等,我特别推荐此方法。