TFS Client side hook

2019-02-05 08:17发布

问题:

We have using TFS as version control. Currently the project management is done through our local PMS application. We have a requirement like when a team member check in the project, show a custom dialog for entering task details and update our local pms database. I want to show a custom dialog box that and/or after the check-in command is invoked. Also ensure that only successful submission of task details through this custom dialog boxes, we can checkin the projects.

回答1:

Creating your own checkin policy

You can do this through a Check-in policy. Check out my blog post on interacting with the user on check-in. The basic trick is to raise a check-in warning which the user can click, on the click event, you can show UI to the user and use standard Windows Forms functionality to interact with your system.

The most basic example code can be found in this StackOverflow question.

My multiple Branch policy uses this trick to ask a user to confirm whether the user really wants to check in code to multiple branches at the same time without having to use the bypass policy validation checkbox.


A note on installing Checkin policies

After configuring the Team project to use the checkin policy, Visual Studio will complain when the policy is not installed on the machine upon checkin. There is no easy way to distribute checkin policies to ensure that every user has it installed on their machine, or will automatically get it installed from TFS.

In your checkin policy you can provide a URI to the location of the policy package through the IPolicyDefinition.InstallationInstructions. The package can be a .msi, a .vsix or just a zip file with a script to copy the assembly and add the required registry key. Visual Studio doesn't care about the method you choose. If your company hosts their own Visual Studio gallery, it could point to the download location there as well.

If you pick an .msi you could have them distributed through existing provisioning tools that might be available in your organisation.

Clients that do not have the policy installed will automatically trigger a warning on checkin that can only be dismissed by checking the "bypass checkin policy" checkbox. That permission can be revoked, requiring all users to setup their machine correctly.

There is one more way to distribute checkin policies, which is through the Visual Studio Power tools. By checkin in the policies in Source Control in a specific folder and telling the Power Tools to download custom binaries (work item controls and checkin polciies), they will be installed automatically. Since these tools are not installed by default, not configured by default they need about the same amount of work to make this scenario work for you.



回答2:

 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using Microsoft.TeamFoundation.VersionControl.Client;
    namespace TFSPMSIntegration
    {
        [Serializable]
        public class CheckForPMSDetails : PolicyBase
        {
            public bool pmsDetailsConfirmed=false;
            private static frmPmsDetails _frm = null;
            public override string Description
            {
                get { return "Remind users to add PMS details to their checkins"; }
            }

            // This is a string that is stored with the policy definition on the source
            // control server.  If a user does not have our policy plugin installed, this string
            // will be displayed.  We can use this as an opportunity to explain to the user
            // how they might go about installing our policy plugin.
            public override string InstallationInstructions
            {
                get { return "To install this policy, follow the instructions in CheckForPMSDetails.cs."; }
            }

            // This string is the type of our policy.  It will be displayed to the user in a list
            // of all installed policy types when they are creating a new policy.
            public override string Type
            {
                get { return "Check for PMS Details"; }
            }

            // This string is a description of the type of our policy.  It will be displayed to the
            // user when they select our policy type in the list of policies installed on the system
            // as mentioned above.
            public override string TypeDescription
            {
                get { return "This policy will prompt the user to decide whether or not they should be allowed to check in."; }
            }

            // This method is invoked by the policy framework when the user creates a new checkin
            // policy or edits an existing checkin policy.  We can use this as an opportunity to
            // display UI specific to this policy type allowing the user to change the parameters
            // of the policy.
            public override bool Edit(IPolicyEditArgs args)
            {
                // no configuration to save
                return true;
            }

            // This method performs the actual evaluation.  It is called by the policy framework at various points in time
            // when policy should be evaluated.  In this example, we invoke this method ourselves when various asyc
            // events occur that may have invalidated the current list of failures.
            public override PolicyFailure[] Evaluate()
            {


                if (!pmsDetailsConfirmed)
                {
                    return new PolicyFailure[] {
                        new PolicyFailure("Please provide PMS Details about your checkin", this),
                    };
                }
                else
                {
                   //frmPmsDetails frm = Application.OpenForms["frmPmsDetails"] as frmPmsDetails;
                    if(_frm!=null)
                    PendingCheckin.PendingChanges.Comment = _frm.txtDescription.Text;
                    return new PolicyFailure[0];
                }
            }

            // This method is called if the user double-clicks on a policy failure in the UI.
            // We can handle this as we please, potentially prompting the user to perform
            // some activity that would eliminate the policy failure.
            public override void Activate(PolicyFailure failure)
            {
                //The Singleton design pattern is used for maitntain only one instance of Form class(UI).But everytime we have passing new value to the custom policy class.
                //Singleton approach needed , otherwise each time we click on policy message error, it will open multiple forms(UI)
                if (_frm == null)
                    _frm = new frmPmsDetails(this);
                else
                    _frm.CheckForPMSDetails = this;

                _frm.WindowState = FormWindowState.Minimized;
                _frm.TopMost = true;
                _frm.Show();
               _frm.ClearAll();
                _frm.WindowState = FormWindowState.Normal;
                _frm.BringToFront();

            }
            public void fn_Evaluate()
            {

                pmsDetailsConfirmed = true;
                base.OnPolicyStateChanged(Evaluate());


            }

            // This method is called if the user presses F1 when a policy failure is active in the UI.
            // We can handle this as we please, displaying help in whatever format is appropriate.
            // For this example, we'll just pop up a dialog.
            public override void DisplayHelp(PolicyFailure failure)
            {
                MessageBox.Show("This policy helps you to remember to add PMS details to your checkins.", "Prompt Policy Help");
            }

        }
    }

Custom checkin policy deployment

  • First create class library for custom checkin policy with your business logic

  • Deploy your check-in policies to customers using VSIX packages, which are easy to install.

  • You want to build your custom check-in policy for VS 2010, VS 2012, and VS 2013, then you’ll need a machine with all three of those Visual Studio versions installed side-by-side, and you’ll need the Visual Studio SDK installed for each one. The VSIX project template only available after successful installation of Visual Studio SDK.

Steps for creating check-in policies using VSIX packages in visual studio 2012 version

1.Create new project in visual studio 2012 version.

2.Select the Extensibility project template and choose the VSIX Project template.

  1. In the VSIX project add a reference to your custom checkin policy project
  2. You should add some items to the project like icon bitmap and License.txt, but only one of these is mandatory : “policies.pkgdef”

    1. You just add a text file, and name it policies.pkgdef. The name can be anything, but the extension should be “pkgdef”.
  3. Edit the policies.pkgdef to look like this:

[$RootKey$\TeamFoundation\SourceControl\Checkin Policies] "TFSPMSIntegration"="$PackageFolder$\TFSPMSIntegration.dll"

Part 1: This is a name you choose to give your policy package, and which will be the name of the key in the registry Part 2: This is the assembly name as defined in the project properties, Application/Assembly name field.

  1. At last you have to set up the vsixmanifest file, the one named source.extension.vsixmanifest.
  2. Choose the Assets tab and add the “ policies.pkgdef” file using “Add new asset” window

  3. You have to build the solution, and install the VSIX by double-clicking it. Note that it first takes effect when you restart Visual Studio.

*In order to disable and uninstall the package go to visual studio tools menu and choose “Extension and Updates “

Choose the extension and do the appropriate actions