TFS与解决方案绑定信息清理
tfs与解决方案之间有相关信息需要清理,以下是相关的清理步骤。
删除关联文件以及文件夹
删除项目目录下所有的*.vssscc
、*.vspscc
为后缀的文件,删除隐藏文件夹$tf
修改项目的解决方案文件
在目录中找到以*.sln
为后缀名的解决方案文件,打开文件进行编辑。删除TeamFoundationVersionControl
所在的整块内容并保存。
GlobalSection(TeamFoundationVersionControl) = preSolution
SccNumberOfProjects = 2
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccTeamFoundationServer = http:///tfs/defaultcollection
SccLocalPath0 = .
SccProjectUniqueName1 = .csproj
//Scc……
EndGlobalSection
修改项目文件
在项目目录中,找到以*.csproj
为后缀的项目文件,打开进行编辑。
删除
<SccProjectName>
、<SccLocalPath>
、<SccAuxPath>
、<SccProvider>
这四个节点。
代码实现
为了方便以后使用,所以这里使用.net 5
写一个小工具来清理这些TFS
绑定信息。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DisassociateSourceCodeManagementTFS
{
public partial class DisassociateTFS : Form
{
public DisassociateTFS()
{
InitializeComponent();
}
private void btnDisassociateTFS_Click(object sender, EventArgs e)
{
string path = txtSourceFolder.Text;
if (string.IsNullOrWhiteSpace(path))
{
MessageBox.Show("请选择需要解除TFS绑定的源码目录","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
return;
}
if (!Directory.Exists(path))
{
return;
}
btnDisassociateTFS.Enabled = false;
var vssscc = Directory.EnumerateFiles(path, "*.vssscc", SearchOption.AllDirectories);
var vspscc = Directory.EnumerateFiles(path, "*.vspscc", SearchOption.AllDirectories);
DeleteFolderOrFiles(vssscc);
DeleteFolderOrFiles(vspscc);
var sln = Directory.EnumerateFiles(path, "*.sln", SearchOption.AllDirectories);
RewriteFileContent(sln,(item)=> {
return Regex.Replace(item, @"GlobalSection\(TeamFoundationVersionControl\)[\s\S]+?EndGlobalSection", "");
});
var csproj = Directory.EnumerateFiles(path, "*.csproj", SearchOption.AllDirectories);
RewriteFileContent(csproj, (item) => {
item = Regex.Replace(item, @"<SccProjectName>.+?</SccProjectName>", "");
item = Regex.Replace(item, @"<SccLocalPath>.+?</SccLocalPath>", "");
item = Regex.Replace(item, @"<SccAuxPath>.+?</SccAuxPath>", "");
item = Regex.Replace(item, @"<SccProvider>.+?</SccProvider>", "");
return item;
});
var tf = Directory.EnumerateDirectories(path, "$tf", SearchOption.AllDirectories);
DeleteFolderOrFiles(tf);
btnDisassociateTFS.Enabled = true;
MessageBox.Show("解除TFS绑定的源码目录成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void DeleteFolderOrFiles(IEnumerable<string> files)
{
if (files == null)
{
return;
}
foreach (var item in files)
{
if (File.Exists(item))
{
File.Delete(item);
continue;
}
if (Directory.Exists(item))
{
Directory.Delete(item, true);
}
}
}
private void RewriteFileContent(IEnumerable<string> files,Func<string,string> contentOperation)
{
foreach (var item in files)
{
if (!File.Exists(item))
{
continue;
}
Encoding textEncoding = GetFileEncodeType(item);
StreamReader reader = new StreamReader(item, textEncoding);
string fileContent = reader.ReadToEnd();
reader?.Close();
reader?.Dispose();
if (contentOperation != null)
{
fileContent = contentOperation(fileContent);
}
StreamWriter writer = new StreamWriter(item, false, textEncoding);
writer.Write(fileContent);
writer.Flush();
writer?.Close();
writer?.Dispose();
}
}
/// <summary>
/// 获取指定文件的编码
/// 以防止在不知道文件编码格式的情况下处理文件而造成的乱码问题
/// </summary>
/// <param name="filename">文件路径</param>
/// <returns></returns>
private System.Text.Encoding GetFileEncodeType(string filename)
{
if (!File.Exists(filename))
{
return System.Text.Encoding.Default;
}
System.Text.Encoding ReturnReturn = null;
System.IO.FileStream fs = null;
System.IO.BinaryReader br = null;
try
{
fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read);
br = new System.IO.BinaryReader(fs);
byte[] buffer = br.ReadBytes(2);
if (buffer.Length > 0 && buffer[0] >= 0xEF)
{
if (buffer[0] == 0xEF && buffer[1] == 0xBB)
{
ReturnReturn = System.Text.Encoding.UTF8;
}
else if (buffer[0] == 0xFE && buffer[1] == 0xFF)
{
ReturnReturn = System.Text.Encoding.BigEndianUnicode;
}
else if (buffer[0] == 0xFF && buffer[1] == 0xFE)
{
ReturnReturn = System.Text.Encoding.Unicode;
}
else
{
ReturnReturn = System.Text.Encoding.Default;
}
}
else if (buffer.Length > 0 && buffer[0] == 0xe4 && buffer[1] == 0xbd) //无BOM的UTF-8
{
ReturnReturn = System.Text.Encoding.UTF8;
}
else
{
ReturnReturn = System.Text.Encoding.Default;
}
}
catch
{
ReturnReturn = System.Text.Encoding.Default;
}
finally
{
br?.Close();
fs?.Close();
fs?.Dispose();
}
return ReturnReturn;
}
private void btnOpenFloder_Click(object sender, EventArgs e)
{
if (fbdFolderSelect.ShowDialog() == DialogResult.OK)
{
txtSourceFolder.Text = fbdFolderSelect.SelectedPath;
}
}
private void txtSourceFolder_DragDrop(object sender, DragEventArgs e)
{
string path = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
if (File.Exists(path))
{
FileInfo fileInfo = new FileInfo(path);
path=fileInfo.DirectoryName;
}
txtSourceFolder.Text = path;
}
private void txtSourceFolder_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.All;//重要代码:表明是所有类型的数据,比如文件路径
}
else
{
e.Effect = DragDropEffects.None;
}
}
}
}
示例下载
解除解决方案与TFS绑定以上示例请使用Microsoft Visual Studio 2019 打开
转载请注明:清风亦平凡 » 移除.net解决方案中TFS的绑定控制