locked
How to add a warning instead of an error with OutputTaskItemString RRS feed

  • Question

  • I'm using OutputTaskItemString on the Build output pane to add compile errors for a script system.  I can add errors but I'm having trouble figuring out how to add warnings.  Is there a way to flag them as warnings as well or do I have to create an error provider?
    Thursday, March 8, 2012 6:10 PM

Answers

  • Try using OutputTaskItemStringEx and passing in CAT_BUILDCOMPILE for the category and TP_NORMAL as the priority.

    Ryan

    Thursday, March 8, 2012 6:20 PM
  • From the VS command prompt:

    C:\Windows\system32>err -2147023116
    # as an HRESULT: Severity: FAILURE (1), FACILITY_WIN32 (0x7), Code 0x6f4
    # for decimal 1780 / hex 0x6f4
      RPC_X_NULL_REF_POINTER                                         winerror.h
    # A null reference pointer was passed to the stub.
    # 1 matches found for "-2147023116"

    This means our IDL is likely missing a [unique] attribute which would allow the pointer params to be null.  Try not passing null for the various string params and instead pass String.Empty.

    Ryan

    • Marked as answer by Joe NC Friday, March 9, 2012 4:42 AM
    Friday, March 9, 2012 4:15 AM

All replies

  • Try using OutputTaskItemStringEx and passing in CAT_BUILDCOMPILE for the category and TP_NORMAL as the priority.

    Ryan

    Thursday, March 8, 2012 6:20 PM
  • Hmm.. switching to OutputTaskItemStringEx causes nothing to be displayed.  Here is my code (VS2010)

    public static void BuildOutputErrorLog(string Text, bool bWarning, string Filename, int Line, string Desc)
    {
        IVsOutputWindowPane BuildOutput = null;
        IVsOutputWindow Window = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsOutputWindow)) as IVsOutputWindow;
        if (Window != null)
        {
            Guid PaneGuid = VSConstants.GUID_BuildOutputWindowPane;
            if (ErrorHandler.Failed(Window.GetPane(ref PaneGuid, out BuildOutput)))
            {
                BuildOutput = null;
            }
        }

        if (BuildOutput != null)
        {
            BuildOutput.Activate();
            VSTASKPRIORITY Pri = bWarning ? VSTASKPRIORITY.TP_NORMAL : VSTASKPRIORITY.TP_HIGH;
            VSTASKCATEGORY Cat = VSTASKCATEGORY.CAT_BUILDCOMPILE;
            BuildOutput.OutputTaskItemStringEx(Text, Pri, Cat, null, 0, Filename,(uint) Line, Desc, null);
        }
    }

    Stepping through everything seems right, but nothing is getting added to my task list.

    Thursday, March 8, 2012 7:16 PM
  • Sorry, I assumed you wanted your errors to go to the error list.  VS has a wacky relationship between the task and error list, I believe it is because the task list pre-dated the error list and when the error list was introduced instead of making everyone that used to be sending errors to the task list rewrite their code to send them to the error list there was just some 'magic' inserted into the task list that would redirect tasks which had certain categories to be displayed in the error list.

    Perhaps using a different category would help as BUILDCOMPILE is one of the 'magic' ones (along with CODESENSE I believe) that would cause this redirection.

    Though most users expect build errors to show up in the error list not the task list, are you putting them into the task list?

    Ryan

    Thursday, March 8, 2012 7:52 PM
  • Sorry, I meant to say nothing is getting added to my error list.  I did notice a mistake where I wasn't setting the bitmap, but I've fixed that.  Still nothing in the error list.  I did notice that the text also doesn't end up in the Output window.  Is it possible GetPane is returning the wrong window?

    Before I was using DTE.ToolWindow.OutputWindow.OutputWindowPanes.Item("Build") to get the build output.  There I could add errors but I'm assuming this is the better way.

    Thursday, March 8, 2012 8:15 PM
  • Hmmm the 'not showing up in the output window' is more suspect, or at least the primary concern here.  What version of VS is this?

    Ryan

    Thursday, March 8, 2012 9:11 PM
  • VS 2010 SP1.  It's not showing up in either right.  From my understanding, is that by calling OutputTaskItemStringEx it should show the text in the Output Window and add the error.  In this case it's doing neither which is why I was wondering if maybe it's getting the wrong window.
    Thursday, March 8, 2012 9:20 PM
  • Let me try and throw together a repro I could debug into, something seems off :) I know the output window has a buffering mechanism, so it may not display immediately, but the timer is rather short iirc, so it shouldn't be delayed by any reasonably noticeable amount of time.

    Ryan

    Thursday, March 8, 2012 9:51 PM
  • It seems to work fine for me using the same code you have above.  I see the output written to the output window and appearing as a warning on the error list.  To make sure all the 'obvious' bases are covered

    1:  Is you error list set up to actually show warnings? You can toggle the Warnings button on the toolbar into an unlatched state and it will hide warnings.

    2:  Are you doing this from the UI thread or is the UI thread able to pump messages while this is occuring (i.e. necessary for repainting to occur).

    Ryan


    • Edited by Ryan MoldenMicrosoft employee Thursday, March 8, 2012 11:00 PM corrected 'hide errors' in point 1 to 'hide warnings' as it is warnings we are talking about here
    Thursday, March 8, 2012 10:06 PM
  • BuildOutputErrorLog() is called from within my own thread.  I create a process that launches an external script compiler and I watch it's console output for the error.  This watching occurs in it's own thread and when an error occurs I call BuildOutputErrorLog().  I dump non-error console output using a similar function that calls OutputString() on the Pane (same watcher thread) and it's showing up fine.  I have to be missing something small.
    Friday, March 9, 2012 1:07 AM
  • I had the same code as you above but I was running on the UI thread.  Can you try simply outputting anything (a test message for instance) from the UI thread to ensure this isn't some weird marshalling issue?  Technically, since you are asking for the OutputWindow from GetGlobalService, and it, under the covers, is using a UI thread bound IServiceProvider, the CLR should be marshalling the call to GetService to the UI thread, thus the OutputWindow RCW should be UI thread bound and all calls made to it (specifically GetPane) should happen on the UI thread automatically.  Further the OutputWindowPane that GetPane returns should be likewise UI thread bound and thus calls to IT'S methods should also be automatically marshalled to the UI thread.

    Edit:  Also check to make sure OutputTaskItemStringEx isn't returning an error code, you are ignoring it above.

    Ryan


    Friday, March 9, 2012 1:18 AM
  • Outputting from the UI thread works,

    although there is a considerable delay before the results appear.  In the Watcher thread it does seem to be failing with the return code of -2147023116.  A search turned up nothing.  

    edit: I also adjusted the code to insure the exact same call between the UI and the Watcher thread with the same result so it's not the data being passed in.  And by UI thread, the working call is in the "Main Thread".  I don't see a "UI Thread" in the threads list so I'm assuming that's the proper thread.  The delay is it doesn't update the error list until I force the list to refresh (change a tab/etc).


    • Edited by Joe NC Friday, March 9, 2012 3:33 AM
    Friday, March 9, 2012 3:18 AM
  • From the VS command prompt:

    C:\Windows\system32>err -2147023116
    # as an HRESULT: Severity: FAILURE (1), FACILITY_WIN32 (0x7), Code 0x6f4
    # for decimal 1780 / hex 0x6f4
      RPC_X_NULL_REF_POINTER                                         winerror.h
    # A null reference pointer was passed to the stub.
    # 1 matches found for "-2147023116"

    This means our IDL is likely missing a [unique] attribute which would allow the pointer params to be null.  Try not passing null for the various string params and instead pass String.Empty.

    Ryan

    • Marked as answer by Joe NC Friday, March 9, 2012 4:42 AM
    Friday, March 9, 2012 4:15 AM
  • That was the trick. Thanks for the help.
    Friday, March 9, 2012 4:42 AM
  • There is still a small issue in that it doesn't update the list until something forces the refresh.  Even calling Activate() on it doesn't seem to work.  I was able to work around it by toggling ShowErrors twice but there has to be a better way.  Am I right in that the main thread is the UI thread?
    Friday, March 9, 2012 5:39 AM
  • Yes, the main thread is the UI thread. Can you try calling FlushToTaskList on the pane? Either on build completion or (less ideally) after each call to OutputTaskItem?

    Ryan

    Friday, March 9, 2012 6:45 AM