【问题标题】:Programmatically reset VisualStudio shortcuts以编程方式重置 VisualStudio 快捷方式
【发布时间】:2016-08-19 16:17:16
【问题描述】:

有两个关于resetting VisualStudio keyboard scheme 和importing VisualStudio settings 的相关问题。但是,这似乎并不能很好地结合在一起。

我有两个包含快捷方式的设置文件:

<!-- 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 命令。仅使用导入对话框时同样的问题。

如下使用DTE重置键盘方案也不行:

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

出于同样的原因,无法导出默认设置。正如shown here 没有导出快捷方式。

因此的问题:如何使用 DTE 以编程方式重置 VisualStudio 键盘方案?

我真正需要的是触发选项 | 中的Reset 按钮的命令环境 |键盘对话框。

【问题讨论】:

标签: c# visual-studio envdte


【解决方案1】:

您可以按照以下方式删除特定的键绑定: Visual Studio key bindings configuration file

不幸的是,我没有 IntelliJ 和 ReSharper 来测试它是否有效。如果确实如此,那么使用 DTE 会很好,但是这个解决方案超出了 DTE 的范围,使用 System.IO.File 将是微不足道的。

更新:

问题:如何使用 DTE 以编程方式重置 VisualStudio 键盘方案?我真正需要的是触发选项中的重置按钮的命令|环境 |键盘对话框。

很遗憾,您不能这样做 (AFAIK),因为重置键盘快捷键超出了 DTE 的范围。

如果您设置一个名为“ResetKeyBoard”的 VS AddIn 项目并在 Exec 方法上放置一个断点,您将看到 DTE 在“工具选项”窗口中没有捕获任何触发的 Visual Studio 事件,它们根本不是t 通过 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 Warning

您不能以编程方式更改默认键盘映射方案的设置。要更改设置,请在“选项”对话框的“键盘”节点中保存默认键盘映射方案的副本。然后,您可以更改该映射方案中的设置。

我不推荐或鼓励这种方法,它的编程很糟糕,你可能会破坏某人的键盘快捷键!

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

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

确保在更改之前备份 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\"");

参考:

Visual Studio 2005 IDE Tips and Tricks

How to reset visual studio settings to my saved settings with just a single shortcut?

How does one set Visual Studio 2010 keyboard shortcuts comfortably, especially when using ReSharper?

https://superuser.com/questions/914244/is-there-a-quick-way-to-delete-all-shortcuts-in-visual-studio-10

Remove a keyboard shortcut binding in Visual Studio using Macros

http://vswindowmanager.codeplex.com/

Get full list of available commands for DTE.ExecuteCommand

HOWTO: Execute a command by Guid and Id from a Visual Studio package

HOWTO: Execute a command by Guid and Id from a Visual Studio add-in

HOWTO: Pass parameters programmatically to a command from a Visual Studio add-in

最后是 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
    }

【讨论】:

  • 呃呃呃,失败了!对不起
  • 您能否尝试使用我回答中的更新信息将其删除。它和以前的原理相同(移除而不是重置),只是这次的技术正确。
  • 我会保留这个作为备用计划。然而,它还不够通用。我已经概述了 IntelliJ/ReSharper 方案作为示例。实际上,那些 vssettings 可以包含任何东西。演示设置、设计模式设置等...在这些情况下,我当然想保留快捷方式。
  • 好的,看看我的最新更新,我已经尽力了。希望其他人提供比第三种解决方法或 JaredPars 项目更好的答案。
【解决方案2】:

您可以直接调用 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 中,您可以通过转到工具 > 导入和导出设置...并选择“导出选定的环境设置”来导出选定的设置。然后,只选择 All Settings > Options > Environment 子树下的 Keyboard 复选框。

【讨论】:

  • @Matthias - 你不能只创建一个仅包含键盘设置的 .vssettings 文件,然后将其与 ResetSettings 结合使用吗?查看我的编辑。
  • 如果您导出默认设置,它不会向该 vssettings 文件写入任何内容。所以,没有。
  • @Matthias - 我不确定我理解为什么这不起作用。如果您在 VS 中按照您希望的方式设置了密钥,那么这就是将导出到 vssettings 文件中的内容。我的环境(VS2013)设置为 C# 的默认值,我得到一个输出文件。
  • 已经编辑了我的问题,显示 no 默认快捷方式将被导出。
  • @Matthias - 你不能将 IntelliJ 和 ReSharper 的 .vssettings 文件合并并导入吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
相关资源
最近更新 更多