Checkin policy multitargeting

Updated 27 August 2015: The provided solution now supports multi-targeting to Visual Studio 2015 as well!

With each major release of Visual Studio, customers find that they have to re-build their check-in policies for TFS version control to target the new version of the client object model. As the pace of Visual Studio major releases has quickened (there will be both a Visual Studio 2012 and a Visual Studio 2013!) customers have been experiencing this pain more often. We also often receive questions about how to manage deployment of check-in policies in mixed environments, where some users have Visual Studio 2010, and some have Visual Studio 2012, but both versions of Visual Studio need to use a custom check-in policy developed in-house.

Example multitargeted checkin policy solution

Today we are releasing an example solution which demonstrates two nifty things:

  1. How to use a single code base for your custom check-in policy, but build that check-in policy for Visual Studio 2010, 2012, and 2013 simultaneously.
  2. How to deploy your check-in policies to customers using VSIX packages, which are easy to install.

You can download the solution from here . (Updated 27 August 2015)

How does it work?

You can open this solution in VS 2010, VS 2012, or VS 2013. In the toolbar of Visual Studio you will see a Configuration drop-down that allows you to select what “target” version of the TFS Version Control client object model to use for the build – 2010, 2012, or 2013. When you say Build, the appropriate version of the client object model is used to create a check-in policy DLL. So if you selected VS2012_Release, then you would get a DLL in the bin\VS2012_Release directory that is suitable for installation on VS 2012 clients.

If you have the Visual Studio SDK installed for whatever version of Visual Studio you’re using, then the solution will automatically detect this, and in addition to the DLL in the bin\VS2012_Release folder, you get a VSIX you can distribute to your clients to install on their machines. If you don’t have the Visual Studio SDK installed, we notify you with a build warning: “The Visual Studio SDK is not installed, so no VSIX installer package can be generated. ” The Visual Studio SDK is a free download – it’s about 10 megabytes and is specific to each version of Visual Studio. (Be careful when getting it for VS 2010 – if you have Service Pack 1 installed, then you need to make sure to get the “VS 2010 SP1 SDK” which is a different download.)

If you have a fully mixed environment, and 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. Then when you’re ready to produce a VSIX installer for your clients, open the solution in each Visual Studio version one at a time. Make sure that the appropriate Configuration is selected in the toolbar (VS2010_Release for VS 2010, VS2012_Release for VS 2012, etc.) and do a build. At the end of the process, in your bin directory, you’ll have three VSIX installers – one for each version of Visual Studio. Distribute these installers to your users so that they can install the check-in policy. VS 2010 users get the VS 2010 VSIX, VS 2012 users get the VS 2012 VSIX, and so on.

How do I adapt the solution to my existing custom check-in policy’s codebase?

You’ll probably want to start by doing a giant search-and-replace on the strings ExampleMultitargetedCheckinPolicy and MultitargetedCheckinPolicy to replace them with your check-in policy name and namespace. Don’t be afraid to open up the .csproj file in Notepad to make changes to it.

Also, be sure to update the VSIXMANIFEST files so that your VSIX extension gets the right company name, new GUIDs, and your own description of the check-in policy. The PKGDEF file contains the registry entries that are added by the VSIX that allow the check-in policy to be discovered by Visual Studio, so it should be updated too, to reflect the new namespace and name of your check-in policy, and the name of the DLL file your solution is producing.

Downsides to VSIX deployment

One downside of VSIX deployment of check-in policies is that they are not visible outside of Visual Studio. If you’re using the TF.exe command line, Git-TFS, or the Windows Explorer shell extension for TFS, then the check-in policy will not be available in those environments, and you’ll have to override it in order to check in. If you need the check-in policy available in these environments, VSIX deployment is not for you, and you should deploy your check-in policy via the traditional method:

  1. Put the DLL file for the check-in policy somewhere on disk
  2. Add a registry value of type REG_SZ to “HKLM\SOFTWARE\Microsoft\VisualStudio\[version]\TeamFoundation\SourceControl\Checkin Policies” that points to the check-in policy DLL
  3. (VS 2012 and later only) Run devenv /setup from an elevated command prompt so that the check-in policy is visible to Visual Studio

If you’re not going to use VSIX deployment, then you don’t need the Visual Studio SDK installed, and you can just ignore the build warning that says the VSIX installer is not being generated.

Comments

  • Anonymous
    August 12, 2013
    Hi P. Kelley, your article was very informative about distributing a single check-in policy to multiple versions of VS for different clients, but what about distributing that same check-in policy to a single client that is running multiple versions of VS on a single machine?  

  • Anonymous
    August 12, 2013
    The comment has been removed

  • Anonymous
    August 13, 2013
    Thanks for the response! Do you think there is a difference in using VSIX and manually modifying the registry? Currently, I have two versions of my custom check-in policy (compiled under VS 2010 and VS 2013).  My clients have both versions of VS installed, so they require both versions of the check-in policy, which means two different string keys/values in the registry.  The problem is VS 2010 generates an error for the VS 2013 version of the check-in policy when trying to check-in files, and VS 2013 generates an error for the VS 2010 version of the check-in policy.   Is there a solution to this specific problem?  Hopefully I described my situation well enough...

  • Anonymous
    August 21, 2013
    Great article - it really helped me.  I'm looking for a way to change the output VSIX name.  The reason for this is that we host an internal extensions library and if both the 2012 and 2013 versions have the same name, they can't live together in the same folder. Any ideas?

  • Anonymous
    August 21, 2013
    Hi CSharpen, You should make sure that your two builds of the check-in policy DLL have the same namespace and type name -- i.e. CSharpen.CheckinPolicyLibrary.MyCheckinPolicy. The version number can vary -- for example you might use 10.0.0.0 for VS 2010, and 12.0.0.0 for VS 2012. This should permit VS 2010 to deserialize the VS 2013 check-in policy from the server, or VS 2013 to deserialize a VS 2010 check-in policy from the server, as long as the objects in the two assemblies have the same internal structure. This is how our check-in policies remain compatible from version to version. They keep the same name, but the version # varies -- and the member variables of the policy object are the same. Thanks, P. Kelley

  • Anonymous
    August 21, 2013
    Greg, This sounds like a great opportunity for you to learn more about MSBuild! If you open the .csproj file up in a text editor, you'll be able to see how the build process makes decisions along the way about how to link against different assemblies when building in different configurations, etc. I believe if you set the property called TargetVsixContainerName in the appropriate configuration sections, you can override the name of the output VSIX to meet your needs. Be sure to put the .vsix extension on the end of whatever fully qualified path you provide. If you want to use the same output directory as everything else, then you could set it to, for example, $(OutDir)MySpecialName.vsix. Thanks, P. Kelley

  • Anonymous
    August 21, 2013
    Thanks - I just didn't know what the property was called.  I added the following to my csproj.  Hopefully this helps others:  <PropertyGroup>      <TargetVsixContainerName Condition="'$(VisualStudioVersion)' == '10.0'">MultitargetedCheckinPolicy.vs2010.vsix</TargetVsixContainerName>      <TargetVsixContainerName Condition="'$(VisualStudioVersion)' == '11.0'">MultitargetedCheckinPolicy.vs2012.vsix</TargetVsixContainerName>      <TargetVsixContainerName Condition="'$(VisualStudioVersion)' == '12.0'">MultitargetedCheckinPolicy.vs2013.vsix</TargetVsixContainerName>  </PropertyGroup>

  • Anonymous
    September 06, 2013
    The comment has been removed