我是开发Visual Studio IDE扩展的新手。
我是从微软的官方文件中学习的。
但是,我无法理解如何制作新菜单。
我已添加到工具中,但我想添加包含我的工具的新菜单。
在微软文档中,有很多东西,比如组,按钮和菜单。但是,我无法理解它们之间的层次结构,特别是与ID的链接。
有人可以解释它是如何运作的吗?
提前致谢
答案 0 :(得分:1)
<VSCTCompile>
标记。这必须通过直接编辑项目文件来完成。您还需要为VSCT编译器添加一个空的VSPackage.resx文件,以将已编译的资源嵌入到项目文件修改(将其添加到任何<ItemGroup>
)如下:xml <VSCTCompile Include="YourName.vsct"> <ResourceName>Menus.ctmenu</ResourceName> </VSCTCompile> <EmbeddedResource Include="VSPackage.resx"> <MergeWithCTO>true</MergeWithCTO> <ManifestResourceName>VSPackage</ManifestResourceName> </EmbeddedResource>
VSCT的内容应如下所示:
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Extern href="stdidcmd.h"/>
<Extern href="vsshlids.h"/>
<Commands package="PackageGuid">
<Buttons>⠀
<Button guid="CommandsGuid" id="MyCommand" priority="0x0101" type="Button">⠀
<Parent guid="guidSHLMainMenu" id="IDG_VS_CODEWIN_NAVIGATETOLOCATION"/> ⠀
<Icon guid="guidObjectBrowserButtons" id="15"/>⠀
<Strings>
<ButtonText>My &Powerful Command</ButtonText>
</Strings>
</Button>
</Buttons>
</Commands>
<Symbols>
<GuidSymbol name="PackageGuid" value="«Package GUID»" />
<GuidSymbol name="CommandsGuid" value="«Command Group GUID»">
<IDSymbol name="MyCommand" value="0" />
</GuidSymbol>
</Symbols>
</CommandTable>
命令ID值在每个命令组(GUID)中必须是唯一的,因此您无需担心与其他命令发生冲突。
<Parent>
条目指定应该放置命令的组;您可以在Program Files \ Microsoft Visual Studio 12.0 \ VSSDK \ VisualStudioIntegration \ Common \ Inc \ vsshlids.h中找到所有标准组。您还可以在同一文件夹中的stdidcmd.h中找到所有命令ID的列表。
首先,添加以下代码文件(类名无关紧要):
using System;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;
namespace YourAddin.Namespace {
// These GUIDS and command IDs must match the VSCT.
[ProvideMenuResource("Menus.ctmenu", 1)]
[Guid("«Package GUID»")]
[PackageRegistration(UseManagedResourcesOnly = true)]
class YourAddinPackage : Package {
}
[Guid("«Command Group GUID»")]
enum YourAddinCommand {
MyCommand = 0
}
}
package类中的属性告诉CreatePkgDef.exe(由VSIX编译器调用)如何在你的插件中发出一个.pkgdef文件,该文件设置了适当的注册表键,用Visual Studio注册addin及其菜单资源原生的基于COM的插件系统。这完全独立于托管插件的MEF注册。
枚举及其[Guid]属性只是跟踪GUID和命令ID的简便方法;如果你愿意,你可以自由地使用不同的方法。
您还需要告诉VSIX包含该包并通过将以下行添加到source.extension.vsixmanifest中的<Content>
元素来生成pkgdef文件:
<VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>
如果您正在使用设计器(对于版本2 VSIXes),请转到Assets部分,单击New,选择Microsoft.VisualStudio.VsPackage,当前解决方案中的项目,然后选择您的项目.⠀
首先,删除<GeneratePkgDefFile>false</GeneratePkgDefFile>
如果它存在,告诉VSIX编译器生成一个pkgdef来注册你的包。纯粹基于MEF的插件根本不需要pkgdef文件,因此大多数项目模板都会添加它,但是一旦创建了VSPackage,就需要一个pkgdef来用Visual Studio的本机COM插件加载器注册它。
接下来,在根元素中的任何位置添加以下标记(不在<ItemGroup>
中):xml <PropertyGroup> <UseCodebase>true</UseCodebase> </PropertyGroup>
VSPackages实际上是在Visual Studio配置单元的配置键中注册并使用普通COM实践加载的COM DLL。使用COM互操作加载托管VSPackage;它们被注册为mscoree.dll,然后查找托管程序集以从同一注册表项加载。默认情况下,PkgDef创建者将发出“Assembly”=“YourAssemblyName”,mscoree将尝试使用标准.Net程序集加载器加载。除非您的VSPackage DLL在GAC中(它不会在GAC中),否则这将无效,VS将默默拒绝加载您的包。在项目文件中设置<UseCodebase>
将使其发出“CodeBase”=“$ PackageFolder $ \ YourAddin.dll”($ PackageFolder $代替安装VSIX时的实际DLL路径),告诉mscoree确切的从中加载它的路径。
完成所有这些操作后,当你在插件中点击F5(在实验实例中运行)时,你的命令就会显示出来。但是,您仍然需要实际执行该命令,以便在单击按钮时发生某些事情。
对于全局命令,最简单的方法是覆盖包中的Initialize()方法并添加如下代码:
var mcs = (OleMenuCommandService) GetService(typeof(IMenuCommandService));
var commandId = new CommandID(typeof(YourAddinCommand).GUID, (int)YourAddinCommand.MyCommand));
mcs.AddCommand(new MenuCommand(delegate {
MessageBox.Show("You clicked me!");
}, commandId);
对于适用于活动编辑器窗口的命令,我编写了一个类,它将拦截器添加到编辑器的命令处理程序链中,并公开了一个接受命令枚举中的条目的简单接口。这既可用于实现新命令,也可用于拦截现有命令。您可以在CommandTargetBase.cs中找到它,您可以在此处查看示例用法。