最近正在微软VSTS Workshop项目中,忙了一个月了,今天将其中一个场景实现写在这里,该场景教大家如何自定义一个代码审核的TFS中的签入策略。
最近正在微软VSTS Workshop项目中,忙了一个月了,今天将其中一个场景实现写在这里,供大家参考。
实现步骤
- 打开VS2008:
- 选择"文件"下的"新建"菜单中的"项目":
- 在新项目中选择"Visual C#">"Windows">"类库":
- 输入项目名为"CopyrightCheckinPolicy":
- 选择确定按钮保存.
- 重命名"Clase1"为"CopyrightPolicy.cs":
- 右击项目选择"添加引用":
- 在".NET"选项卡选择"System.Windows.Forms"选择"确定":
- 再右击项目, 选择"添加引用"选择"浏览"选项卡, 找到下面路径的文件:
C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE \PrivateAssemblies\Microsoft.TeamFoundation.VersionControl.Client.dll
并添加:
- 在类中输入下面代码:

Code
using System.Windows.Forms;

using Microsoft.TeamFoundation.VersionControl.Client;

using System.Collections;

using System.IO;

using System;

using System.Collections.Generic;

using System.Text;

namespace CopyrightCheckinPolicy



{

[Serializable]

public class CopyrightPolicy : PolicyBase



{

public override string Description



{


get
{ return Strings.policyDescription; }

}

public override bool Edit(IPolicyEditArgs policyEditArgs)



{

return false;

}

public override PolicyFailure[] Evaluate()



{

if (this.Disposed)



{

throw new ObjectDisposedException(Strings.policyType, Strings.policyDisposedMessage);

}

ArrayList changes = new ArrayList();

PendingChange[] checkedFiles = this.PendingCheckin.PendingChanges.CheckedPendingChanges;

foreach (PendingChange change in checkedFiles)



{

if (Path.GetExtension(change.LocalItem) == ".cs")



{

if (change.ChangeType.ToString().Contains(ChangeType.Edit.ToString()) || change.ChangeType.ToString().Contains(ChangeType.Add.ToString()))



{

if (IsFileMissingCopyrightNotice(change.LocalItem))



{

PolicyFailure failure = new PolicyFailure(Strings.activateMessage + " : " + change.LocalItem, this);

changes.Add(failure);

}

}

}

}

return (PolicyFailure[])changes.ToArray(typeof(PolicyFailure));

}

public override string Type



{


get
{ return Strings.policyType; }

}

public override string TypeDescription



{


get
{ return Strings.policyTypeDescription; }

}

public override bool CanEdit



{

get



{

return false;

}

}

public override void DisplayHelp(PolicyFailure failure)



{

MessageBox.Show(Strings.policyHelp);

}

public override string InstallationInstructions



{

get



{

return Strings.policyInstallationInstructions;

}

set



{

Strings.policyInstallationInstructions = value;

}

}

public override void Activate(PolicyFailure failure)



{

MessageBox.Show(Strings.activateMessage);

}

protected override void OnPolicyStateChanged(PolicyFailure[] failures)



{

base.OnPolicyStateChanged(failures);

}

public override void Initialize(IPendingCheckin pendingCheckin)



{

base.Initialize(pendingCheckin);

pendingCheckin.PendingChanges.CheckedPendingChangesChanged += new EventHandler(pendingCheckin_CheckedPendingChangesChanged);

}

public override void Dispose()



{

PendingCheckin.PendingChanges.CheckedPendingChangesChanged -= new EventHandler(pendingCheckin_CheckedPendingChangesChanged);

base.Dispose();

}

private void pendingCheckin_CheckedPendingChangesChanged(Object sender, EventArgs e)



{

OnPolicyStateChanged(Evaluate());

}

private bool IsFileMissingCopyrightNotice(string fullFileName)



{

try



{

StreamReader sr = new StreamReader(fullFileName, true);

string sourceCode = sr.ReadToEnd();

bool result = !sourceCode.Contains("Copyright");

sr.Close();

return result;

}

catch (Exception)



{

return false;

}

}

}

internal class Strings



{

public static string policyType = "Copyright Notice Policy";

public static string policyDescription = "This policy ensures that all C# Source Files include a Copyright Notice.";

public static string policyInstallationInstructions = "Sorry, No instructions are available at this time";

public static string policyTypeDescription = policyType + " Description";

public static string policyDisposedMessage = policyType + " Object has been disposed.";

public static string policyHelp = "Sorry, help for " + policyType + " is not available at this time.";

public static string activateMessage = "Copyright Notice not found in this source file.";

}


- 编译成功后保存.
注册策略
- 中键入"Regedit"来运行注册表编辑器, 并找到下面注册表键:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\TeamFoundation\
SourceControl\Checkin Policies:
- 添加一个字符串类型的值, 然后将名字命名为刚才建立项目生成的DLL的名字"CopyrightCheckinPolicy":
- 双击选择在值中写入该DLL的完整路径, 如下(视具体情况而定):
C:\HOL\Dev\Module 05 - Lab 01 - Setting Up Custom Checkin Policies\Begin\CopyrightCheckinPolicy\CopyrightCheckinPolicy\bin\Debug\CopyrightCheckinPolicy.dll:
- 保存后即可.
测试策略
- 打开VS2008, 右击项目选择其属性:
- 选择"调试"页:
- 选择"启动外部程序"单选按钮, 然后设置其值为"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe":
- 保存.
- 调试该程序, 这时一个新的VS2008被打开:
- 选择团队项目, 在其中选择"团队项目设置"菜单中的"源代码管理":
- 选择"签入策略"选项卡, 点击"添加"按钮:
- 这时我们看到刚才定义的策略已经在其中了, 选择它并点击"确定":
- 新建一个项目, 将其加入到该团队项目中:

- 继续后将" // Copyright ( c ) MyCompany"加入Class1中:
- 再新建一个类:
- 然后"签入"所有代码:
- 这时可以看到提示未加入版权的信息:

希望本文对大家有帮助,谢谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!