繁体   English   中英

Visual Studio - 在调试时将多行表达式插入Watch Window

[英]Visual Studio - inserting multi-line expressions into Watch Window while debugging

在Visual Studio中进行调试时,如何在监视窗口中插入多行表达式,以便每行不会分成单独的INVALID监视表达式。 这真是令人沮丧,因为我有很多表达式需要观察多行。 请注意,Pin to Source和Immediate Window都不能用于跟踪源代码中许多位置的多个值。

例如

PyFunc1(Py.kw("var1", var1),
        Py.kw("var2", var2))

被打破:

PyFunc1(Py.kw("var1", var1),

Py.kw("var2", var2))

摄制

我不认为这是“By-Design”,它只是不可用的“开箱即用”。

我同意,使用行终止符而不是新行将多行调用添加到监视窗口是更好的行为:

在此输入图像描述


研究

我发现这个类似的问题有一些“解决方法”可供选择: Visual Studio 2010中的多线监视窗口?

我还在MSFT工程师MSDN论坛中发现了这条评论:

我担心它不受支持,我们经常一个一个地编辑它们。 也许您可以提交此功能请求: http//visualstudio.uservoice.com/forums/121579-visual-studio


滚动您自己的Visual Studio加载项

所以我自己动手了,这绝不是生产代码,但它告诉你如何做到:

(点击图片放大)

在此输入图像描述

namespace AddinMultiLineWatch
{
public class Connect : IDTExtensibility2, IDTCommandTarget
{
    //ADD THESE MEMBER VARIABLES
    //private DebuggerEvents _debuggerEvents = null;
    //private _dispDebuggerEvents_OnEnterBreakModeEventHandler DebuggerEvents_OnEnterBreakMode;
    private Window _watchWindow = null;
    private CommandEvents _objCommandEvents;
    private bool _isRecursive = false;
    public Connect()
    {
    }

    public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
    {
        _applicationObject = (DTE2)application;
        _addInInstance = (AddIn)addInInst;

        //SET THE MEMBER VARIABLES
        //_debuggerEvents = _applicationObject.Events.DebuggerEvents;
        //_debuggerEvents.OnEnterBreakMode += new _dispDebuggerEvents_OnEnterBreakModeEventHandler(BreakHandler);
        //var watchWindow = _applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindWatch);
        _objCommandEvents = _applicationObject.Events.CommandEvents;
        _objCommandEvents.BeforeExecute += new _dispCommandEvents_BeforeExecuteEventHandler(BeforeExecute);

        if(connectMode == ext_ConnectMode.ext_cm_UISetup)
        {
            object []contextGUIDS = new object[] { };
            Commands2 commands = (Commands2)_applicationObject.Commands;
            string toolsMenuName = "Tools";

            Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];
ar:
            CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
            CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;

            try
            {
                Command command = commands.AddNamedCommand2(_addInInstance, "AddinMultiLineWatch", "AddinMultiLineWatch", "Executes the command for AddinMultiLineWatch", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);

                if((command != null) && (toolsPopup != null))
                {
                    command.AddControl(toolsPopup.CommandBar, 1);
                }
            }
            catch(System.ArgumentException)
            {
            }
        }
    }

    //ADD THIS METHOD TO INTERCEPT THE DEBUG.ADDWATCH COMMAND
    public void BeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
    {
        EnvDTE.Command objCommand = default(EnvDTE.Command);
        try
        {
            objCommand = _applicationObject.Commands.Item(Guid, ID);
        }
        catch (Exception ex)
        {
        }

        if ((objCommand != null))
        {
            if (objCommand.Name == "Debug.AddWatch")
            {
                //if (_isRecursive) return;
                //_isRecursive = true;
                TextSelection selection = (TextSelection)_applicationObject.ActiveDocument.Selection;
                //TODO make selection goto next semi-colon/Line Terminator...
                var selText = selection.Text;  

                if (string.IsNullOrEmpty(selText)) return;   
                //Only intercept multi-line Add Watch commands                    
                if (selText.Contains(Environment.NewLine))
                {
                  //THE BLACK MAGIC: make it fit in one line! lol
                  selText = selText.Replace(Environment.NewLine, string.Empty);              
                  //THIS CALL IS RECURSIVE, I'LL LEAVE IT TO THE READER AS AN EXERCISE TO SOLVE..
                _applicationObject.ExecuteCommand("Debug.AddWatch", selText);
               }
            }
        }
    }
  1. 创建新项目>其他项目类型>可扩展性> Visual Studio加载项>将其命名为AddinMultiLineWatch

  2. 完成向导

  3. 将上面的代码添加到Connect.cs类 - 请参阅我的//大写注释以及要添加的内容。

  4. 在行上放置一个断点TextSelection selection = (TextSelection)_applicationObject.ActiveDocument.Selection;

  5. 按F5,VS的新实例将启动>选择New Project> Console App>将其命名为TestMultilineAddWatch

  6. 在Console App的program.cs中,指定2行代码调用并在其上放置一个断点,如屏幕截图所示,例如:

     Add(1, //Breakpoint here and select both lines 2); } static int Add(int i, int j) { return i + j; } 
  7. TestMultilineAddWatch解决方案中的F5和代码控制在断点处停止>选择/突出显示两行Add(1, \\r\\n 2) >右键单击>添加监视

  8. 在VS IDE调试上下文菜单中单击Add Watch会导致VS AddinMultiLineWatch解决方案拦截调用并激活,暂停中断点....您将看到将多行代码替换为发送到的单行 的黑魔法观察窗口。

Visual Studio EXEC命令调用本身使这个方法递归,如果你调试它,手动退出递归,你会看到我的截图结果。

快乐的调试!

您可以使用autohotkey和自定义键绑定(例如Alt + Shift + V)来完成

!+ v表示Alt + Shift + v

下面的宏:如果在devenv.exe中,按Alt + Shift + V,编辑剪贴板内容,删除/ r / n并替换为空,然后按Ctrl + V粘贴

我在视觉工作室的文本文档中测试了切割和粘贴。

#IfWinActive ahk_exe devenv.exe
!+v::
FixString = %clipboard%
StringReplace, FixString, FixString,`r`n,,A
Clipboard := FixString
Send, ^v

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM