以编程方式重置VisualStudio快捷键

14
有两个相关问题重置VisualStudio键盘方案导入VisualStudio设置。但是,这些似乎不能很好地一起使用。
我有两个包含快捷方式的设置文件:
<!-- IntelliJ.vssettings -->   
<ShortcutsScheme>Visual C# 2005</ShortcutsScheme>
<UserShortcuts>
  <Shortcut Command="ReSharper.ReSharper_GotoNextHighlight" Scope="Global">F12</Shortcut>
</UserShortcuts>

<!-- ReSharper.vssettings -->   
<ShortcutsScheme>Visual C# 2005</ShortcutsScheme>
<UserShortcuts>
  <!-- Implicitly has F12 assigned to Edit.GoToDefinition -->
</UserShortcuts>

正如您看到的,ReSharper.vssettings没有真正分配F12快捷键,因为它是VisualStudio的默认设置。导入该文件将不会重新应用ShortcutsScheme,在这两种情况下都是Visual Studio C# 2005。这反过来导致F12继续执行GotoNextHighlight命令。当使用导入对话框时也会出现同样的问题。

使用以下方法来重置键盘方案,也无法解决问题:

var property = dte.Properties["Environment", "Keyboard"];
property.Item("SchemeName").Value = "(Default)";

导出默认设置也无法工作,原因相同。如此处所示,没有快捷方式被导出。
问题是:我如何使用DTE编程重置VisualStudio键盘方案?
实际上我需要的是在选项|环境|键盘对话框中触发“重置”按钮的命令。

相关链接:http://stackoverflow.com/questions/40525815/programmatically-change-visual-studio-options - Jeremy Thompson
2个回答

4
您可以按以下方式删除特定的键绑定: Visual Studio键绑定配置文件 不幸的是,我没有IntelliJ和ReSharper来测试它是否有效。如果有效,最好使用DTE执行此操作,但是这种解决方案超出了DTE的范围,并且可以使用System.IO.File轻松解决。
更新:
问题:如何使用DTE以编程方式重置VisualStudio键盘方案?实际上,我需要的是在选项|环境|键盘对话框中触发重置按钮的命令。
不幸的是,您无法(据我所知)这样做,因为重置键盘快捷键超出了DTE的范围。
如果您设置一个名为“ResetKeyBoard”的VS AddIn项目,并在Exec方法上放置断点,则会看到DTE在您处于Tools Options窗口内时没有捕获到任何Visual Studio事件触发,它们只是未通过DTE对象模型公开。
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)

这也可以通过录制宏来证明,录制的命令只能深入到打开选项对话框(无论更改其中的哪些设置):
Public Module RecordingModule
    Sub TemporaryMacro()
        DTE.ExecuteCommand("Tools.Options")
    End Sub
End Module

我确实学会了如何直接打开选项窗口的键盘选项卡,但由于它是模态对话框,您甚至不能使用SendKeys来按下重置按钮:

public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
        {
            handled = false;
            if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
            {
                if(commandName == "ResetKeyBoard.Connect.ResetKeyBoard")
                {
                    _applicationObject.ExecuteCommand("Tools.Options", "BAFF6A1A-0CF2-11D1-8C8D-0000F87570EE");
                    System.Windows.Forms.SendKeys.Send("%e");
                    System.Windows.Forms.SendKeys.Send("{ENTER}");

我尝试过最后一个 DTE 选项(不成功)是使用 Commands.Raise,但你无法深入到打开工具选项中,或者至少如果你能的话,这是未记录的
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
    handled = false;
    if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
    {
        if(commandName == "ResetKeyBoard.Connect.ResetKeyBoard")
        {
            Commands cmds = _applicationObject.Commands;
            Command cmdobj = cmds.Item("Tools.Options");
            object customIn = null;
            object customOut = null;
            _applicationObject.Commands.Raise(cmdobj.Guid, cmdobj.ID, ref customIn, ref customOut);

解决方法:

a)我不建议替换Visual C# 2005.vsk文件,但如果你想调查一下这个文件:

C:\Program Files (x86)\Microsoft Visual Studio 1X.0\Common7\IDE\Visual C# 2005.vsk

MSDN警告

您无法以编程方式更改默认键盘映射方案的设置。要更改设置,请将默认键盘映射方案另存为“选项”对话框中的“键盘”节点中。然后,您可以更改该映射方案中的设置。

我不推荐或鼓励此方法,这是糟糕的编程实践,可能会破坏某人的键盘快捷键!

b) 另一种方法是创建自己的VSK文件并将其设置为currentSettings.vssettings:

    </ScopeDefinitions>
     <ShortcutsScheme>Visual C# JT</ShortcutsScheme>
    </KeyboardShortcuts>

enter image description here

在修改之前,请确保备份 currentSettings.vssettings 文件。

c) 这与 Chris Dunaway 的建议相一致,您可以创建一个纯包含键盘快捷方式的 vssettings 文件,并将其导入以重置键盘快捷方式。我知道默认快捷方式不会被保存,但以下是一些您可以使用 DTE 代码导出命令并插入到新的 vssettings 文件中以导入的代码:

//note, this is untested code!
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
    handled = false;
    if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
    {
        if(commandName == "ResetKeyBoard.Connect.ResetKeyBoard")
        {
            System.Diagnostics.Debug.WriteLine("<UserShortcuts>");
            foreach (Command c in _applicationObject.Commands)
            {
                if (!string.IsNullOrEmpty(c.Name))
                {
                    System.Array bindings = default(System.Array);
                    bindings = (System.Array)c.Bindings;
                    for (int i = 0; i <= bindings.Length - 1; i++)
                    {
                        string scope = string.Empty;
                        string keyShortCut = string.Empty;
                        string[] binding = bindings.GetValue(i).ToString().Split(new string[] {  "::" },StringSplitOptions.RemoveEmptyEntries );
                        scope = binding[0];
                        keyShortCut = binding[1];
                        System.Diagnostics.Debug.WriteLine("<RemoveShortcut Command=\"...\" Scope=\"" + scope + "\">" + keyShortCut + "</RemoveShortcut>");
                        System.Diagnostics.Debug.WriteLine("<Shortcut Command=\"" + c.Name + "\" Scope=\"" + scope + "\">" + keyShortCut + "</Shortcut>");
                    }
                }
            }
            System.Diagnostics.Debug.WriteLine("</UserShortcuts>");

一旦你把它们弄出来,将它们导入就很容易了:
_applicationObject.ExecuteCommand("Tools.ImportandExportSettings", "/import:\"KeyboardOnly-Exported-2016-08-29.vssettings\"");

REFs:

Visual Studio 2005 IDE技巧和窍门

如何使用单个快捷方式将Visual Studio设置重置为已保存的设置?

如何舒适地设置Visual Studio 2010键盘快捷键,特别是在使用ReSharper时?

是否有一种快速删除Visual Studio 10中所有快捷方式的方法?

使用宏在Visual Studio中删除键盘快捷键绑定

http://vswindowmanager.codeplex.com/

获取DTE.ExecuteCommand可用命令的完整列表

HOWTO:从Visual Studio包中通过Guid和Id执行命令

HOWTO:从Visual Studio插件中通过Guid和Id执行命令

HOWTO:从Visual Studio插件中以编程方式向命令传递参数

最后这个是Jared Par写的:

https://github.com/jaredpar/VsVim/blob/master/Src/VsVimShared/Extensions.cs

/// <summary>
/// Safely reset the keyboard bindings on this Command to the provided values
/// </summary>
public static void SafeSetBindings(this DteCommand command, IEnumerable<string> commandBindings)
{
    try
    {
        var bindings = commandBindings.Cast<object>().ToArray();
        command.Bindings = bindings;

        // There are certain commands in Visual Studio which simply don't want to have their
        // keyboard bindings removed.  The only way to get them to relinquish control is to
        // ask them to remove the bindings twice.  
        //
        // One example of this is SolutionExplorer.OpenFilesFilter.  It has bindings for both
        // "Ctrl-[, O" and "Ctrl-[, Ctrl-O".  Asking it to remove all bindings will remove one
        // but not both (at least until you restart Visual Studio, then both will be gone).  If
        // we ask it to remove bindings twice though then it will behave as expected.  
        if (bindings.Length == 0 && command.GetBindings().Count() != 0)
        {
            command.Bindings = bindings;
        }
    }
    catch (Exception)
    {
        // Several implementations, Transact SQL in particular, return E_FAIL for this
        // operation.  Simply ignore the failure and continue
    }

抱歉,出错了!失败了! - Jeremy Thompson
你能否尝试使用我回答中的更新信息来删除它。这与之前的原理相同(删除而不是重置),只是这次使用了正确的技术。 - Jeremy Thompson
我会将其作为备选方案。但是,它不够“通用”。我已经概述了IntelliJ/ReSharper方案作为一个示例。实际上,那些vssettings可以包含任何内容。演示设置、设计模式设置等等...在这些情况下,我当然想保留快捷键。 - Matthias
好的,看看我的最新更新,我已经尽力了。希望有人能提供比第三个解决方法或JaredPars项目更好的答案。 - Jeremy Thompson

-1

您可以直接调用devenv.exe并传递/ResetSettings开关。以下是Visual Studio命令行选项的链接: https://msdn.microsoft.com/en-us/library/xee0c8y7.aspx

您可以使用Systems.Diagnostics.Process类执行devenv.exe以重置设置:

Devenv.exe /ResetSettings

您可以选择性地传递包含要恢复的设置的设置文件:

Devenv.exe /ResetSettings "C:\My Files\MySettings.vssettings"

在Visual Studio中,您可以通过转到工具>导入和导出设置...并选择“导出所选环境设置”来导出所选设置。然后,在所有设置>选项>环境子树下仅选择键盘复选框。


@Matthias - 你不能只创建一个只包含键盘设置的.vssettings文件,然后与ResetSettings一起使用吗?请参见我的编辑。 - Chris Dunaway
如果你导出默认设置,它不会写入任何内容到那个vssettings文件中。所以答案是否定的。 - Matthias
@Matthias - 我不确定为什么这个不起作用。如果你在VS中设置了你想要的键,那就会被导出到vssettings文件中。我的环境(VS2013)是设置为C#的默认值,我可以得到一个输出文件。 - Chris Dunaway
我已经编辑了我的问题,表明不会导出任何默认快捷键。 - Matthias
@Matthias - 你不能将IntelliJ和ReSharper的.vssettings文件合并后导入吗? - Chris Dunaway
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接