/**************************************************************************** ** ** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt VS Tools. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ using System; using System.Threading.Tasks; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Threading; using Task = System.Threading.Tasks.Task; namespace QtVsTools.Core { using VisualStudio; public class OutputWindowPane { public enum VSOutputWindowPane { General, Build, Debug, } public static Task GetVSOutputWindowPaneAsync(VSOutputWindowPane pane) { switch (pane) { case VSOutputWindowPane.General: return GetAsync(VSConstants.OutputWindowPaneGuid.GeneralPane_guid); case VSOutputWindowPane.Build: return GetAsync(VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid); case VSOutputWindowPane.Debug: return GetAsync(VSConstants.OutputWindowPaneGuid.DebugPane_guid); default: throw new InvalidOperationException("Unsupported Visual Studio output pane"); }; } public static async Task GetAsync(Guid guid) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); try { IVsOutputWindow w = null; if (guid == VSConstants.OutputWindowPaneGuid.GeneralPane_guid) { w = await VsServiceProvider.GetServiceAsync(); } else { w = await VsServiceProvider.GetServiceAsync(); } ErrorHandler.ThrowOnFailure(w.GetPane(guid, out IVsOutputWindowPane pane)); return new OutputWindowPane(guid, pane); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); return null; } } public static async Task CreateAsync(string name, Guid guid) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException($"{ nameof(name) } cannot be null"); await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); try { var w = await VsServiceProvider.GetServiceAsync(); const int visible = 1, clear = 1; ErrorHandler.ThrowOnFailure(w.CreatePane(guid, name, visible, clear)); ErrorHandler.ThrowOnFailure(w.GetPane(guid, out IVsOutputWindowPane pane)); return new OutputWindowPane(guid, pane); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); return null; } } public static async Task GetActiveAsync() { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); try { var w2 = await VsServiceProvider .GetServiceAsync() as IVsOutputWindow2; ErrorHandler.ThrowOnFailure(w2.GetActivePaneGUID(out Guid guid)); IVsOutputWindow w = w2 as IVsOutputWindow; ErrorHandler.ThrowOnFailure(w.GetPane(guid, out IVsOutputWindowPane pane)); return new OutputWindowPane(guid, pane); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); return null; } } private Guid Guid { get; } private IVsOutputWindowPane Pane { get; set; } = null; private OutputWindowPane(Guid guid, IVsOutputWindowPane pane) { Guid = guid; Pane = pane; } public async Task ActivateAsync() { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (Pane == null) throw new InvalidOperationException($"{ nameof(Pane) } cannot be null"); Pane.Activate(); } public async Task HideAsync() { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (Pane == null) throw new InvalidOperationException($"{ nameof(Pane) } cannot be null"); Pane.Hide(); } public async Task ClearAsync() { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (Pane == null) throw new InvalidOperationException($"{ nameof(Pane) } cannot be null"); Pane.Clear(); } public void Print() { ThreadHelper.JoinableTaskFactory.Run(async () => { await PrintAsync(""); }); } public void Print(string value) { ThreadHelper.JoinableTaskFactory.Run(async () => { await PrintAsync(value); }); } public Task PrintAsync() { return PrintAsync(""); } public async Task PrintAsync(string value) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); if (Pane is IVsOutputWindowPaneNoPump noPumpPane) noPumpPane.OutputStringNoPump(value + Environment.NewLine); else ErrorHandler.ThrowOnFailure(Pane.OutputStringThreadSafe(value + Environment.NewLine)); } } }