Search code examples
c#visual-studiotfstfs-2015visual-studio-extensions

How to subscribe to TFS's VersionControlServer Events programatically in C#?


I'm writing an Visual Studio 2015 Extension, where i want to subscribe to some of the TFS's VersionControlServer Events. But actually none of the events getting fired. I guess i already know why, but I dont know how to get it working for my purpose. Also the documentation from microsoft is pretty poor and literally non-existend ...

The question is: Is there a way to subscribe to the events from my extension.

I've already researched many threads and couldn't find anything that is helpful for me. My code looks like this:

var tfsProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection (TfsPath, new UICredentialsProvider ());
var tfsVersionControlServer = tfsProjectCollection.GetService<VersionControlServer> ();

tfsVersionControlServer.CommitCheckin += TfsVersionControlServer_CommitCheckin;

The problem here is , that the VersionControlServer is not the same instance that the Visual Studio uses. So if I, for example, make a shelveset, the event wont fire. Only if I would do the shelving programatically with the instance I have here, I would get the event fired.

My extension is working fine, except this issue. My extension is getting initialized on startup and subscribes during Visual Studio startup to the events. Now if I create Shelveset I would like to have the event BeforeShelvePendingChange fired.

Thanks in advance


Solution

  • As I already said, I got a solution for my problem (with some drawbacks).

    Lets say my extension name is MyExtension:

    First I added a Property in MyExtension.cs

     public EnvDTE.DTE DTEObject { get; set; }
    

    Then in MyExtensionPackage.cs I can get a DTEObject right after the package got initialized:

    protected override void Initialize ()
    {
      MyExtension.Initialize (this);
      base.Initialize ();
      MyExtension.Instance.DTEObject = (EnvDTE.DTE)base.GetService (typeof (Microsoft.VisualStudio.Shell.Interop.SDTE));
    }
    

    Now I can work with the DTEObject within the extension and get any Object via GetObject. In My case I'm getting the current instance of the VersionControlEx.

    var tfsVersionControlExt = DTEObject.GetObject ("Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt") as Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt;
    

    And then I'm able to get the VersionControlServer for this instance:

    TfsVersionControlServer = tfsVersionControlExt.Explorer.Workspace.VersionControlServer;
    

    The drawback here is, that the new instance of Visual Studio needs to have the Source Control Explorer to be opened. If the user starts his Visual Studio without the Explorer, you will always getting null for the VersioncontrolServer.

    The workaround I did is, that I'm waiting for the Studio to startup and then I navigate in the Source Control Explorer (programatically) to the base path and force the Studio to load the Explorer and then I'm able to get what I need. I'm not that happy with my solution, but i go it working. If there is a better solution, I'm listening :)