简体   繁体   English

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

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

While debugging in Visual Studio, how can I insert multi-line expressions into Watch Window, so that each line is not broken into a separate INVALID watch expression. 在Visual Studio中进行调试时,如何在监视窗口中插入多行表达式,以便每行不会分成单独的INVALID监视表达式。 This is really frustrating because I have many expressions spanning multiple lines that I need to watch. 这真是令人沮丧,因为我有很多表达式需要观察多行。 Note that both Pin to Source and Immediate Window do not work for tracking multiple values from many places in source code. 请注意,Pin to Source和Immediate Window都不能用于跟踪源代码中许多位置的多个值。

eg 例如

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

gets broken to: 被打破:

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

and

Py.kw("var2", var2))

Repro 摄制

I dont think this is "By-Design", its just unavailable "out-of-the-box". 我不认为这是“By-Design”,它只是不可用的“开箱即用”。

I agree, it'd be better behaviour for multi-line calls to be added to the Watch Window using line terminators instead of new lines: 我同意,使用行终止符而不是新行将多行调用添加到监视窗口是更好的行为:

在此输入图像描述


Research 研究

I found this similar question with a few "workarounds" to choose from: Multi-Line Watch Window in Visual Studio 2010? 我发现这个类似的问题有一些“解决方法”可供选择: Visual Studio 2010中的多线监视窗口?

I also found this comment in the MSDN Forums by a MSFT Engineer : 我还在MSFT工程师MSDN论坛中发现了这条评论:

I'm afraid that it is not supported, we often edit them one by one. 我担心它不受支持,我们经常一个一个地编辑它们。 Maybe you could submit this feature request: http://visualstudio.uservoice.com/forums/121579-visual-studio 也许您可以提交此功能请求: http//visualstudio.uservoice.com/forums/121579-visual-studio


Roll your own Visual Studio Add-In 滚动您自己的Visual Studio加载项

So I had a go at it myself, this is by no means production code but it shows you how to do it: 所以我自己动手了,这绝不是生产代码,但它告诉你如何做到:

(click image to enlarge) (点击图片放大)

在此输入图像描述

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. Create a New Project > Other Project Types > Extensibility > Visual Studio Add-In > name it AddinMultiLineWatch 创建新项目>其他项目类型>可扩展性> Visual Studio加载项>将其命名为AddinMultiLineWatch

  2. Go through the wizard 完成向导

  3. Add the code above to the Connect.cs class - see my //UPPERCASE comments with what stuff to add. 将上面的代码添加到Connect.cs类 - 请参阅我的//大写注释以及要添加的内容。

  4. Put a break point on the line TextSelection selection = (TextSelection)_applicationObject.ActiveDocument.Selection; 在行上放置一个断点TextSelection selection = (TextSelection)_applicationObject.ActiveDocument.Selection;

  5. Press F5 and a new instance of VS will launch > choose New Project > Console App > name it TestMultilineAddWatch 按F5,VS的新实例将启动>选择New Project> Console App>将其命名为TestMultilineAddWatch

  6. In the program.cs of the Console App, specify a code call over 2 lines and put a break point on it, as shown in the screenshot, eg: 在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. F5 in the TestMultilineAddWatch solution and when the code control halts on the break point > select/highlight the two lines Add(1, \\r\\n 2) > right click > Add Watch TestMultilineAddWatch解决方案中的F5和代码控制在断点处停止>选择/突出显示两行Add(1, \\r\\n 2) >右键单击>添加监视

  8. Clicking Add Watch in the VS IDE debugging context menu causes the VS AddinMultiLineWatch solution to intercept the call and activate, halting on the break point.... where you will see the black magic of replacing multi lined code in to a single line sent to the Watch Window. 在VS IDE调试上下文菜单中单击Add Watch会导致VS AddinMultiLineWatch解决方案拦截调用并激活,暂停中断点....您将看到将多行代码替换为发送到的单行 的黑魔法观察窗口。

The Visual Studio EXEC command calling itself makes this method recursive, if you debug it, exiting out of the recursion manually you will see the results as per my screenshot. Visual Studio EXEC命令调用本身使这个方法递归,如果你调试它,手动退出递归,你会看到我的截图结果。

Happy debugging! 快乐的调试!

You could do it using autohotkey and a custom key binding ( eg Alt+Shift+V) 您可以使用autohotkey和自定义键绑定(例如Alt + Shift + V)来完成

!+v means Alt+Shift+v !+ v表示Alt + Shift + v

The macro below: If in devenv.exe, and you press Alt+Shift+V, edit the clipboard contents, removing /r/n and replace them with nothing, then press Ctrl+V to paste 下面的宏:如果在devenv.exe中,按Alt + Shift + V,编辑剪贴板内容,删除/ r / n并替换为空,然后按Ctrl + V粘贴

I tested this out cutting and pasting in a text document in visual studio. 我在视觉工作室的文本文档中测试了切割和粘贴。

#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