簡體   English   中英

如何在我的自定義工具中寫入 Visual Studio Output Window?

[英]How do I write to the Visual Studio Output Window in My Custom Tool?

我正在編寫一個自定義工具,目前我正在使用它來實現我想要的功能。 如果出現問題,我希望能夠寫入 Visual Studio。 (格式不正確的代碼或其他)。

這有什么標准嗎? 現在我基本上可以強制該工具失敗,而 Visual Studio 會發出警告,說明它已經這樣做了。 我想要 Output window 中的一個類別,其中包含我要發送的任何結果消息。 我還可以接受錯誤列表 window 中更具描述性的任務/警告。

輸出窗口

要在Visual Studio中寫入“常規”輸出窗口,您需要執行以下操作:

IVsOutputWindow outWindow = Package.GetGlobalService( typeof( SVsOutputWindow ) ) as IVsOutputWindow;

Guid generalPaneGuid = VSConstants.GUID_OutWindowGeneralPane; // P.S. There's also the GUID_OutWindowDebugPane available.
IVsOutputWindowPane generalPane;
outWindow.GetPane( ref generalPaneGuid , out generalPane );

generalPane.OutputString( "Hello World!" );
generalPane.Activate(); // Brings this pane into view

但是,如果要寫入自定義窗口,則需要執行以下操作:

IVsOutputWindow outWindow = Package.GetGlobalService( typeof( SVsOutputWindow ) ) as IVsOutputWindow;

// Use e.g. Tools -> Create GUID to make a stable, but unique GUID for your pane.
// Also, in a real project, this should probably be a static constant, and not a local variable
Guid customGuid = new Guid("0F44E2D1-F5FA-4d2d-AB30-22BE8ECD9789");
string customTitle = "Custom Window Title";
outWindow.CreatePane( ref customGuid, customTitle, 1, 1 );

IVsOutputWindowPane customPane;
outWindow.GetPane( ref customGuid, out customPane);

customPane.OutputString( "Hello, Custom World!" );
customPane.Activate(); // Brings this pane into view

有關IVsOutputWindowIVsOutputWindowPane的詳細信息,請訪問 MSDN。

錯誤列表

為了將項添加到錯誤列表, IVsSingleFileGenerator有一個方法調用void Generate(...) ,其參數類型為IVsGeneratorProgress 此接口有一個方法void GeneratorError() ,它允許您向Visual Studio錯誤列表報告錯誤和警告。

public class MyCodeGenerator : IVsSingleFileGenerator
{
    ...
    public void Generate( string inputFilePath, string inputFileContents, string defaultNamespace, out IntPtr outputFileContents, out int output, IVsGeneratorProgress generateProgress )
    {
        ...
        generateProgress.GeneratorError( false, 0, "An error occured", 2, 4);
        ...
    }
    ...
}

可以在MSDN上找到GeneratorError()的詳細信息。

還有另一種方法使用Marshal.GetActiveObject來獲取正在運行的DTE2實例。

首先參考EnvDTE和envdte80。 這目前在VisualStudio 2012中有效,我還沒有嘗試過其他的。

using System;
using System.Runtime.InteropServices;
using EnvDTE;
using EnvDTE80;

internal class VsOutputLogger
{
    private static Lazy<Action<string>> _Logger = new Lazy<Action<string>>( () => GetWindow().OutputString );

    private static Action<string> Logger
    {
        get { return _Logger.Value; }
    }

    public static void SetLogger( Action<string> logger )
    {
        _Logger = new Lazy<Action<string>>( () => logger );
    }

    public static void Write( string format, params object[] args)
    {
        var message = string.Format( format, args );
        Write( message );
    }

    public static void Write( string message )
    {
        Logger( message + Environment.NewLine );
    }

    private static OutputWindowPane GetWindow()
    {
        var dte = (DTE2) Marshal.GetActiveObject( "VisualStudio.DTE" );
        return dte.ToolWindows.OutputWindow.ActivePane;
    }
}

如果要在“輸出”窗口中顯示任何內容,則必須來自stdout。 為此,您的應用需要作為“控制台”應用進行關聯。 在項目的屬性頁面中設置/ SUBSYSTEM:CONSOLE標志,在Linker / System下將SubSystem屬性設置為CONSOLE。

在窗口中輸出輸出后,如果包含文本“錯誤:”,它將顯示為錯誤,或者如果設置“警告:”,它將顯示為警告。 如果您的錯誤文本以路徑/文件名開頭,后跟括號中的行號,則IDE會將其識別為“可單擊”錯誤,並自動導航到錯誤行。

Microsoft 示例項目中的以下幫助程序 class 對此進行了演示:

https://github.com/microsoft/VSSDK-Extensibility-Samples/blob/df10d37b863feeff6e8fcaa6f4d172f602a882c5/Reference_Services/C%23/Reference.Services/HelperFunctions.cs#L28

代碼如下:

using System;
using System.Diagnostics;
using Microsoft.VisualStudio.Shell.Interop;

namespace Microsoft.Samples.VisualStudio.Services
{
    /// <summary>
    /// This class is used to expose some utility functions used in this project.
    /// </summary>
    internal static class HelperFunctions
    {
        /// <summary>
        /// This function is used to write a string on the Output window of Visual Studio.
        /// </summary>
        /// <param name="provider">The service provider to query for SVsOutputWindow</param>
        /// <param name="text">The text to write</param>
        internal static void WriteOnOutputWindow(IServiceProvider provider, string text)
        {
            // At first write the text on the debug output.
            Debug.WriteLine(text);

            // Check if we have a provider
            if (null == provider)
            {
                // If there is no provider we can not do anything; exit now.
                Debug.WriteLine("No service provider passed to WriteOnOutputWindow.");
                return;
            }

            // Now get the SVsOutputWindow service from the service provider.
            IVsOutputWindow outputWindow = provider.GetService(typeof(SVsOutputWindow)) as IVsOutputWindow;
            if (null == outputWindow)
            {
                // If the provider doesn't expose the service there is nothing we can do.
                // Write a message on the debug output and exit.
                Debug.WriteLine("Can not get the SVsOutputWindow service.");
                return;
            }

            // We can not write on the Output window itself, but only on one of its panes.
            // Here we try to use the "General" pane.
            Guid guidGeneral = Microsoft.VisualStudio.VSConstants.GUID_OutWindowGeneralPane;
            IVsOutputWindowPane windowPane;
            if (Microsoft.VisualStudio.ErrorHandler.Failed(outputWindow.GetPane(ref guidGeneral, out windowPane)) ||
                (null == windowPane))
            {
                if (Microsoft.VisualStudio.ErrorHandler.Failed(outputWindow.CreatePane(ref guidGeneral, "General", 1, 0)))
                {
                    // Nothing to do here, just debug output and exit
                    Debug.WriteLine("Failed to create the Output window pane.");
                    return;
                }
                if (Microsoft.VisualStudio.ErrorHandler.Failed(outputWindow.GetPane(ref guidGeneral, out windowPane)) ||
                (null == windowPane))
                {
                    // Again, there is nothing we can do to recover from this error, so write on the
                    // debug output and exit.
                    Debug.WriteLine("Failed to get the Output window pane.");
                    return;
                }
                if (Microsoft.VisualStudio.ErrorHandler.Failed(windowPane.Activate()))
                {
                    Debug.WriteLine("Failed to activate the Output window pane.");
                    return;
                }
            }

            // Finally we can write on the window pane.
            if (Microsoft.VisualStudio.ErrorHandler.Failed(windowPane.OutputString(text)))
            {
                Debug.WriteLine("Failed to write on the Output window pane.");
            }
        }
    }
}

您可以使用Debug和/或Trace類。 這里有一些信息: http//msdn.microsoft.com/en-us/library/bs4c1wda(VS.71).aspx

祝你好運。

使用System.Diagnostics.Debugger.Message

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM