簡體   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