Skip to content

Instantly share code, notes, and snippets.

@h2m730131
Last active June 1, 2026 05:28
Show Gist options
  • Select an option

  • Save h2m730131/3e23b75bfc4c2607cbc95c1910c19b31 to your computer and use it in GitHub Desktop.

Select an option

Save h2m730131/3e23b75bfc4c2607cbc95c1910c19b31 to your computer and use it in GitHub Desktop.
Visual Studio 2022 + Visual Commander
// 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