仅在特定文件名(+扩展名)的上下文菜单中显示命令

Only show command in context menu on specific filename (+extension)

所以基本上我只想在右键单击名为 "example.cs" 的文件时显示命令。由于我使用的是 Visual Studio 2019,所以我不能使用旧的 BeforeQueryStatus 方式。而是在我的包 class 上使用 ProvideUIContextRule 属性。目前看起来像这样:

    [ProvideUIContextRule(_uiContextSupportedFiles,
    name: "Supported Files",
    expression: "CSharp",
    termNames: new[] { "CSharp" },
    termValues: new[] { "HierSingleSelectionName:.cs$" })]

这对于文件本身的扩展名来说完全没问题。那么有没有办法限制到example.cs?

顺便说一句,我正在使用这个 Guide

要确定命令的可见性,您可以实现 QueryStatus 方法。

像 CommandsFilter 一样实现 Microsoft.VisualStudio.OLE.Interop.IOleCommandTarget。并将其作为服务添加到包中。

var serviceContainer = (IServiceContainer)this; // this - is your Package/AsyncPakage
var commandTargetType = typeof(IOleCommandTarget);
var commandsFilter = new CommandsFilter();
serviceContainer.RemoveService(commandTargetType);
serviceContainer.AddService(commandTargetType, commandsFilter);

每次更新命令时,都会调用 CommandsFilter 中的方法 QueryStatus。 等待您的命令 ID 并更改它的状态

class CommandsFilter : IOleCommandTarget {
// ...
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText) {
    var cmdId = prgCmds[0].cmdID;
    // check cmdId and set status depends on your conditions
    // like fileName == "example.cs"
    prgCmds[0].cmdf = (uint)GetVsStatus(status);

    //....
}

private OLECMDF GetVsStatus(CommandStatus commandStatus) {

  OLECMDF ret = 0;
  if (commandStatus.HasFlag(CommandStatus.Supported))
    ret |= OLECMDF.OLECMDF_SUPPORTED;
  if (commandStatus.HasFlag(CommandStatus.Enabled))
    ret |= OLECMDF.OLECMDF_ENABLED;
  if (commandStatus.HasFlag(CommandStatus.Invisible))
    ret |= OLECMDF.OLECMDF_INVISIBLE;
  return ret;
}

QueryStatus 和其他 MS 样本检查 sample

对于和我有同样问题的其他人来说。解决方法很简单,参考MSDN:

(...) The term evaluates to true whenever the current selection in the active hierarchy has a name that matches the regular expression pattern(...)

所以基本上改变了 { "HierSingleSelectionName:.cs$" }{ "HierSingleSelectionName:Program.cs$" } 将只显示以 Program.cs 结尾的文件。

这导致分号后的所有内容都包含正则表达式。