VisualStudio拦截F1帮助命令我在找一个visualstudio插件,它拦截默认的在线帮助命令,并在类或类型库URL上调用F1帮助时获取MSDN.例如,如果我将光标放在关键字字符串上并按F1,它通常会自动打开浏览器并导航到字符串引用类型的帮助文档。我想在它到达浏览器之前抓取传递给浏览器的URL。是否可以编写可以拦截默认F1帮助命令的visualstudio插件/扩展?如果以上可以做任何指针,从哪里开始?大约10年前,当我在Microsoft工作时,我为VisualStudio2005中最初的“在线F1”功能编写了规范。所以我的知识有些权威,但也可能已经过时。?您无法更改VisualStudio正在使用的URL(至少我不知道如何更改它),但您可以简单地编写另一个窃取F1键绑定的加载项,使用与默认F1处理程序相同的帮助上下文可以将用户定向到您自己的URL或应用程序。首先,关于F1如何在线工作的一些信息:VisualStudioIDE的组件将关键字推送到“F1HelpContext”,这是一个关于用户正在做什么的信息包:例如代码编辑器中的当前选择、编辑正在编辑的文件类型、正在编辑的项目类型等。当用户按下F1时,IDE将帮助上下文打包到URL中并打开指向MSDN的浏览器。Here'sanexampleURL,inthiscase,whentheCSSproperty"width"isselected,bypressingF1intheVS2012HTMLeditormsdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(width);k(vs.csseditor);k(TargetFrameworkMoniker-.NETFramework,版本%3Dv4.0);k(DevLang-CSS)&rd=true上面的“k”参数包含了visualstudio中的帮助上下文。帮助上下文包含“关键字”(文本字符串)和“属性”(名称/值对),VisualStudio中的各种窗口使用它们来告诉IDE当前用户正在做什么。CSS编辑器推送两个关键字:我选择的“width”和MSDN可以用作“后备”的“vs.csseditor”,例如,如果我的选择在MSDN上找不到。还有一些上下文过滤属性:TargetFrameworkMoniker=NETFramework,Version=v4.0DevLang=CSS这些确保F1加载正确语言或技术的页面,在本例中为CSS。(还有另一个.NET4.0过滤器,因为我加载的项目是针对.NET4.0的)请注意上下文是有序的。“宽度”关键字比它下面的关键字更重要。MSDN上的实际帮助内容包含元数据(由编写文档的团队手动设置),其中包含与该页面关联的关键字和名称/值上下文属性。例如,MSDN上的CSS宽度属性文档,当存储在MSDN服务器上时,有一个与之关联的关键字列表(在本例中为“width”)和一个上下文属性列表(在本例中为:“DevLang=CSS””)。页面可以有多个关键字(例如“System.String”、“String”)和多个上下文属性(例如“DevLang=C#”、“DevLang=VB”等)。当关键字列表进入MSDNOnlineF1服务,算法是这样的,需要注意的是多年来它可能发生了变化:使用第一个关键字查找与该关键字匹配的所有页面排除所有具有与名称匹配的上下文属性页面(例如“DevLang”),但不是值。例如,这将排除Control.Width页面,因为它将被标记为“DevLang=C#”、“DevLang=VB”。但它不会排除没有DevLang属性的页面。如果没有结果剩下但还有更多关键字,从#1和下一个关键字(按顺序)重新开始,除非关键字用完。如果没有关键字,请执行“备份”操作,这可能会返回MSDN列表搜索结果,可能是“找不到页面”或其他解决方案。对剩余的结果进行排序。我不记得确切的排名算法,从那以后它可能已经改变,但我相信一般的想法是首先显示匹配更多属性的页面,并首先显示更受欢迎的匹配项。在浏览器中显示最上面的结果这是VisualStudio加载项的代码示例:接管F1键绑定当按下F1时,获取帮助上下文并将其转换为一组名称=值对转换这组名称=value对传递给一些外部代码以对F1请求执行某些操作。我省略了所有VisualStudio插件样板代码-如果您也需要,谷歌上应该有很多示例。使用系统;使用可扩展性;使用EnvDTE;使用EnvDTE80;使用Microsoft.VisualStudio.CommandBars;使用系统资源;使用System.Reflection;使用System.Globalization;使用系统集合;使用System.Collections.Generic;使用系统文本;namespaceReplaceF1{///实现插件的对象。///publicclassConnect:IDTExtensibility2,IDTCommandTarget{///实现插件对象的构造函数。将您的初始化代码放在该方法中。publicConnect(){}MsdnExplorer.MainWindowExplorer=newMsdnExplorer.MainWindow();///实现IDTExtensibility2接口的OnConnection方法。接收加载项正在加载的通知。///宿主应用程序的根对象。///描述加载项的加载方式。///表示此加载项的对象。///publicvoidOnConnection(objectapplication,ext_ConnectModeconnectMode,objectaddInInst,refArraycustom){_applicationObject=(DTE2)应用程序;_addInInstance=(插件)addInInst;如果(connectMode==ext_ConnectMode.ext_cm_UISetup){object[]contextGUIDS=newobject[]{};Commands2命令=(Commands2)_applicationObject.Commands;字符串工具菜单名称;try{//如果您想将命令移动到不同的菜单,请将“帮助”一词更改为菜单的//英文版本。此代码将获取区域性,附加在菜单的名称上//然后将命令添加到该菜单。您可以在文件//CommandBar.resx中找到所有顶级菜单的列表。ResourceManagerresourceManager=newResourceManager("ReplaceF1.CommandBar",Assembly.GetExecutingAssembly());CultureInfocultureInfo=newSystem.Globalization.CultureInfo(_applicationObject.LocaleID);stringresourceName=String.Concat(cultureInfo.TwoLetterISOLanguageName,"Help");toolsMenuName=resourceManager.GetString(resourceName);}catch{//我们试图找到t的本地化版本他字工具,但没有找到。//默认为en-US单词,这可能适用于当前的文化。toolsMenuName="帮助";}//将命令放在工具菜单上。//找到MenuBar命令栏,这是包含所有主菜单项的顶级命令栏:Microsoft.VisualStudio.CommandBars.CommandBarmenuBarCommandBar=((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];//在MenuBar命令栏上找到Tools命令栏:CommandBarControltoolsControl=menuBarCommandBar.Controls[toolsMenuName];CommandBarPopuptoolsPopup=(CommandBarPopup)toolsControl;//如果您希望添加多个命令由您的加载项处理,则可以复制此try/catch块,//只需确保您还更新了QueryStatus/Exec方法以包含新的命令名称。try{//向Commands集合添加命令:Commandcommand=commands.AddNamedCommand2(_addInInstance,"ReplaceF1","MSDNAdvancedF1","通过MSDN加载项调出上下文相关的帮助",true,59,refcontextGUIDS,(int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.vsCommandStatusEnabled,(int)vsCommandStyle.vsCommandStylePictAndText,vsCommandControlType.vsCommandControlTypeButton);command.Bindings=newobject[]{"Global::F1"};}catch(System.ArgumentException){//如果我们在这里,那么异常可能是因为具有该名称的命令//已经存在。如果因此无需重新创建命令,我们可以//安全地忽略异常。}}}///实现IDTExtensibility2接口的OnDisconnection方法。接收加载项正在卸载的通知。///描述如何正在卸载加载项。///特定于主机应用程序的参数数组。///publicvoidOnDisconnection(ext_DisconnectModedisconnectMode,refArraycustom){}///实现IDTExtensibi的OnAddInsUpdate方法lity2接口。当加载项集合发生更改时收到通知。///特定于主机应用程序的参数数组。///publicvoidOnAddInsUpdate(refArraycustom){}///实现IDTExtensibility2接口的OnStartupComplete方法。接收主机应用程序已完成加载的通知。///特定于主机应用程序的参数数组。///publicvoidOnStartupComplete(refArraycustom){}///实现IDTExtensibility2接口的OnBeginShutdown方法。接收正在卸载主机应用程序的通知。///特定于主机应用程序的参数数组。///publicvoidOnBeginShutdown(refArraycustom){}///实现IDTCommandTarget接口的QueryStatus方法。当命令的可用性更新时调用///确定状态的命令的名称。///命令所需的文本。///员工用户界面中的命令。///neededText参数请求的文本。///publicvoidQueryStatus(stringcommandName,vsCommandStatusTextWantedneededText,refvsCommandStatusstatus,refobjectcommandText){if(neededText==vsCommandStatusTextWanted.vsCommandStatusTextWantedNone){if(commandName=="ReplaceF1.Connect.ReplaceF1"){状态=(vsCommandStatus)vsCommandStatus.vsCommandStatusSupported|vsCommandStatus.vsCommandStatusEnabled;返回;}}}///实现IDTCommandTarget接口的Exec方法。调用命令时将调用它。///要执行的命令的名称。///描述命令应该如何运行。///从调用者传递给命令处理程序的参数。///从命令处理程序传递给调用者的参数。///通知调用者命令是否被处理。///publicvoidExec(stringcommandName,vsCommandExecOptionexecuteOption,refobjectvarIn,refobjectvarOut,refboolhandled){if(executeOption==vsCommandExecOption.vsCommandExecOptionDoDefault){if(commandName=="ReplaceF1.Connect.ReplaceF1"){//获取对解决方案资源管理器的引用。窗口activeWindow=_applicationObject.ActiveWindow;ContextAttributescontextAttributes=activeWindow.DTE.ContextAttributes;contextAttributes.Refresh();列表属性=newList();尝试{ContextAttributeshighPri=contextAttributes==null?null:contextAttributes.HighPriorityAttributes;highPri.Refresh();if(highPri!=null){foreach(ContextAttributeCAinhighPri){列表值=newList();foreach((ICollection)CA.Values中的字符串值){values.Add(value);}字符串属性=CA.Name+"="+String.Join(";",values.ToArray());attributes.Add(CA.Name+"=");}}}catch(System.Runtime.InteropServices.COMExceptione){//忽略这个异常——意味着这里没有高Pri值stringx=e.Message;}赶上(System.Reflection.TargetInvocationExceptione){//忽略这个异常——意味着这里没有HighPri值stringx=e.Message;}catch(System.Exceptione){System.Windows.Forms.MessageBox.Show(e.Message);//忽略这个异常--意味着这里没有HighPri值stringx=e.Message;}//获取优先级不高的上下文属性foreach(ContextAttributeCAincontextAttributes){Listvalues=newList();foreach((ICollection)CA.Values中的字符串值){values.Add(value);}字符串属性=CA.Name+"="+String.Join(";",values.ToArray());attributes.Add(属性);}//用帮助上下文信息HelpHandler.HandleF1(attributes);替换这个调用。}}}私有DTE2_applicationObject;私有加载项_addInInstance;}}一切都非常令人兴奋但可能过度设计?我有一个像大多数人一样的可编程鼠标,我设置了一个搜索按钮。即单击该词,浏览器将在您最喜欢的搜索引擎中打开该词。通常MSDN帮助在该列表中。AS是SO链接。我喜欢一个有效而简单的灵魂:-)以上就是C#学习教程的全部内容:VisualStudio拦截F1帮助命令。网络收藏不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
