Last active
June 1, 2026 05:28
-
-
Save h2m730131/3e23b75bfc4c2607cbc95c1910c19b31 to your computer and use it in GitHub Desktop.
Visual Studio 2022 + Visual Commander
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Getting Latest Version From TFS on Solution Open | |
| public class E : VisualCommanderExt.IExtension | |
| { | |
| public void SetSite(EnvDTE80.DTE2 DTE_, Microsoft.VisualStudio.Shell.Package package) | |
| { | |
| DTE = DTE_; | |
| events = DTE.Events; | |
| solutionEvents = events.SolutionEvents; | |
| solutionEvents.Opened += OnSolutionOpened; | |
| if (IsSolutionOpen()) | |
| OnSolutionOpened(); | |
| } | |
| public void Close() | |
| { | |
| solutionEvents.Opened -= OnSolutionOpened; | |
| } | |
| private void OnSolutionOpened() | |
| { | |
| try | |
| { | |
| RenameGitDirectory(".git", ".git-temp"); | |
| SelectSolutionInSolutionExplorer(); | |
| if (IsSolutionPathValid() && IsSolutionUnderTfsSourceControl() && ConfirmGetLatestFromTFS()) | |
| { | |
| DTE.ExecuteCommand("File.TfsGetLatestVersion"); | |
| DTE.ExecuteCommand("View.Output"); | |
| System.Windows.MessageBox.Show("請在「View > Output > Source Control - Team Foundation」檢視 TFS 的更新狀態。"); | |
| } | |
| } | |
| catch (System.Exception ex) | |
| { | |
| System.Windows.MessageBox.Show(ex.ToString()); | |
| } | |
| finally | |
| { | |
| RenameGitDirectory(".git-temp", ".git"); | |
| } | |
| } | |
| private void SelectSolutionInSolutionExplorer() | |
| { | |
| try | |
| { | |
| EnvDTE.Window solutionExplorerWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindSolutionExplorer); | |
| EnvDTE.UIHierarchy uiHierarchy = solutionExplorerWindow.Object as EnvDTE.UIHierarchy; | |
| if (uiHierarchy != null && uiHierarchy.UIHierarchyItems.Count > 0) | |
| { | |
| EnvDTE.UIHierarchyItem rootItem = uiHierarchy.UIHierarchyItems.Item(1); | |
| if (rootItem != null) | |
| { | |
| rootItem.Select(EnvDTE.vsUISelectionType.vsUISelectionTypeSelect); | |
| solutionExplorerWindow.Activate(); | |
| } | |
| } | |
| } | |
| catch (System.Exception ex) | |
| { | |
| System.Windows.MessageBox.Show("選擇方案失敗: " + ex.Message); | |
| } | |
| } | |
| private bool IsSolutionUnderTfsSourceControl() | |
| { | |
| try | |
| { | |
| // 檢查方案是否在原始檔控制之下 | |
| if (DTE.SourceControl == null) | |
| return false; | |
| // 檢查方案檔案是否在原始檔控制之下 | |
| string solutionPath = DTE.Solution.FileName; | |
| if (string.IsNullOrEmpty(solutionPath)) | |
| return false; | |
| // // 使用 SourceControl.IsItemUnderSCC 檢查是否在版本控制中 (包含 Git, TFS, ...) | |
| // bool isUnderSourceControl = DTE.SourceControl.IsItemUnderSCC(solutionPath); | |
| // 判斷方案檔案內容是否含有 "GlobalSection(TeamFoundationVersionControl)" | |
| string slnContent = System.IO.File.ReadAllText(solutionPath); | |
| bool isUnderSourceControl = slnContent.Contains("GlobalSection(TeamFoundationVersionControl)"); | |
| if (!isUnderSourceControl) | |
| { | |
| // System.Windows.MessageBox.Show("此方案不在 Team Foundation 版本控制之下,將略過取得最新版本。", | |
| // "", | |
| // System.Windows.MessageBoxButton.OK, | |
| // System.Windows.MessageBoxImage.Information); | |
| } | |
| return isUnderSourceControl; | |
| } | |
| catch (System.Exception ex) | |
| { | |
| System.Windows.MessageBox.Show("檢查原始檔控制狀態失敗: " + ex.Message); | |
| return false; | |
| } | |
| } | |
| private bool IsSolutionOpen() | |
| { | |
| return DTE != null && DTE.Solution != null && DTE.Solution.IsOpen; | |
| } | |
| private bool IsSolutionPathValid() | |
| { | |
| try | |
| { | |
| string path = DTE.Solution.FileName; | |
| return path != null && path.Length > 0 && System.IO.Path.IsPathRooted(path) && System.IO.File.Exists(path); | |
| } | |
| catch (System.Exception ex) | |
| { | |
| System.Windows.MessageBox.Show(ex.ToString()); | |
| } | |
| return false; | |
| } | |
| private bool ConfirmGetLatestFromTFS() | |
| { | |
| bool result = true; | |
| int countdown = 5; | |
| var window = new System.Windows.Window | |
| { | |
| Title = "Confirm", | |
| Width = 420, | |
| Height = 140, | |
| WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen, | |
| ResizeMode = System.Windows.ResizeMode.NoResize, | |
| Topmost = true | |
| }; | |
| var label = new System.Windows.Controls.TextBlock | |
| { | |
| TextWrapping = System.Windows.TextWrapping.Wrap, | |
| Margin = new System.Windows.Thickness(12, 12, 12, 8), | |
| Text = string.Format("Are you sure you want to get latest version from TFS? (Auto YES in {0}s)", countdown) | |
| }; | |
| var yesButton = new System.Windows.Controls.Button { Content = "Yes", Width = 75, Margin = new System.Windows.Thickness(5) }; | |
| var noButton = new System.Windows.Controls.Button { Content = "No", Width = 75, Margin = new System.Windows.Thickness(5) }; | |
| yesButton.Click += (s, e) => { result = true; window.Close(); }; | |
| noButton.Click += (s, e) => { result = false; window.Close(); }; | |
| var buttonPanel = new System.Windows.Controls.StackPanel | |
| { | |
| Orientation = System.Windows.Controls.Orientation.Horizontal, | |
| HorizontalAlignment = System.Windows.HorizontalAlignment.Center | |
| }; | |
| buttonPanel.Children.Add(yesButton); | |
| buttonPanel.Children.Add(noButton); | |
| var panel = new System.Windows.Controls.StackPanel(); | |
| panel.Children.Add(label); | |
| panel.Children.Add(buttonPanel); | |
| window.Content = panel; | |
| var timer = new System.Windows.Threading.DispatcherTimer | |
| { | |
| Interval = System.TimeSpan.FromSeconds(1) | |
| }; | |
| timer.Tick += (s, e) => | |
| { | |
| countdown--; | |
| if (countdown <= 0) | |
| { | |
| timer.Stop(); | |
| result = true; | |
| window.Close(); | |
| } | |
| else | |
| { | |
| label.Text = string.Format("Are you sure you want to get latest version from TFS? (Auto YES in {0}s)", countdown); | |
| } | |
| }; | |
| timer.Start(); | |
| window.ShowDialog(); | |
| return result; | |
| } | |
| private void RenameGitDirectory(string fromName, string toName) | |
| { | |
| try | |
| { | |
| if (!IsSolutionPathValid()) | |
| return; | |
| string solutionPath = DTE.Solution.FileName; | |
| string solutionDirectory = System.IO.Path.GetDirectoryName(solutionPath); | |
| string fromPath = System.IO.Path.Combine(solutionDirectory, fromName); | |
| string toPath = System.IO.Path.Combine(solutionDirectory, toName); | |
| // 檢查來源目錄是否存在 | |
| if (System.IO.Directory.Exists(fromPath)) | |
| { | |
| // 如果目標目錄已存在,先刪除 | |
| if (System.IO.Directory.Exists(toPath)) | |
| { | |
| System.IO.Directory.Delete(toPath, true); | |
| } | |
| // 重新命名目錄 | |
| System.IO.Directory.Move(fromPath, toPath); | |
| } | |
| } | |
| catch (System.Exception ex) | |
| { | |
| // 靜默處理錯誤,不影響主要流程 | |
| System.Diagnostics.Debug.WriteLine("RenameGitDirectory 失敗: " + ex.Message); | |
| } | |
| } | |
| EnvDTE80.DTE2 DTE; | |
| private EnvDTE.Events events; | |
| private EnvDTE.SolutionEvents solutionEvents; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment