4

I'm trying to create simple extension for Visual Studio for Mac which will handle the moment when user saves the document (sample project is on GitHub, right here).

Here's how looks my implementation of ICommandHandler<SaveCommandArgs>:

[Export(typeof(ICommandHandler))]
[Name(nameof(SaveCommandHandler))]
[ContentType(StandardContentTypeNames.Code)]
[TextViewRole(PredefinedTextViewRoles.PrimaryDocument)]
public class SaveCommandHandler : ICommandHandler<SaveCommandArgs>
{
    public string DisplayName => nameof(SaveCommandHandler);

    private readonly IEditorCommandHandlerServiceFactory _editorCommandHandlerServiceFactory;

    [ImportingConstructor]
    public SaveCommandHandler(IEditorCommandHandlerServiceFactory editorCommandHandlerServiceFactory)
    {
        _editorCommandHandlerServiceFactory = editorCommandHandlerServiceFactory;
    }

    public bool ExecuteCommand(SaveCommandArgs args, CommandExecutionContext executionContext)
    {
        try
        {
            var service = _editorCommandHandlerServiceFactory.GetService(args.TextView);
            Debug.WriteLine($"I am executing something on save with {service.GetType()}");
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }

        return true;
    }

    public CommandState GetCommandState(SaveCommandArgs args)
    {
        return CommandState.Available;
    }
}

Good point: system call the constructor of this handler, when you start editing the first file

Bad point: ExecuteCommand method never called, as well as GetCommandState method

Any ideas why it doesn't work?

I was trying to do all the things according to the documentation on official wiki in github project for visual studio api

Unfortunately, there're only samples for quick info and autocomplete features. No samples for ICommandHandler-s, haven't found any similar projects for Visual Studio for Mac as well

Taras Shevchuk
  • 326
  • 3
  • 14

1 Answers1

1

I agree the examples since Microsoft Visual Studio SDK documentation is horrible with no good examples of ICommandHandler.

I tried your exact code in visual studio 2022 on Windows 10 and the ExecuteCommand function is called.

So your code is fine.

I think the core problem here is that the ICommandHandler interface structure is somewhat newer and Microsoft did a poor job of properly checking for custom command handlers and adding calls.

I am trying to do a similar thing where I add an ICommandHandler to intercept the GoToDefinition command using an ICommandHandler, using this very similar code I can't get the ExecuteCommand function to fire ever.

I have been able to intercept commands using Microsofts older, yuckier DTE or DTE2 interface.

//provider constructor code
var dte2 = (DTE2)Package.GetGlobalService(typeof(DTE));
dte2.Events.CommandEvents.BeforeExecute += CommandEvents_BeforeExecute;

private static void CommandEvents_BeforeExecute(string guid, int id, object customIn, object customOut, ref bool cancelDefault)  
{   //All events fired here use, the guid you want is likely 
    // Microsoft.VisualStudio.VSConstants.CMDSETID.StandardCommandSet97_string
    // With an ID defined in 
    // Microsoft.VisualStudio.VSConstants.VSStd97CmdID
    Debug.WriteLine("CommandEvents_BeforeExecute1 " + String.Format(
                "dte2 GUID: {0}\nID: {1}\nIn: {2}\nOut: {3}",
                guid, id, customIn, customOut));
}
paulwesterberg
  • 644
  • 6
  • 6