Esempio n. 1
0
        private void OnDocumentSaved(EnvDTE.Document dteDocument)
        {
            var documentIds = this.workspace.CurrentSolution.GetDocumentIdsWithFilePath(
                dteDocument.FullName);

            if (documentIds != null && documentIds.Length == 1)
            {
                var documentId = documentIds[0];
                var document   = this.workspace.CurrentSolution.GetDocument(documentId);

                if (Path.GetExtension(document.FilePath) == ".cs")
                {
                    SyntaxNode root = null;

                    if (document.TryGetSyntaxRoot(out root))
                    {
                        var newRoot = root.RemoveComments();

                        if (newRoot != root)
                        {
                            var newSolution = document.Project.Solution
                                              .WithDocumentSyntaxRoot(document.Id, newRoot);
                            this.workspace.TryApplyChanges(newSolution);
                            dteDocument.Save();
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Find corresponding file and open it
        ///
        /// First, get the list of possible file endings
        /// Then, look in same folder
        /// Then, look in project folder and use the first match
        /// </summary>
        public static void SwitchToRelated(EnvDTE.Document document)
        {
            AutoUpdate.OnFeatureUsed();

            // This should never occur, but let's make sure it doesn't crash
            if (document == null)
            {
                return;
            }

            string path     = document.Path;
            string name     = document.Name;
            string ext      = GetExtensionExt(name);
            string name_new = null;

            List <string> list;

            // If the following fails, we don't know what we're looking for
            // There is (surprisingly!) no entry in the dictionary for that ending
            if (!Dict.TryGetValue(ext, out list))
            {
                return;
            }

            // First, look in the same folder and try all the endings we have
            foreach (string ext_new in list)
            {
                name_new = ChangeExtensionExt(name, ext_new);

                if (File.Exists(path + name_new))
                {
                    document.DTE.ItemOperations.OpenFile(path + name_new, Constants.vsViewKindAny);
                    return;
                }
            }

            Project prj = document.ProjectItem.ContainingProject;

            // If the file does not belong to a project, we don't know where to look
            if (prj == null)
            {
                return;
            }

            // Then, look in project folder and use the first match
            foreach (string ext_new in list)
            {
                name_new = Path.ChangeExtension(name, ext_new);

                foreach (ProjectItem projectItem in prj.ProjectItems)
                {
                    ProjectItem found = FindProjectItemByName(projectItem, name_new);
                    if (found != null)
                    {
                        found.Open(Constants.vsViewKindCode);
                        return;
                    }
                }
            }
        }
        public static string GetNameSpace(EnvDTE.Document Document)
        {
            var project = Document.ProjectItem.ContainingProject;

            return(Path.Combine(project.Name) + "." +
                   string.Join(".", Path.GetDirectoryName(Document.ProjectItem.FileNames[0]).Substring(Path.GetDirectoryName(project.FullName).Length).Split(Path.DirectorySeparatorChar)).Trim('.'));
        }
Esempio n. 4
0
        private void OnDocumentSaved(EnvDTE.Document doc)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            try
            {
                var filename = doc.Name;

                var filepath = GetConfigfilePath(doc.Path); // Find configuration file path
                if (filepath.Length > 0)
                {
                    var configList = LoadJson(filepath); // Get content of configuration path

                    if (configList.items.Length > 0)
                    {
                        foreach (var config in configList.items)
                        {
                            if (doc.Name.ToLower().Contains("." + config.ext) || config.ext.Equals("*"))
                            {
                                //run "powershell Set-ExecutionPolicy RemoteSigned" in x86 and x64 powershell
                                PowerShell.Create().AddCommand(config.command).Invoke();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                GetLogger().LogInformation(GetPackageName(), ex.Message);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// This event will run when any file is saved
        /// </summary>
        /// <param name="document">Saved document</param>
        private void DocumentEvents_DocumentSaved(EnvDTE.Document document)
        {
            // If this is a file we should use for replacement, let's use it
            if (regex.Match(document.Name).Success)
            {
                var    groups = regex.Split(document.Name);
                string activeConfiguration = document.ProjectItem.ContainingProject.ConfigurationManager.ActiveConfiguration.ConfigurationName;
                string name       = groups[1];
                string configName = groups[2];
                string extension  = groups[3];

                // Check if we should exclude the file
                if (!filesToExclude.Any(f => f.Equals(name + "." + extension, StringComparison.InvariantCultureIgnoreCase)))
                {
                    // Only copy the file if it matches the current active configuration (the match is case insensitive)
                    if (configName.Equals(activeConfiguration, StringComparison.InvariantCultureIgnoreCase))
                    {
                        string sourceFile = document.FullName;
                        string destFile   = Path.Combine(Path.GetDirectoryName(document.FullName), name + "." + extension);

                        // Replace the file
                        ReplaceFile(sourceFile, destFile, document.ProjectItem.ContainingProject);
                    }
                }
            }
        }
        private void ExtractSelectionAndIncludes(EnvDTE.Document document, TrialAndErrorRemovalOptionsPage settings,
                                                 out ITextBuffer textBuffer, out Formatter.IncludeLineInfo[] includeLinesArray)
        {
            // Parsing.
            document.Activate();
            var documentTextView = VSUtils.GetCurrentTextViewHost();

            textBuffer = documentTextView.TextView.TextBuffer;
            string documentText = documentTextView.TextView.TextSnapshot.GetText();
            IEnumerable <Formatter.IncludeLineInfo> includeLines = Formatter.IncludeLineInfo.ParseIncludes(documentText, Formatter.ParseOptions.IgnoreIncludesInPreprocessorConditionals | Formatter.ParseOptions.KeepOnlyValidIncludes);

            // Optionally skip top most include.
            if (settings.IgnoreFirstInclude)
            {
                includeLines = includeLines.Skip(1);
            }

            // Skip everything with preserve flag.
            includeLines = includeLines.Where(x => !x.ShouldBePreserved);

            // Apply filter ignore regex.
            {
                string   documentName    = Path.GetFileNameWithoutExtension(document.FullName);
                string[] ignoreRegexList = RegexUtils.FixupRegexes(settings.IgnoreList, documentName);
                includeLines = includeLines.Where(line => !ignoreRegexList.Any(regexPattern =>
                                                                               new System.Text.RegularExpressions.Regex(regexPattern).Match(line.IncludeContent).Success));
            }
            // Reverse order if necessary.
            if (settings.RemovalOrder == TrialAndErrorRemovalOptionsPage.IncludeRemovalOrder.BottomToTop)
            {
                includeLines = includeLines.Reverse();
            }

            includeLinesArray = includeLines.ToArray();
        }
Esempio n. 7
0
        public async Task <bool> PerformTrialAndErrorIncludeRemoval(EnvDTE.Document document, TrialAndErrorRemovalOptionsPage settings)
        {
            if (document == null)
            {
                return(false);
            }

            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            var canCompile = await VSUtils.VCUtils.IsCompilableFile(document);

            if (canCompile.Result == false)
            {
                Output.Instance.WriteLine($"Can't compile file '{canCompile.Reason}': {document.Name}");
                return(false);
            }

            if (WorkInProgress)
            {
                _ = Output.Instance.ErrorMsg("Trial and error include removal already in progress!");
                return(false);
            }
            WorkInProgress = true;

            // Start wait dialog.
            IVsThreadedWaitDialog2 progressDialog = await StartProgressDialog(document.Name);

            if (progressDialog == null)
            {
                return(false);
            }

            // Extract all includes.
            ITextBuffer textBuffer;

            Formatter.IncludeLineInfo[] includeLines;
            try
            {
                ExtractSelectionAndIncludes(document, settings, out textBuffer, out includeLines);
            }
            catch (Exception ex)
            {
                Output.Instance.WriteLine("Unexpected error while extracting include selection: {0}", ex);
                progressDialog.EndWaitDialog();
                return(false);
            }

            // Hook into build events.
            SubscribeBuildEvents();

            // The rest runs in a separate thread since the compile function is non blocking and we want to use BuildEvents
            // We are not using Task, since we want to make use of WaitHandles - using this together with Task is a bit more complicated to get right.
            outputWaitEvent.Reset();
            var removalThread = new System.Threading.Thread(() => TrialAndErrorRemovalThreadFunc(document, settings, includeLines, progressDialog, textBuffer));

            removalThread.Start();
            return(true);
        }
Esempio n. 8
0
        public static IEnumerable <(string line, int index)> GetLines(this EnvDTE.Document document)
        {
            TextDocument textDoc = (TextDocument)document.Object("TextDocument");

            if (textDoc == null)
            {
                return(Enumerable.Empty <(string line, int index)>());
            }
            return(textDoc.GetLines());
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="d"></param>
 /// <param name="text"></param>
 public static void InsertTextIntoActiveDocument(EnvDTE.Document d, string text)
 {
     if ((!String.IsNullOrEmpty(text)) && (!String.IsNullOrEmpty(text.Trim())))
     {
         EnvDTE.TextSelection SelectedText = d.Selection as EnvDTE.TextSelection;
         EnvDTE.EditPoint     TopPoint     = SelectedText.TopPoint.CreateEditPoint();
         TopPoint.LineUp(1);
         TopPoint.EndOfLine();
         TopPoint.Insert(text);
     }
 }
Esempio n. 10
0
        public static Language GetLanguage(VS.Document doc)
        {
            Language result = Language.Unknown;

            if (doc != null)
            {
                result = GetLanguage(doc.Language, doc.FullName);
            }

            return(result);
        }
Esempio n. 11
0
        /// <summary>
        /// See if there is a related file we can switch to
        ///
        /// We are happy if the file has a supported ending
        /// There's no check whether there are any related files we can switch to or not
        /// </summary>
        public static bool SwitchPossible(EnvDTE.Document document)
        {
            // We need an open file to be able to switch
            if (document == null)
            {
                return(false);
            }

            string ext = GetExtensionExt(document.Name);

            return(Dict.ContainsKey(ext));
        }
Esempio n. 12
0
        private static bool IsLanguageSupported(EnvDTE.Document document)
        {
            if (document == null)
            {
                return(false);
            }

            if ((document.Language != "CSharp") && (document.Language != "Basic"))
            {
                return(false);
            }

            return(true);
        }
        private void DocumentSaved(EnvDTE.Document document)
        {
            //DafnyLanguage.ProgressTagger tagger;
            //IWpfTextView textView = GetWpfTextView(document.FullName);
            //if (textView != null && DafnyLanguage.ProgressTagger.ProgressTaggers.TryGetValue(textView.TextBuffer, out tagger))
            //{
            //    MenuProxy.Output("restart verifier on file save: " + document.FullName + "\n");
            //    // stop the old verification
            //    tagger.StopVerification();

            //    // start a new one.
            //    tagger.StartVerification(false);
            //}
        }
Esempio n. 14
0
        public bool ToggleAllRegions(EnvDTE.Document doc, bool closeAll)
        {
            bool          open = false;
            TextSelection ts   = (TextSelection)doc.Selection;

            string startpattern;
            string endpattern;

            if (!this.GetPatterns(doc, out startpattern, out endpattern))
            {
                return(false);
            }
            ts.EndOfDocument(false);
            EditPoint ep = ts.ActivePoint.CreateEditPoint();
            string    line;

            while (!ep.AtStartOfDocument)
            {
                ts.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false);
                ts.LineUp(true, 1);
                line = ts.Text.ToLower().Trim();
                if (line.StartsWith(endpattern))
                {
                    open = true;
                }
                else if (line.StartsWith(startpattern))
                {
                    if (closeAll)
                    {
                        if (open)
                        {
                            doc.DTE.ExecuteCommand("Edit.ToggleOutliningExpansion", "");
                        }
                    }
                    else
                    {
                        if (!open)
                        {
                            doc.DTE.ExecuteCommand("Edit.ToggleOutliningExpansion", "");
                        }
                    }
                    open = false;
                }
                ep = ts.ActivePoint.CreateEditPoint();
            }
            toogleRegionDocument = doc;
            ts.Cancel();
            return(true);
        }
Esempio n. 15
0
        public static Language GetLanguage(VS.Document doc)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            Language result = Language.Unknown;

            if (doc != null)
            {
                result = GetLanguage(doc.Language, doc.FullName);

                // I'd like to get the "current" (based on the caret position) ITextBuffer's ContentType.
                // That would allow for better Language decisions in multi-language files like .razor,
                // which allows C#, HTML, and CSS. But I can't figure out a way to get the current
                // caret position's ITextBuffer. This started from https://stackoverflow.com/a/7373385/1882616.
                if ((result == Language.Unknown || result == Language.PlainText) &&
                    doc.DTE is Microsoft.VisualStudio.OLE.Interop.IServiceProvider oleServiceProvider &&
                    !string.IsNullOrEmpty(doc.FullName))
                {
                    using (var serviceProvider = new ServiceProvider(oleServiceProvider))
                    {
                        if (VsShellUtilities.IsDocumentOpen(
                                serviceProvider,
                                doc.FullName,
                                Guid.Empty,
                                out _,
                                out _,
                                out IVsWindowFrame windowFrame))
                        {
                            IVsTextView view = VsShellUtilities.GetTextView(windowFrame);
                            if (view.GetBuffer(out IVsTextLines lines) == VSConstants.S_OK && lines is IVsTextBuffer vsBuffer)
                            {
                                IComponentModel componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
                                IVsEditorAdaptersFactoryService adapterFactory = componentModel.GetService <IVsEditorAdaptersFactoryService>();
                                ITextBuffer buffer          = adapterFactory.GetDataBuffer(vsBuffer);
                                string      contentType     = buffer?.ContentType?.TypeName;
                                Language    contentLanguage = GetLanguage(contentType, doc.FullName);
                                if (contentLanguage != Language.Unknown)
                                {
                                    result = contentLanguage;
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }
Esempio n. 16
0
        private void DocumentEventsOnDocumentClosing(EnvDTE.Document document)
        {
            if (SolutionState == SolutionStates.Opened)
            {
                var doc = new ClosedDocument()
                {
                    FullName = document.FullName,
                    Name     = document.Name,
                    Kind     = document.Kind,
                    Language = document.Language,
                    ClosedAt = DateTime.Now,
                };

                _documentHistoryManager.Add(doc);
            }
        }
Esempio n. 17
0
        private void DocumentEventsOnDocumentSaved(Document document)
        {
            if (!document.Name.EndsWith(".cs", StringComparison.InvariantCultureIgnoreCase))
            {
                return;
            }
            var source = File.ReadAllText(document.FullName);

            if (!source.StartsWith("//CONTEST_TOOL_SUBMIT:"))
            {
                return;
            }
            document.DTE.StatusBar.Text = "Generating file to submit...";
            int p = source.IndexOf(Environment.NewLine);

            if (p == -1)
            {
                return;
            }
            var submitFileName = source.Substring(22, p - 22);

            source = source.Substring(p + 1);               // stripping hint file name

            source = MakeAllReplacements(source, submitFileName);

            lock ( Sync )
            {
                if (_compilation != null)
                {
                    source = _codeImporter.ImportCode(source);
                }

                var errorFile = Path.Combine(Path.GetDirectoryName(submitFileName), "compilationLog.txt");
                var errors    = _codeImporter.Validate(source);
                if (errors.Any())
                {
                    File.WriteAllText(errorFile, string.Join(Environment.NewLine, errors.ToArray()));

                    document.DTE.StatusBar.Text = "COMPILATION ERROR !!!";
                }
                else
                {
                    File.Delete(errorFile);
                }
            }
            File.WriteAllText(submitFileName, source);
        }
Esempio n. 18
0
 public int OnBeforeSave(uint docCookie)
 {
     if (_pkg.RemoveOnSave())
     {
         RunningDocumentInfo runningDocumentInfo = new RunningDocumentInfo(_pkg.rdt, docCookie);
         EnvDTE.Document     document            = _pkg.dte.Documents.OfType <EnvDTE.Document>().SingleOrDefault(x => x.FullName == runningDocumentInfo.Moniker);
         if (document == null)
         {
             return(VSConstants.S_OK);
         }
         if (document.Object("TextDocument") is TextDocument textDoc)
         {
             _pkg.RemoveTrailingWhiteSpaces(textDoc);
         }
     }
     return(VSConstants.S_OK);
 }
        /// <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();

            EnvDTE.Document doc = this.Dte.ActiveDocument;
            if (doc == null)
            {
                return;
            }
            dynamic textSelection = doc.Selection;

            if (textSelection == null)
            {
                return;
            }
            textSelection.Insert("ˉ");
        }
Esempio n. 20
0
 public int OnBeforeSave(uint docCookie)
 {
     if (_pkg.removeOnSave())
     {
         RunningDocumentInfo runningDocumentInfo = _pkg.rdt.GetDocumentInfo(docCookie);
         EnvDTE.Document     document            = _pkg.dte.Documents.OfType <EnvDTE.Document>().SingleOrDefault(x => x.FullName == runningDocumentInfo.Moniker);
         if (document == null)
         {
             return(VSConstants.S_OK);
         }
         var textDoc = document.Object("TextDocument") as TextDocument;
         if (textDoc != null)
         {
             RemoveTrailingWhitespacesPackage.removeTrailingWhiteSpaces(textDoc);
         }
     }
     return(VSConstants.S_OK);
 }
Esempio n. 21
0
 // После закрытия aspx файла исключим автосгенерированный исходник из списка компиляции проекта
 void OnDocumentClosing(EnvDTE.Document document)
 {
     if (Location.GetFileIndex(document.FullName) == Location.GetFileIndex(_filePath))
     {
         try
         {
             if (_windowManager != null)
             {
                 // RemoveAdornments вызывает уничтожение (close и dispose) view filter и source, связанных с _windowManager
                 _windowManager.RemoveAdornments();
             }
         }
         finally
         {
             _windowManager = null;
             _documentEvents.DocumentClosing -= _documentClosingEventHandler;
         }
     }
 }
        public EnvDTE.Document GetOpenedDocumentInCodeWindow(Func <string, bool> checkerFunction)
        {
            EnvDTE.Document result = null;

            if (ApplicationObject.ActiveWindow != null &&
                ApplicationObject.ActiveWindow.Type == vsWindowType.vsWindowTypeDocument &&
                ApplicationObject.ActiveWindow.Document != null
                )
            {
                string path = ApplicationObject.ActiveWindow.Document.FullName;

                if (checkerFunction(path))
                {
                    result = ApplicationObject.ActiveWindow.Document;
                }
            }

            return(result);
        }
Esempio n. 23
0
        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            EnvDTE80.DTE2   oApplication = (EnvDTE80.DTE2)GetService(typeof(EnvDTE.DTE));
            EnvDTE.Document oActive      = oApplication.ActiveDocument;

            if (oActive != null)
            {
                string        szExt      = Path.GetExtension(oActive.FullName);
                TextSelection oSelection = ( TextSelection )oActive.Selection;

                Color2CodeMap oMap = OptionPage.Color2CodeList.Find(oItem => oItem.Extensions.ToLower( ).Split(';').Any(szString => szString.Equals(szExt.ToLower( ))));

                if (oMap != null)
                {
                    oSelection.Text = EvaluateTemplate(oMap.Template, (( SolidColorBrush )(( Button )sender).Background).Color);
                }

                oActive.Activate( );
            }
        }
        private TextSelection GetTextSelection()
        {
            try
            {
                EnvDTE.Document objDocument = this.dteProvider.Dte.ActiveDocument;
                if (objDocument == null)
                {
                    ShowMessageBox("GetTextSelection()", "ActiveDocument not found. Are you in a code editor window ?");
                    return(null);
                }

                EnvDTE.TextDocument  objTextDocument  = (EnvDTE.TextDocument)objDocument.Object("TextDocument");
                EnvDTE.TextSelection objTextSelection = objTextDocument.Selection;
                return(objTextSelection);
            }
            catch (Exception ex)
            {
                ShowMessageBox("GetTextSelection()", ex.Message);
            }
            return(null);
        }
Esempio n. 25
0
        //preview on MouseUp
        public void PreviewResultDoc(object src, EventArgs args)
        {
            ResultItem   resultLine = dictResultItems[(TreeViewItem)src];
            FindSettings settings   = dictSearchSettings[(TreeViewItem)src];
            RichTextBox  tbPreview  = dictTBPreview[settings];

            tbPreview.Document.Blocks.Clear();

            EnvDTE.Document document = GetDocumentByPath(resultLine.linePath);
            //It document exists in VS memory
            if (document != null)
            {
                EnvDTE.TextSelection selection = GetSelection(document);
                FillPreviewFromDocument(tbPreview.Document.Blocks, selection, resultLine);
                SelectOffsetLength(selection, resultLine);
            }
            else
            {
                FillPreviewFromFile(tbPreview.Document.Blocks, resultLine);
            }
        }
        private static string GetTypeFullName(EnvDTE.Document document)
        {
            if (document == null)
            {
                return(string.Empty);
            }

            string fileType = string.Empty;

            VSProject2 proj = document?.ProjectItem?.ContainingProject?.Object as VSProject2;

            if (proj != null)
            {
                fileType = CSharpCodeHelper.GetFileTypeFullName(document.FullName, proj);
            }

            if (string.IsNullOrEmpty(fileType))
            {
                fileType = Path.GetFileNameWithoutExtension(document.FullName).Split('.').FirstOrDefault();
            }

            return(fileType);
        }
Esempio n. 27
0
        public void PerformCompileUnityFile(EnvDTE.Document document)
        {
            if (document == null)
            {
                return;
            }

            string errorMessage;
            bool   isHeader;
            var    fileConfig = GetFileConfig(document, out errorMessage, out isHeader);

            if (fileConfig == null)
            {
                Output.Instance.WriteLine(errorMessage);
                return;
            }
            if (isHeader)
            {
                return;
            }

            PerformCompileUnityFile(document, fileConfig);
        }
Esempio n. 28
0
        private void OnDocumentSaved(Document dteDocument)
        {
            var documentIds = _workspace.CurrentSolution.GetDocumentIdsWithFilePath(dteDocument.FullName);

            if (documentIds == null || documentIds.Length != 1)
            {
                return;
            }

            var documentId = documentIds[0];
            var document   = _workspace.CurrentSolution.GetDocument(documentId);

            if (Path.GetExtension(document.FilePath) != ".cs")
            {
                return;
            }

            SyntaxNode root;

            if (!document.TryGetSyntaxRoot(out root))
            {
                return;
            }

            var newRoot = root.RemoveComments();

            if (newRoot == root)
            {
                return;
            }

            var newSolution = document.Project.Solution.WithDocumentSyntaxRoot(document.Id, newRoot);

            _workspace.TryApplyChanges(newSolution);
            dteDocument.Save();
        }
        private void OnTrialAndErrorRemovalDone(IVsThreadedWaitDialog2 progressDialog, EnvDTE.Document document, int numRemovedIncludes, bool canceled)
        {
            // Close Progress bar.
            progressDialog.EndWaitDialog();

            // Remove build hook again.
            UnsubscribeBuildEvents();

            // Message.
            Output.Instance.WriteLine("Removed {0} #include directives from '{1}'", numRemovedIncludes, document.Name);
            Output.Instance.OutputToForeground();

            // Notify that we are done.
            WorkInProgress = false;
            OnFileFinished?.Invoke(numRemovedIncludes, canceled);
        }
        private void TrialAndErrorRemovalThreadFunc(EnvDTE.Document document, TrialAndErrorRemovalOptionsPage settings,
                                                    Formatter.IncludeLineInfo[] includeLines, IVsThreadedWaitDialog2 progressDialog, ITextBuffer textBuffer)
        {
            int  numRemovedIncludes = 0;
            bool canceled           = false;

            try
            {
                int currentProgressStep = 0;

                // For ever include line..
                foreach (Formatter.IncludeLineInfo line in includeLines)
                {
                    // If we are working from top to bottom, the line number may have changed!
                    int currentLine = line.LineNumber;
                    if (settings.RemovalOrder == TrialAndErrorRemovalOptionsPage.IncludeRemovalOrder.TopToBottom)
                    {
                        currentLine -= numRemovedIncludes;
                    }

                    // Update progress.
                    string waitMessage  = $"Removing #includes from '{document.Name}'";
                    string progressText = $"Trying to remove '{line.IncludeContent}' ...";
                    progressDialog.UpdateProgress(
                        szUpdatedWaitMessage: waitMessage,
                        szProgressText: progressText,
                        szStatusBarText: "Running Trial & Error Removal - " + waitMessage + " - " + progressText,
                        iCurrentStep: currentProgressStep + 1,
                        iTotalSteps: includeLines.Length + 1,
                        fDisableCancel: false,
                        pfCanceled: out canceled);
                    if (canceled)
                    {
                        break;
                    }

                    ++currentProgressStep;

                    // Remove include - this needs to be done on the main thread.
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        using (var edit = textBuffer.CreateEdit())
                        {
                            if (settings.KeepLineBreaks)
                            {
                                edit.Delete(edit.Snapshot.Lines.ElementAt(currentLine).Extent);
                            }
                            else
                            {
                                edit.Delete(edit.Snapshot.Lines.ElementAt(currentLine).ExtentIncludingLineBreak);
                            }
                            edit.Apply();
                        }
                        outputWaitEvent.Set();
                    });
                    outputWaitEvent.WaitOne();

                    // Compile - In rare cases VS tells us that we are still building which should not be possible because we have received OnBuildFinished
                    // As a workaround we just try again a few times.
                    {
                        const int maxNumCompileAttempts = 3;
                        for (int numCompileFails = 0; numCompileFails < maxNumCompileAttempts; ++numCompileFails)
                        {
                            try
                            {
                                VSUtils.VCUtils.CompileSingleFile(document);
                            }
                            catch (Exception e)
                            {
                                Output.Instance.WriteLine("Compile Failed:\n{0}", e);

                                if (numCompileFails == maxNumCompileAttempts - 1)
                                {
                                    document.Undo();
                                    throw e;
                                }
                                else
                                {
                                    // Try again.
                                    System.Threading.Thread.Sleep(100);
                                    continue;
                                }
                            }
                            break;
                        }
                    }

                    // Wait till woken.
                    bool noTimeout = outputWaitEvent.WaitOne(timeoutMS);

                    // Undo removal if compilation failed.
                    if (!noTimeout || !lastBuildSuccessful)
                    {
                        Output.Instance.WriteLine("Could not remove #include: '{0}'", line.IncludeContent);
                        document.Undo();
                        if (!noTimeout)
                        {
                            Output.Instance.ErrorMsg("Compilation of {0} timeouted!", document.Name);
                            break;
                        }
                    }
                    else
                    {
                        Output.Instance.WriteLine("Successfully removed #include: '{0}'", line.IncludeContent);
                        ++numRemovedIncludes;
                    }
                }
            }
            catch (Exception ex)
            {
                Output.Instance.WriteLine("Unexpected error: {0}", ex);
            }
            finally
            {
                Application.Current.Dispatcher.Invoke(() => OnTrialAndErrorRemovalDone(progressDialog, document, numRemovedIncludes, canceled));
            }
        }