/// <summary> /// The trace task event. /// </summary> /// <param name="type"> /// The type. /// </param> /// <param name="projectName"> /// The project name. /// </param> /// <param name="category"> /// The category. /// </param> /// <param name="taskMessage"> /// The task message. /// </param> /// <param name="file"> /// The file. /// </param> /// <param name="line"> /// The line. /// </param> /// <param name="outputMessage"> /// The output message. /// </param> private static void TraceTaskEvent(TraceEventType type, string projectName, string category, string taskMessage, string file, uint line, string outputMessage) { outputMessage = AppendNewLine(outputMessage); IVsOutputWindowPane outputPane = OutputPane; if (outputPane != null) { switch (type) { case TraceEventType.Error: ErrorHandler.ThrowOnFailure(outputPane.OutputTaskItemString(string.IsNullOrEmpty(outputMessage) ? " " : outputMessage, VSTASKPRIORITY.TP_HIGH, VSTASKCATEGORY.CAT_BUILDCOMPILE, projectName + (string.IsNullOrEmpty(category) ? string.Empty : (":" + category)), 1, string.IsNullOrEmpty(file) ? string.Empty : file, line, taskMessage)); break; case TraceEventType.Warning: ErrorHandler.ThrowOnFailure(outputPane.OutputTaskItemString(string.IsNullOrEmpty(outputMessage) ? " " : outputMessage, VSTASKPRIORITY.TP_NORMAL, VSTASKCATEGORY.CAT_BUILDCOMPILE, projectName + (string.IsNullOrEmpty(category) ? string.Empty : (":" + category)), 2, string.IsNullOrEmpty(file) ? string.Empty : file, line, taskMessage)); break; case TraceEventType.Information: ErrorHandler.ThrowOnFailure(outputPane.OutputTaskItemString(string.IsNullOrEmpty(outputMessage) ? " " : outputMessage, VSTASKPRIORITY.TP_LOW, VSTASKCATEGORY.CAT_USER, projectName + (string.IsNullOrEmpty(category) ? string.Empty : (":" + category)), 3, string.IsNullOrEmpty(file) ? string.Empty : file, line, taskMessage)); break; case TraceEventType.Verbose: OutputString(TraceEventType.Verbose, outputMessage); break; default: OutputString(TraceEventType.Information, outputMessage); break; } ErrorHandler.ThrowOnFailure(outputPane.FlushToTaskList()); Application.DoEvents(); } }
void BuildMain() { int fContinue = 1; foreach (IVsBuildStatusCallback cb in callbacks) { cb.BuildBegin(ref fContinue); if (fContinue == 0) { return; } } bool ok = false; try { ok = config.ProjectMgr.Build(this.options, this.config.Node, this.output, this.fCleanBuild); } catch (Exception e) { output.OutputStringThreadSafe("Unhandled Exception:" + e.Message + "\n"); } int fSuccess = ok? 1 : 0; foreach (IVsBuildStatusCallback cb in callbacks) { cb.BuildEnd(fSuccess); } output.FlushToTaskList(); }
private void Build(uint options, IVsOutputWindowPane output, string target) { if (!this.NotifyBuildBegin()) { return; } try { config.ProjectMgr.BuildAsync(options, this.config.ConfigName, output, target, (result, buildTarget) => this.NotifyBuildEnd(result, buildTarget)); } catch (Exception e) { if (e.IsCriticalException()) { throw; } Trace.WriteLine("Exception : " + e.Message); ErrorHandler.ThrowOnFailure(output.OutputStringThreadSafe("Unhandled Exception:" + e.Message + "\n")); this.NotifyBuildEnd(MSBuildResult.Failed, target); throw; } finally { ErrorHandler.ThrowOnFailure(output.FlushToTaskList()); } }
public void WriteLineAndTask(string lineText, string taskText, TaskType type, string fileName, uint lineNum) { ThreadHelper.JoinableTaskFactory.RunAsync(async() => { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); VSTASKPRIORITY priority = VSTASKPRIORITY.TP_NORMAL; var subCategory = ""; switch (type) { case TaskType.Error: priority = VSTASKPRIORITY.TP_HIGH; subCategory = "Error"; break; case TaskType.Warning: priority = VSTASKPRIORITY.TP_NORMAL; subCategory = "Warning"; break; } if (lineNum > 0) { lineNum--; } _pane.OutputTaskItemString(lineText + "\r\n", priority, VSTASKCATEGORY.CAT_BUILDCOMPILE, subCategory, (int)_vstaskbitmap.BMP_COMPILE, fileName, lineNum, taskText); _pane.FlushToTaskList(); }); }
/// <summary> /// Flush the content to a task list /// </summary> public void FlushToTaskList() { if (pane == null) { return; } int hr = pane.FlushToTaskList(); Marshal.ThrowExceptionForHR(hr); }
/// <summary> /// The output string line. /// </summary> /// <param name="type"> /// The type. /// </param> /// <param name="text"> /// The text. /// </param> private static void OutputStringLine(TraceEventType type, string text) { IVsOutputWindowPane outputPane = OutputPane; if (outputPane != null) { ErrorHandler.ThrowOnFailure(outputPane.OutputStringThreadSafe(text + "\n")); ErrorHandler.ThrowOnFailure(outputPane.FlushToTaskList()); Application.DoEvents(); } }
void BuildMain() { int fContinue = 1; foreach (IVsBuildStatusCallback cb in callbacks) { try { NativeMethods.ThrowOnFailure(cb.BuildBegin(ref fContinue)); if (fContinue == 0) { return; } } catch (Exception e) { Debug.Fail(String.Format("Exception was thrown during BuildBegin event\n{0}", e.Message)); } } bool ok = false; try { string target = null; if (this.fCleanBuild) { target = "Rebuild"; } else { target = "Build"; } ok = config.ProjectMgr.Build(this.options, this.config.ConfigName, this.output, target); } catch (Exception e) { NativeMethods.ThrowOnFailure(output.OutputStringThreadSafe("Unhandled Exception:" + e.Message + "\n")); } int fSuccess = ok ? 1 : 0; foreach (IVsBuildStatusCallback cb in callbacks) { try { NativeMethods.ThrowOnFailure(cb.BuildEnd(fSuccess)); } catch (Exception e) { Debug.Fail(String.Format("Exception was thrown during BuildEnd event\n{0}", e.Message)); } } NativeMethods.ThrowOnFailure(output.FlushToTaskList()); }
public int FlushToTaskList() { var result = target.FlushToTaskList(); if (ErrorHandler.Failed(result)) { throw new Win32Exception(result); } return(result); }
private void Build(uint options, IVsOutputWindowPane output, string target) { int shouldContinue = 1; foreach (IVsBuildStatusCallback cb in callbacks) { try { ErrorHandler.ThrowOnFailure(cb.BuildBegin(ref shouldContinue)); if (shouldContinue == 0) { return; } } catch (Exception e) { // If those who ask for status have bugs in their code it should not prevent the build/notification from happening Debug.Fail(String.Format("Exception was thrown during BuildBegin event\n{0}", e.Message)); } } MSBuildResult result = MSBuildResult.Failed; try { result = config.ProjectMgr.Build(options, this.config.ConfigName, output, target); } catch (Exception e) { Trace.WriteLine("Exception : " + e.Message); ErrorHandler.ThrowOnFailure(output.OutputStringThreadSafe("Unhandled Exception:" + e.Message + "\n")); throw e; } finally { int success = ((result == MSBuildResult.Sucessful) ? 1 : 0); foreach (IVsBuildStatusCallback cb in callbacks) { try { ErrorHandler.ThrowOnFailure(cb.BuildEnd(success)); } catch (Exception e) { // If those who ask for status have bugs in their code it should not prevent the build/notification from happening Debug.Fail(String.Format("Exception was thrown during BuildEnd event\n{0}", e.Message)); } } ErrorHandler.ThrowOnFailure(output.FlushToTaskList()); } }
/// <returns> /// The summary line for the build, which generally looks something like this: /// /// <code> /// ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== /// </code> /// </returns> private async Task <string> WaitForBuildToFinishAsync(IVsOutputWindowPane buildOutputWindowPane, CancellationToken cancellationToken) { await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); await KnownUIContexts.SolutionExistsAndNotBuildingAndNotDebuggingContext; // Force the error list to update ErrorHandler.ThrowOnFailure(buildOutputWindowPane.FlushToTaskList()); var textView = (IVsTextView)buildOutputWindowPane; var wpfTextViewHost = await textView.GetTextViewHostAsync(JoinableTaskFactory, cancellationToken); var lines = wpfTextViewHost.TextView.TextViewLines; if (lines.Count < 1) { return(string.Empty); } // The build summary line should be second to last in the output window return(lines[^ 2].Extent.GetText());
private void Build(uint options, IVsOutputWindowPane output, string target) { if (!this.config.ProjectMgr.HasPassedSecurityChecks) { // From a security perspective, if there was something truly malicious about the project, // the user is about to toast himself by requesting a build. Any further attempts at // preventing damage by avoiding MSBuild targets/tasks are futile. So, from this point // forward, we might as well pretend that this project has passed all security checks, // and we're free to run any targets we like. this.config.ProjectMgr.HasPassedSecurityChecks = true; } // We want to refresh the references if we are building with the Build or Rebuild target or if the project was opened for browsing only. bool shouldRepaintReferences = (target == null || target == MsBuildTarget.Build || target == MsBuildTarget.Rebuild || !this.config.ProjectMgr.HasPassedSecurityChecks); int shouldContinue = 1; foreach (IVsBuildStatusCallback cb in callbacks) { try { ErrorHandler.ThrowOnFailure(cb.BuildBegin(ref shouldContinue)); if (shouldContinue == 0) { return; } } catch (Exception e) { // If those who ask for status have bugs in their code it should not prevent the build/notification from happening Debug.Fail(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.BuildEventError, CultureInfo.CurrentUICulture), e.Message)); } } MSBuildResult result = MSBuildResult.Failed; try { result = config.ProjectMgr.Build(options, this.config.ConfigName, this.config.PlatformName, output, target); } catch (Exception e) { Trace.WriteLine("Exception : " + e.Message); ErrorHandler.ThrowOnFailure(output.OutputStringThreadSafe("Unhandled Exception:" + e.Message + "\n")); throw e; } finally { int success = ((result == MSBuildResult.Successful) ? 1 : 0); foreach (IVsBuildStatusCallback cb in callbacks) { try { ErrorHandler.ThrowOnFailure(cb.BuildEnd(success)); } catch (Exception e) { // If those who ask for status have bugs in their code it should not prevent the build/notification from happening Debug.Fail(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.BuildEventError, CultureInfo.CurrentUICulture), e.Message)); } } ErrorHandler.ThrowOnFailure(output.FlushToTaskList()); // Now repaint references if that is needed. // We hardly rely here on the fact the ResolveAssemblyReferences target has been run as part of the build. // One scenario to think at is when an assembly reference is renamed on disk thus becomming unresolvable, // but msbuild can actually resolve it. // Another one if the project was opened only for browsing and now the user chooses to build or rebuild. if (shouldRepaintReferences && (result == MSBuildResult.Successful)) { this.RefreshReferences(); } } }
private void Build(uint options, IVsOutputWindowPane output, string target) { int shouldContinue = 1; foreach (IVsBuildStatusCallback cb in callbacks) { try { ErrorHandler.ThrowOnFailure(cb.BuildBegin(ref shouldContinue)); if (shouldContinue == 0) return; } catch (Exception e) { // If those who ask for status have bugs in their code it should not prevent the build/notification from happening Debug.Fail(String.Format("Exception was thrown during BuildBegin event\n{0}", e.Message)); } } MSBuildResult result = MSBuildResult.Failed; try { result = config.ProjectMgr.Build(options, this.config.ConfigName, output, target); } catch (Exception e) { Trace.WriteLine("Exception : " + e.Message); ErrorHandler.ThrowOnFailure(output.OutputStringThreadSafe("Unhandled Exception:" + e.Message + "\n")); throw e; } finally { int success = ((result == MSBuildResult.Sucessful) ? 1 : 0); foreach (IVsBuildStatusCallback cb in callbacks) { try { ErrorHandler.ThrowOnFailure(cb.BuildEnd(success)); } catch (Exception e) { // If those who ask for status have bugs in their code it should not prevent the build/notification from happening Debug.Fail(String.Format("Exception was thrown during BuildEnd event\n{0}", e.Message)); } } ErrorHandler.ThrowOnFailure(output.FlushToTaskList()); } }
/* * Method: ShutdownLogger * * This is called when the build complete. * */ private void ShutdownLogger() { // If there was any error/warnings, send them to the task list NativeMethods.ThrowOnFailure(_output.FlushToTaskList()); }
public virtual bool ObsoleteBuild(uint vsopts, string config, IVsOutputWindowPane output, bool fCleanBuild) { if (fCleanBuild) { // we are done return true; } lock (Project.BuildLock) { ProjectOptions options = this.GetProjectOptions(config); CompilerResults results; ArrayList files = new ArrayList(); /*UNDONE: need to get this to use MSBuild foreach (XmlElement e in doc.SelectNodes("//Files/Include/File")) { //TODO: Support other "BuildActions" like "EmbeddedResource"... if (e.GetAttribute("BuildAction") == "Compile") { string rel = e.GetAttribute("RelPath"); Url url = new Url(new Url(doc.BaseURI), rel); files.Add(url.AbsoluteUrl); } } */ try { ICodeCompiler compiler = this.GetCompiler(); if (files.Count == 1) { string filename = (string)files[0]; results = compiler.CompileAssemblyFromFile(options, filename); } else { string[] fileNames = (string[])files.ToArray(typeof(string)); results = compiler.CompileAssemblyFromFileBatch(options, fileNames); } } catch (Exception e) { results = new CompilerResults(options.TempFiles); results.Errors.Add(new CompilerError(options.OutputAssembly, 1, 1, "", "Internal Compiler Error: " + e.ToString() + "\n")); results.NativeCompilerReturnValue = 1; } taskProvider.Tasks.Clear(); int errorCount = 0; int warningCount = 0; foreach (CompilerError e in results.Errors) { if (e.IsWarning) warningCount++; else errorCount++; NativeMethods.ThrowOnFailure(output.OutputTaskItemString(GetFormattedErrorMessage(e, false) + "\n", VSTASKPRIORITY.TP_HIGH, VSTASKCATEGORY.CAT_BUILDCOMPILE, "", -1, e.FileName, (uint)e.Line - 1, e.ErrorText)); } NativeMethods.ThrowOnFailure(output.OutputStringThreadSafe("Build complete -- " + errorCount + " errors, " + warningCount + " warnings")); //TODO: globalize NativeMethods.ThrowOnFailure(output.FlushToTaskList()); return results.NativeCompilerReturnValue == 0; } }
private void Build(uint options, IVsOutputWindowPane output, string target) { bool shouldRepaintReferences = false; if (!this.config.ProjectMgr.HasPassedSecurityChecks) { // From a security perspective, if there was something truly malicious about the project, // the user is about to toast himself by requesting a build. Any further attempts at // preventing damage by avoiding MSBuild targets/tasks are futile. So, from this point // forward, we might as well pretend that this project has passed all security checks, // and we're free to run any targets we like. this.config.ProjectMgr.HasPassedSecurityChecks = true; shouldRepaintReferences = true; } int shouldContinue = 1; foreach (IVsBuildStatusCallback cb in callbacks) { try { ErrorHandler.ThrowOnFailure(cb.BuildBegin(ref shouldContinue)); if (shouldContinue == 0) { return; } } catch (Exception e) { // If those who ask for status have bugs in their code it should not prevent the build/notification from happening Debug.Fail(String.Format("Exception was thrown during BuildBegin event\n{0}", e.Message)); } } MSBuildResult result = MSBuildResult.Failed; try { result = config.ProjectMgr.Build(options, this.config.ConfigName, output, target); } catch (Exception e) { Trace.WriteLine("Exception : " + e.Message); ErrorHandler.ThrowOnFailure(output.OutputStringThreadSafe("Unhandled Exception:" + e.Message + "\n")); throw e; } finally { int success = ((result == MSBuildResult.Sucessful) ? 1 : 0); foreach (IVsBuildStatusCallback cb in callbacks) { try { ErrorHandler.ThrowOnFailure(cb.BuildEnd(success)); } catch (Exception e) { // If those who ask for status have bugs in their code it should not prevent the build/notification from happening Debug.Fail(String.Format("Exception was thrown during BuildEnd event\n{0}", e.Message)); } } ErrorHandler.ThrowOnFailure(output.FlushToTaskList()); // Now repaint references if that is needed. // We hardly rely here on the fact the ResolveAssemblyReferences target has been run as part of the build. if (shouldRepaintReferences) { // Repaint references IReferenceContainer referenceContainer = this.config.ProjectMgr.GetReferenceContainer(); foreach (ReferenceNode node in referenceContainer.EnumReferences()) { node.RefreshReference(); } } } }
private void Build(uint options, IVsOutputWindowPane output, string target) { if (!this.config.ProjectMgr.HasPassedSecurityChecks) { // From a security perspective, if there was something truly malicious about the project, // the user is about to toast himself by requesting a build. Any further attempts at // preventing damage by avoiding MSBuild targets/tasks are futile. So, from this point // forward, we might as well pretend that this project has passed all security checks, // and we're free to run any targets we like. this.config.ProjectMgr.HasPassedSecurityChecks = true; } // We want to refresh the references if we are building with the Build or Rebuild target or if the project was opened for browsing only. bool shouldRepaintReferences = (target == null || target == MsBuildTarget.Build || target == MsBuildTarget.Rebuild || !this.config.ProjectMgr.HasPassedSecurityChecks); int shouldContinue = 1; foreach (IVsBuildStatusCallback cb in callbacks) { try { ErrorHandler.ThrowOnFailure(cb.BuildBegin(ref shouldContinue)); if (shouldContinue == 0) return; } catch (Exception e) { // If those who ask for status have bugs in their code it should not prevent the build/notification from happening Debug.Fail(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.BuildEventError, CultureInfo.CurrentUICulture), e.Message)); } } MSBuildResult result = MSBuildResult.Failed; try { result = config.ProjectMgr.Build(options, this.config.ConfigName, output, target); } catch (Exception e) { Trace.WriteLine("Exception : " + e.Message); ErrorHandler.ThrowOnFailure(output.OutputStringThreadSafe("Unhandled Exception:" + e.Message + "\n")); throw e; } finally { int success = ((result == MSBuildResult.Successful) ? 1 : 0); foreach (IVsBuildStatusCallback cb in callbacks) { try { ErrorHandler.ThrowOnFailure(cb.BuildEnd(success)); } catch (Exception e) { // If those who ask for status have bugs in their code it should not prevent the build/notification from happening Debug.Fail(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.BuildEventError, CultureInfo.CurrentUICulture), e.Message)); } } ErrorHandler.ThrowOnFailure(output.FlushToTaskList()); // Now repaint references if that is needed. // We hardly rely here on the fact the ResolveAssemblyReferences target has been run as part of the build. // One scenario to think at is when an assembly reference is renamed on disk thus becomming unresolvable, // but msbuild can actually resolve it. // Another one if the project was opened only for browsing and now the user chooses to build or rebuild. if (shouldRepaintReferences && (result == MSBuildResult.Successful)) { this.RefreshReferences(); } } }
internal static void WriteToPane(string message) { VerificationOutputpane.OutputString(message + "\n"); VerificationOutputpane.FlushToTaskList(); }
////////////////////////////////////////////////////////////////////////////////////////////////// // This is called from the compiler background thread. // fCleanBuild is not part of the vsopts, but passed down as the callpath is differently // ////////////////////////////////////////////////////////////////////////////////////////////////// /// <include file='doc\Project.uex' path='docs/doc[@for="Project.Build"]/*' /> public virtual bool Build(uint vsopts, XmlElement config, IVsOutputWindowPane output, bool fCleanBuild){ if (fCleanBuild){ // we are done return true; } lock (Project.BuildLock){ #if LookForMemoryLeaks System.GC.Collect(); System.GC.WaitForPendingFinalizers(); System.GC.Collect(); System.GC.WaitForPendingFinalizers(); long usedMemoryBeforeBuild = System.GC.GetTotalMemory(true); #endif int errorCount = 0; int warningCount = 0; CompilerResults results = this.CompileProject(config); #if WHIDBEY if (this.taskManager != null && this.taskManagerBuild != null) { taskManager.ClearTasksOnProject(this.Caption); taskManagerBuild.ClearTasksOnProject(this.Caption); bool runVerifierBuildOnly = this.GetBoolAttr(config, "RunProgramVerifier") && !this.GetBoolAttr(config, "RunProgramVerifierWhileEditing"); string verifierCode = ((int)System.Compiler.Error.GenericWarning).ToString("0000"); foreach (CompilerError e in results.Errors) { if (e.IsWarning) warningCount++; else errorCount++; // output.OutputTaskItemString(GetFormattedErrorMessage(e, false) + "\n", VSTASKPRIORITY.TP_HIGH, VSTASKCATEGORY.CAT_BUILDCOMPILE, "", -1, e.FileName, (uint)e.Line - 1, e.ErrorText); int endLine; int endColumn; if (e is System.Compiler.CompilerErrorEx) { System.Compiler.CompilerErrorEx errorEx = (System.Compiler.CompilerErrorEx)e; endLine = errorEx.EndLine; endColumn = errorEx.EndColumn; } else { endLine = e.Line; endColumn = e.Column + 1; } bool isBuildOnly = runVerifierBuildOnly && e.ErrorNumber == verifierCode; (isBuildOnly ? taskManagerBuild : taskManager).AddTask(e.ErrorText, null, e.ErrorNumber, "CS" + e.ErrorNumber, TaskPriority.Normal, (e.IsWarning ? TaskCategory.Warning : TaskCategory.Error), (isBuildOnly ? TaskMarker.Error : (e.IsWarning ? TaskMarker.Warning : TaskMarker.CodeSense)), TaskOutputPane.Build, this.Caption, e.FileName, e.Line, e.Column, endLine, endColumn, null); } taskManager.OutputString("Build complete -- " + errorCount + " errors, " + warningCount + " warnings\n", TaskOutputPane.Build); taskManager.Refresh(); taskManagerBuild.Refresh(); } else { #endif this.taskProvider.ClearErrors(); foreach (CompilerError e in results.Errors) { if (e.IsWarning) warningCount++; else errorCount++; output.OutputTaskItemString(GetFormattedErrorMessage(e, false) + "\n", VSTASKPRIORITY.TP_HIGH, VSTASKCATEGORY.CAT_BUILDCOMPILE, "", -1, e.FileName, (uint)e.Line - 1, e.ErrorText); } output.OutputStringThreadSafe("Build complete -- " + errorCount + " errors, " + warningCount + " warnings\n"); //TODO: globalize output.FlushToTaskList(); #if WHIDBEY } #endif bool success = results.NativeCompilerReturnValue == 0; #if LookForMemoryLeaks results = null; System.GC.Collect(); System.GC.WaitForPendingFinalizers(); System.GC.Collect(); System.GC.WaitForPendingFinalizers(); long usedMemoryAfterBuild = System.GC.GetTotalMemory(true); output.OutputStringThreadSafe("Build leaked "+(usedMemoryAfterBuild-usedMemoryBeforeBuild)+" bytes"); #endif return success; } }
private void BuildCoda(BuildResult result, IVsOutputWindowPane output, bool shouldRepaintReferences) { try { // Now repaint references if that is needed. // We hardly rely here on the fact the ResolveAssemblyReferences target has been run as part of the build. // One scenario to think at is when an assembly reference is renamed on disk thus becomming unresolvable, // but msbuild can actually resolve it. // Another one if the project was opened only for browsing and now the user chooses to build or rebuild. if (shouldRepaintReferences && (result.IsSuccessful)) { this.RefreshReferences(result); } } finally { try { ErrorHandler.ThrowOnFailure(output.FlushToTaskList()); } finally { NotifyBuildEnd(result.IsSuccessful); } } }
/// <summary> /// This function is the callback used to execute the command when the menu item is clicked. /// See the constructor to see how the menu item is associated with this function using /// OleMenuCommandService service and MenuCommand class. /// </summary> /// <param name="sender">Event sender.</param> /// <param name="e">Event args.</param> private void Execute(object sender, EventArgs e) { ThreadHelper.ThrowIfNotOnUIThread(); // Get current opened file DTE2 dte2 = Package.GetGlobalService(typeof(DTE)) as DTE2; Document document = dte2.ActiveDocument; // Return, if no documents opened if (document == null) { return; } document.Save(); // Run Validator utility string xmlErrors = ""; bool validationOK = RunValidator(document.FullName, ref xmlErrors); // Output results IVsOutputWindowPane windowPane = (IVsOutputWindowPane)Package.GetGlobalService(typeof(SVsGeneralOutputWindowPane)); if (null != windowPane) { windowPane.Clear(); if (validationOK) { // Output "completed OK" banner windowPane.OutputString(xmlErrors); windowPane.OutputString("========== Gen<i>Cam Validation completed OK ========== \n"); windowPane.Activate(); } else { // Output errors to "Error List" pane string[] xmlErrorsArray = xmlErrors.Split('\n'); int errNum = xmlErrorsArray.GetLength(0) - 1; for (int i = 0; i < errNum; ++i) { // Parse error string to extract the error line number string strTmp = xmlErrorsArray[i]; strTmp = strTmp.Replace(document.FullName, ""); strTmp = strTmp.TrimPrefix("("); strTmp = strTmp.Remove(strTmp.IndexOf(")")); uint nLine = UInt32.Parse(strTmp) - 1; // Output the error info windowPane.OutputTaskItemString(xmlErrorsArray[i], VSTASKPRIORITY.TP_HIGH, VSTASKCATEGORY.CAT_BUILDCOMPILE, "Error", (int)Microsoft.VisualStudio.Shell.Interop._vstaskbitmap.BMP_COMPILE, document.FullName, nLine, xmlErrorsArray[i]); } // Output "FAILED" banner windowPane.OutputString("========== Gen<i>Cam Validation FAILED ========== \n"); windowPane.FlushToTaskList(); } } else { // We have no IVsOutputWindowPane, just show message box VsShellUtilities.ShowMessageBox( this.package, validationOK ? "Gen<i>Cam valication OK": "Gen<i>Cam valication FAILED", "Gen<i>Cam valication", validationOK ? OLEMSGICON.OLEMSGICON_INFO : OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); } }