I have created another (hopefully useful) checkin policy for Team Foundation Server 2008 - one that checks C# and VB.NET project files for COM references. The idea came from a customer, where they require the developers to use "authorized" interop assemblies instead of developers recreating those by simply adding a COM reference to each and every project. And how do you prevent this? By having a TFS checkin policy in place.
A COM reference looks like this in an MSBuild project file:
<ItemGroup> <COMReference Include="XcpControlLib"> <Guid>{283C8576-0726-4DBC-9609-3F855162009A}</Guid> <VersionMajor>1</VersionMajor> <VersionMinor>0</VersionMinor> <Lcid>0</Lcid> <WrapperTool>tlbimp</WrapperTool> <Isolated>False</Isolated> </COMReference> </ItemGroup>
Instead of searching for the string "<COMReference" I decided to use the MSBuild Engine API in my implementation:
public override PolicyFailure[] Evaluate() { PendingChange[] checkedFiles = PendingCheckin.PendingChanges.CheckedPendingChanges; ArrayList failures = new ArrayList(); foreach (PendingChange change in checkedFiles) { string extension = Path.GetExtension(change.LocalItem); if ((0 == String.Compare(extension, ".csproj", false)) || (0 == String.Compare(extension, ".vbproj", false))) { if (change.ChangeType == ChangeType.Edit || change.ChangeType == ChangeType.Add) { // this is a workaround because project.Load(fileName doesn't work in the same process as VS FileStream fs = File.OpenRead(change.LocalItem); Project project = new Project(); project.Load(new StreamReader(fs), ProjectLoadSettings.IgnoreMissingImports); foreach (BuildItemGroup big in project.ItemGroups) { foreach (BuildItem bi in big) { if (0 == String.Compare(bi.Name, "COMReference", true)) { PolicyFailure failure = new PolicyFailure(String.Format(ComReferencePolicyStrings.activateMessage, change.LocalItem), this); failures.Add(failure); } } } } } } return (PolicyFailure[])failures.ToArray(typeof(PolicyFailure)); }
At first, I tried to load directly from the .??proj files, but Visual Studio (after thinking a bit about it it is pretty obvious...) doesn't like someone inside its process play around with the MSBuild engine. That's why I resorted to loading it indirectly.
For installation I have provided checkinpolicy.reg, however, you must adapt the path to the .dll before importing it into the registry.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\TeamFoundation\SourceControl\Checkin Policies]"ChrisOnNet.CheckinPolicies.ComReferencePolicy"="C:\\Work\\ChrisOnNet.CheckinPolicies.ComReferencePolicy.dll"
Once registered, you can add it to your team projects:
As usual I have included the source code (BSD licensed) in the download:
ChrisOnNet.CheckinPolicies.ComReferencePolicy.zip (35.35 KB)