internal string GetNewTitle(Solution solution, string pattern, SettingsSet cfg) { Document activeDocument = null; Window activeWindow = null; try { activeDocument = Globals.DTE.ActiveDocument; } catch { // Do nothing } try { activeWindow = Globals.DTE.ActiveWindow; } catch { // Do nothing } var solutionFp = solution?.FullName; if (activeDocument == null && string.IsNullOrEmpty(solutionFp)) { if (activeWindow == null || activeWindow.Caption == Globals.DTE.MainWindow.Caption) { return(this.IDEName); } } string path; var documentName = Globals.GetActiveDocumentNameOrEmpty(activeDocument); var documentPath = Globals.GetActiveDocumentPathOrEmpty(activeDocument); var windowName = Globals.GetActiveWindowNameOrEmpty(activeWindow); if (!string.IsNullOrEmpty(solutionFp)) { path = solutionFp; } else { path = documentPath; } var pathParts = this.SplitPath(path); if (!string.IsNullOrEmpty(path)) { pathParts[0] = Path.GetPathRoot(path).Replace("\\", ""); } var documentPathParts = this.SplitPath(documentPath); if (!string.IsNullOrEmpty(documentPath)) { documentPathParts[0] = Path.GetPathRoot(documentPath).Replace("\\", ""); } pattern = this.TagRegex.Replace(pattern, match => { try { var tag = match.Groups[1].Value; try { switch (tag) { case "configurationName": return(Globals.GetActiveConfigurationNameOrEmpty(solution)); case "platformName": return(Globals.GetPlatformNameOrEmpty(solution)); case "projectName": return(Globals.GetActiveProjectNameOrEmpty()); case "solutionName": return(cfg.SolutionName ?? string.Empty); case "gitBranchName": Globals.UpdateGitExecFp(this.GlobalSettings.GitDirectory); // there is likely a better way to adjust the git path return(Globals.GetGitBranchNameOrEmpty(solution)); case "workspaceName": return(Globals.GetWorkspaceNameOrEmpty(solution)); case "workspaceOwnerName": return(Globals.GetWorkspaceOwnerNameOrEmpty(solution)); case "documentName": return(string.IsNullOrEmpty(documentName) ? windowName : documentName); case "documentProjectName": return(Globals.GetActiveDocumentProjectNameOrEmpty(activeDocument: activeDocument)); case "documentProjectFileName": return(Globals.GetActiveDocumentProjectFileNameOrEmpty(activeDocument: activeDocument)); case "documentPath": return(string.IsNullOrEmpty(documentName) ? windowName : documentPath); case "vsMajorVersion": return(Globals.VsMajorVersion.ToString(CultureInfo.InvariantCulture)); case "vsMajorVersionYear": return(Globals.VsMajorVersionYear.ToString(CultureInfo.InvariantCulture)); case "ideName": return(this.IDEName ?? string.Empty); case "path": return(string.IsNullOrEmpty(path) ? windowName : path); case "parentPath": return(GetParentPath(pathParts, cfg?.ClosestParentDepth ?? this.GlobalSettings.ClosestParentDepth, cfg?.FarthestParentDepth ?? this.GlobalSettings.FarthestParentDepth) ?? string.Empty); default: if (tag.StartsWith("parent")) { var m = RangeRegex.Match(tag.Substring("parent".Length)); if (m.Success) { if (!pathParts.Any()) { return(string.Empty); } var startIndex = Math.Min(pathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["startIndex"].Value, CultureInfo.InvariantCulture))); var endIndex = Math.Min(pathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["endIndex"].Value, CultureInfo.InvariantCulture))); var pathRange = pathParts.GetRange(startIndex: pathParts.Length - 1 - startIndex, endIndex: pathParts.Length - 1 - endIndex).ToArray(); return(GetPathForTitle(pathRange)); } m = IndexRegex.Match(tag.Substring("parent".Length)); if (m.Success) { if (!pathParts.Any()) { return(string.Empty); } var index = Math.Min(pathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["index"].Value, CultureInfo.InvariantCulture))); return(pathParts[pathParts.Length - 1 - index]); } } if (tag.StartsWith("path")) { var m = RangeRegex.Match(tag.Substring("path".Length)); if (m.Success) { if (!pathParts.Any()) { return(string.Empty); } var startIndex = Math.Min(pathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["startIndex"].Value, CultureInfo.InvariantCulture))); var endIndex = Math.Min(pathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["endIndex"].Value, CultureInfo.InvariantCulture))); var pathRange = pathParts.GetRange(startIndex: startIndex, endIndex: endIndex).ToArray(); return(GetPathForTitle(pathRange)); } m = IndexRegex.Match(tag.Substring("path".Length)); if (m.Success) { if (!pathParts.Any()) { return(string.Empty); } var index = Math.Min(pathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["index"].Value, CultureInfo.InvariantCulture))); return(pathParts[index]); } } if (tag.StartsWith("documentPath")) { var m = RangeRegex.Match(tag.Substring("documentPath".Length)); if (m.Success) { if (!documentPathParts.Any()) { return(string.Empty); } var startIndex = Math.Min(documentPathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["startIndex"].Value, CultureInfo.InvariantCulture))); var endIndex = Math.Min(documentPathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["endIndex"].Value, CultureInfo.InvariantCulture))); var pathRange = documentPathParts.GetRange(startIndex: startIndex, endIndex: endIndex).ToArray(); return(GetPathForTitle(pathRange)); } m = IndexRegex.Match(tag.Substring("documentPath".Length)); if (m.Success) { if (!documentPathParts.Any()) { return(string.Empty); } var index = Math.Min(documentPathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["index"].Value, CultureInfo.InvariantCulture))); return(documentPathParts[index]); } } if (tag.StartsWith("documentParentPath")) { var m = RangeRegex.Match(tag.Substring("documentParentPath".Length)); if (m.Success) { if (!documentPathParts.Any()) { return(string.Empty); } var startIndex = Math.Min(documentPathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["startIndex"].Value, CultureInfo.InvariantCulture))); var endIndex = Math.Min(documentPathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["endIndex"].Value, CultureInfo.InvariantCulture))); var pathRange = documentPathParts.GetRange(startIndex: documentPathParts.Length - 1 - startIndex, endIndex: documentPathParts.Length - 1 - endIndex).ToArray(); return(GetPathForTitle(pathRange)); } m = IndexRegex.Match(tag.Substring("documentParentPath".Length)); if (m.Success) { if (!documentPathParts.Any()) { return(string.Empty); } var index = Math.Min(documentPathParts.Length - 1, Math.Max(0, int.Parse(m.Groups["index"].Value, CultureInfo.InvariantCulture))); return(documentPathParts[documentPathParts.Length - 1 - index]); } } break; } return(match.Value); } catch (Exception ex) { if (this.GlobalSettings.EnableDebugMode) { WriteOutput("ReplaceTag (" + tag + ") failed: " + ex); } throw; } } catch { return(""); } }); var appendedString = cfg?.AppendedString ?? this.GlobalSettings.AppendedString; return(pattern + " " + appendedString); }
private void UpdateWindowTitle() { if (!Monitor.TryEnter(this.UpdateWindowTitleLock)) { return; } try { var useDefaultPattern = true; if (this.GlobalSettings.AlwaysRewriteTitles) { useDefaultPattern = false; } else { Globals.VSMultiInstanceInfo info; Globals.GetVSMultiInstanceInfo(out info); if (info.nb_instances_same_solution >= 2) { useDefaultPattern = false; } else { var currentInstance = System.Diagnostics.Process.GetCurrentProcess(); var vsInstances = System.Diagnostics.Process.GetProcessesByName("devenv"); if (vsInstances.Length >= 2) { //Check if multiple instances of devenv have identical original names. If so, then rewrite the title of current instance (normally the extension will run on each instance so no need to rewrite them as well). Otherwise do not rewrite the title. //The best would be to get the EnvDTE.DTE object of the other instances, and compare the solution or project names directly instead of relying on window titles (which may be hacked by third party software as well). But using moniker it will only work if they are launched with the same privilege. var currentInstanceName = Path.GetFileNameWithoutExtension(Globals.DTE.Solution.FullName); if (string.IsNullOrEmpty(currentInstanceName) || (from vsInstance in vsInstances where vsInstance.Id != currentInstance.Id select this.GetVSSolutionName(vsInstance.MainWindowTitle)).Any(vsInstanceName => vsInstanceName != null && currentInstanceName == vsInstanceName)) { useDefaultPattern = false; } } } } var solution = Globals.DTE.Solution; var solutionFp = solution?.FullName; var settings = this.GetSettings(solutionFp); var pattern = this.GetPattern(solutionFp, useDefaultPattern, settings); this.ChangeWindowTitle(this.GetNewTitle(solution, pattern, settings)); } catch (Exception ex) { try { if (this.GlobalSettings.EnableDebugMode) { WriteOutput("UpdateWindowTitle exception: " + ex); } } catch { // ignored } } finally { Monitor.Exit(this.UpdateWindowTitleLock); } }