英文:
ICommandHandler not executing for SaveCommandArgs (Visual Studio for Mac Extension)
问题
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 the official wiki in GitHub project for Visual Studio API.
Unfortunately, there are 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.
英文:
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
答案1
得分: 1
I agree the examples since Microsoft Visual Studio SDK documentation is horrible with no good examples of ICommandHandler.
我同意这一观点,因为微软的Visual Studio SDK文档中没有提供ICommandHandler的良好示例。
I tried your exact code in visual studio 2022 on Windows 10 and the ExecuteCommand function is called.
我在Windows 10上的Visual Studio 2022中尝试了您的精确代码,并且ExecuteCommand函数被调用。
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.
我认为这里的核心问题是ICommandHandler接口结构相对较新,而微软在正确检查自定义命令处理程序并添加调用方面做得不好。
I am trying to do a similar thing where I add an ICommandHandler to intercept the GoToDefinition command using an ICommandHandler<GoToDefinitionCommandArgs>, using this very similar code I can't get the ExecuteCommand function to fire ever.
我正在尝试类似的操作,其中我使用ICommandHandler<GoToDefinitionCommandArgs>添加了一个ICommandHandler来拦截GoToDefinition命令,但使用这个非常相似的代码,我无法让ExecuteCommand函数触发。
I have been able to intercept commands using Microsofts older, yuckier DTE or DTE2 interface.
我已经能够使用Microsoft较旧的、不太理想的DTE或DTE2接口拦截命令。
//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));
}
英文:
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<GoToDefinitionCommandArgs>, 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));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论