5

So basically I only want to display the Command when I right click on a file named "example.cs". Since I am using Visual Studio 2019 I can't go with the old BeforeQueryStatus way. Instead using the ProvideUIContextRule Attribute on my Package class. Which currently looks something like this:

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

Which totally looks fine for the extension of the file itself. So is there any way to restrict it to example.cs?

By the way I am using this Guide.

Twenty
  • 5,234
  • 4
  • 32
  • 67

2 Answers2

2

So for everyone else having the same issue as I had. The solution is fairly simple, regarding to the MSDN:

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

So basically changing { "HierSingleSelectionName:.cs$" } to { "HierSingleSelectionName:Program.cs$" } will only show files that end with Program.cs.

This leads to, that everything after the semicolon contains a Regular Expression.

Twenty
  • 5,234
  • 4
  • 32
  • 67
  • Hi Twenty, thanks for your sharing and please mark your reply as answer and that will help other community members who easier search this useful information, it just a reminder :) – LoLance Jul 25 '19 at 08:50
  • @LanceLi-MSFT just letting you know, there is a 6 hour cooldown before you can accept your own answers ;) – Twenty Jul 25 '19 at 08:54
0

To determine your command's visibility, you can implement QueryStatus method.

Implement Microsoft.VisualStudio.OLE.Interop.IOleCommandTarget like CommandsFilter. And add it as service to package.

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

On every commands update will be called method QueryStatus in CommandsFilter. Wait for your command id and change it status

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;
}

Check sample with QueryStatus and others MS samples

vik_78
  • 1,107
  • 2
  • 13
  • 20