我正在编写一个自定义工具,就功能而言,我目前正在做我想做的事情。如果出现问题,我希望能够写信给 Visual Studio。(格式不正确的代码或其他)。
这有什么标准吗?现在我基本上可以强制该工具失败,Visual Studio 会发出警告说它已经这样做了。我想要输出窗口中的一个类别,其中包含我想要发送的任何结果消息。我还可以在错误列表窗口中接受更具描述性的任务/警告。
我正在编写一个自定义工具,就功能而言,我目前正在做我想做的事情。如果出现问题,我希望能够写信给 Visual Studio。(格式不正确的代码或其他)。
这有什么标准吗?现在我基本上可以强制该工具失败,Visual Studio 会发出警告说它已经这样做了。我想要输出窗口中的一个类别,其中包含我想要发送的任何结果消息。我还可以在错误列表窗口中接受更具描述性的任务/警告。
要写入 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
关于IVsOutputWindow和IVsOutputWindowPane的详细信息可以在 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);
...
}
...
}
GeneratorError()的详细信息可以在 MSDN 上找到。
还有另一种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;
}
}
如果您希望任何内容出现在“输出”窗口中,它必须来自标准输出。为此,您的应用需要链接为“控制台”应用。在项目的属性页中设置 /SUBSYSTEM:CONSOLE 标志,在 Linker/System 下将 SubSystem 属性设置为 CONSOLE。
一旦你在窗口中有输出,如果你包含文本“错误:”它将显示为一个错误,或者如果你设置“警告:”它将显示为一个警告。如果您的错误文本以路径/文件名开头,后跟括号中的行号,IDE 会将其识别为“可点击”错误,并自动将您导航到错误行。
您可以使用 Debug 和/或 Trace 类。这里有一些信息:http: //msdn.microsoft.com/en-us/library/bs4c1wda (VS.71).aspx
祝你好运。
这在 Microsoft 示例项目的以下帮助程序类中得到了演示:
代码如下:
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.");
}
}
}
}
采用System.Diagnostics.Debugger.Message