But it works on my PC!

The random thoughts of Richard Fennell on technology and software development

Getting going with the TFS Java API

If you are using the TFS 2012 Java API it is important you read the release notes. It is not enough to just reference the com.microsoft.tfs.sdk-11.0.0.jar file in your classpath as you might expect. You also have to pass a Java system property that associates com.microsoft.tfs.jni.native.base-directory with the location of the native library files that provide platform specific implementation for method calls.  The command line for this is done in the form

java.exe -D"com.microsoft.tfs.jni.native.base-directory=C:\Users\Username\YourApplication\native"

If you don’t set this property you get an exception similar to

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.microsoft.tfs.jni.internal.platformmisc.NativePlatformMisc.nativeGetEnvironmentVariable(Ljava/lang/String;)Ljava/lang/String;

Now setting this property on the command line is all well and good, but how do you do this if you are working in Eclipse?

The answer is you set the argument via the Run > Run Configuration. Select your configuration and enter the VM argument as shown below.


Once this is set you can run and debug you application inside Eclipse

Accessing TFS work item tags via the API

With TFS 2012.2 Microsoft have added tags to work items. These provide a great way to add custom information to work items without the need to customise the process template to add custom fields. This is important for users of the hosted http://tfs.visualstudio.com as this does not, at this time, allow any process customisation.

It is easy to add tags to any work item via the TFS web client, just press the Add.. button and either select an existing tag or add a new one. In the following PBI work item example I have added two tags, Tag1 and Tag2.


However, the problem with tags, at present, is that they can only be used as filters within the result of a work item query in the web client, as shown below.


They are not available inside work item queries and are not published to the TFS warehouse/cube for reporting purposes. Hopefully these limitations will be addressed in the future, but not today.

Given all this, I was recently asked by a client if they could use tags to mark PBI work items scheduled for a given release with a view to using this information to produce release notes. Obviously given the current limitations this cannot be done via work item queries or reporting, but you can use the TFS 2012.2 API to do this easily in .NET or Java.

The tags are stored as a ; separated list in a string field property. In C# there is a property in the API to get the tags …

using System;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Linq;

namespace BlackMarble
    public class TFSDemo
        public static string[] GetTagsForWorkItem(Uri tfsUri, int workItemId)
            // get a reference to the team project collection
            using (var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(tfsUri))
                // get a reference to the work item tracking service
                var workItemStore = projectCollection.GetService<WorkItemStore>();

                // and get the work item
                var wi = workItemStore.GetWorkItem(workItemId);
                return wi.Tags.Split(';');

but in Java you have to get the field yourself …

import java.net.URI;
import java.net.URISyntaxException;

import com.microsoft.tfs.core.TFSTeamProjectCollection;
import com.microsoft.tfs.core.clients.workitem.WorkItem;
import com.microsoft.tfs.core.clients.workitem.WorkItemClient;
import com.microsoft.tfs.core.httpclient.Credentials;
import com.microsoft.tfs.core.httpclient.DefaultNTCredentials;

public class TFSDemo {
      public static String[] GetTagsForWorkItem(URI tfsUri, int workItemId) 
          // get a reference to the team project collection
          Credentials credentials = new DefaultNTCredentials();
          TFSTeamProjectCollection projectCollection = new TFSTeamProjectCollection(tfsUri, credentials);
          // get a reference to the work item tracking service
          WorkItemClient wic = projectCollection.getWorkItemClient();
          // get the work item and return the tags
          WorkItem wi = wic.getWorkItemByID(workItemId);
          // there is no method for the tags, but can pull it out of the fields
          return wi.getFields().getField("Tags").getValue().toString().split(";");


Given these methods it is possible to write a tool that can select matching work items. Thus allowing you generate any output you require.

Update 14 May 2013

Just had confirmed that at present there is no API to write tags, I had not tried, I only need a read only solution. Keep an eye open for future releases of the SDKs to get a write call method.

Workaround for TF900546: An unexpected error occurred while running the RunTests activity

The problem

I have been working on a project that contains SharePoint 2010 WSP packages and a MSI distributed WPF application. These projects are all in a single solution with their unit tests. I have been getting a problem with our TFS 2012.2 build system, all the projects compile but at the test point I get the unhelpful

TF900546: An unexpected error occurred while running the RunTests activity: 'Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.'.

If I remote onto the build box and loaded the solution in Visual Studio (which was luckily installed on the build box) and tried to run the test in the test explorer I got


and the event log showed

Application: vstest.executionengine.x86.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidProgramException
   at System.ServiceModel.ServiceHost..ctor(System.Object, System.Uri[])
   at Microsoft.VisualStudio.TestPlatform.TestExecutor.TestExecutorMain.Run(System.String[])
   at Microsoft.VisualStudio.TestPlatform.TestExecutor.ServiceMain.Main(System.String[])


Faulting application name: vstest.executionengine.x86.exe, version: 11.0.60315.1, time stamp: 0x5142b4b6
Faulting module name: KERNELBASE.dll, version: 6.1.7601.18015, time stamp: 0x50b83c8a
Exception code: 0xe0434352
Fault offset: 0x0000c41f
Faulting process id: 0x700
Faulting application start time: 0x01ce4663824905bd
Faulting module path: C:\Windows\syswow64\KERNELBASE.dll
Report Id: c2689d15-b256-11e2-80aa-00155d0a5201

Next I tried creating in a simple new test project with one unit test, this failed with the same error.

As all the tests work locally on my development PC it was all pointing to a corrupted installed of Visual Studio (and/or the components installed as part of TFS build) on the build box. It should be noted that this was a build box with a good number of additional packages installed to support SharePoint, so patching order could be an issue.

The workaround

Robert, another of our ALM consultants, said he had seen a similar problem at client and suggested changing the test runner.

So in the build definition > process > Basic > Automated Tests > I edited the test run settings and changed to the MSTest VS2010 runner from the default.


Once this was done my tests then ran. However I then got a publishing error

API restriction: The assembly 'file:///C:\Builds\2\BM\CTAppBox.Main.CI\Binaries\_PublishedWebsites\WebServiceTestClient\bin\WebServiceTestClient.dll' has already loaded from a different location. It cannot be loaded from a new location within the same appdomain.

The problem was the build was set to the default test search criteria of *test*. This meant it picked a project it should not have, due to a poor naming convention. As soon as I changed the filter to *.tests all was OK.

I did retry the VS2012 test runner after fixing this naming issue, it had no effect.

I know I need to sort (rebuild) this build box, but now is not the time, I have a working solution that will do for now

Our upgrade to TFS 2012.2 has worked OK

I have mentioned in past posts the issues we had doing our first quarterly update for TFS 2012. Well today we had scheduled our upgrade to 2012.2 and I am please to say it all seems to have worked.

Unlike the last upgrade, this time we were doing nothing complex such as moving DB tier SQL instances; so it was a straight upgrade of a dual tier TFS 2012.1 instance with the DB being stored on a SQL2012 Availability Group (in previous updates you had to remove the DBs from the availability group for the update, with update 2 this is no longer required).

So we ran the EXE, all the files were copied on OK. So when we got to the verify stage of the wizard we had expected no issues, but the tool reported problems with the servers HTTPS Url. A quick check showed the issue was the server had the TFS ODATA service bound to HTTP on port 433, but using a different IP address to that used by TFS itself. As soon as this web site was stopped the wizard passed verification and the upgrade proceeded without an errors.

So it would seem that the verification does a rather basic check to see if port 443 is used on any IP address on the server, not just the ones being used TFS as identified via either IP address or host header bindings.

The only other thing we have had to do is upgrade Tiago’s Team Foundation Task Board Enhancer, without the upgrade the previous version of this extension did not work.

So not too bad an experience.

Error TF400129: Verifying that the team project collection has space for new system fields when upgrading TFS to 2012.2

Whist testing an upgrade of TFS 2010 to TFS 2012.2 I was getting a number of verification errors in the TFS configuration upgrade wizard. They were all TF400129 based such as

TF400129: Verifying that the team project collection has space for new system fields

but also mention models and schema.

A quick search threw up this thread on the subject, but on checking the DB tables I could see my problem was all together more basic. The thread talked of TPCs in incorrect states. In my case I had been provided with an empty DB, so TFS could find not tables at all. So I suppose the error message was a bit too specific, should have been ‘DB is empty!!!!’ error. Once I got a valid file backup restored for the TPC in question all was ok.

A bit more digging showed that I could also see an error if I issued the command

tfsconfig remapdbs /sqlinstances:TFS1 /databaseName:TFS1;Tfs_Configuration

As this too reported it could not find a DB it was expecting.

So the tip is make sure you really have the Dbs restored you think you have.

What machine name is being used when you compose an environment from running VMs in Lab Management?

This is a follow up to my older post on a similar subject 

When composing a new Lab Environment from running VMs the PC you are running MTM on needs to be able to connect to the running VMs. It does this using IP so at the most basic level you need to be able to resolve the name of the VM to an IP address.

If your VM is connected to the same LAN as your PC, but not in the same domain the chances are that DNS name resolution will not work. I find the best option is to put a temporary entry in your local hosts file, keeping it for just as long as the creation process takes.

But what should this entry be? Should it be the name of the VM as it appears in the MTM new environment wizard?

Turns out the answer is no, it needs to be the name as appears in the SC-VMM console


So the hosts table contains the correct entries for the FQDN (watch out for typo’s here, a mistype IP address only adds to the confusion) e.g. wyfrswin7.wyfrs.local shamrockbay.wyfrs.local

Once all this is set then just follow the process in my older post to enable the connection so the new environment wizard can verify OK.

Remember the firewall on the VMs may also be an issue. Just for the period of the environment creation I often disable this.

Also Wireshark is your friend, it will show if the machine you think is responding is the one you really want.

Lab Management with SCVMM 2012 and /labenvironmentplacementpolicy:aggressive

I did a post a year or so ago about setting up TFS Labs and mentioned command

C:\Program Files\Microsoft Team Foundation Server 2010\Tools>tfsconfig lab /hostgroup /collectionName:myTpc  ​/labenvironmentplacementpolicy:aggressive /edit /Name:"My hosts group"

This can be used tell TFS Lab Management to place VMs using any memory that is assigned stopped environments. This allowed a degree of over commitment of resources.

As I discovered today this command only works for SCVMM 2010 based system. if you try it you just get a message saying not support on SCVMM 2012. There appears to be no equivalent for 2012.

However you can use features such as dynamic memory with in SCVMM 2012 so all is not lost

TF900548 when using my Typemock 2012 TFS custom build activity

Using the Typemock TFS 2012 Build activity I created I had started seen the error

TF900548: An error occurred publishing the Visual Studio test results. Details: 'The following id must have a positive value: testRunId.'

I thought it might be down to having patched our build boxes to TFS 2012 Update 1, maybe it needed to be rebuild due to some dependency? However, on trying the build activity on my development TFS server I found it ran fine.

I made sure I had the same custom assemblies and Typemock autorun folder and build definition on both systems, I did, so it was not that.

Next I tried running the build but targeting an agent not on the same VM as the build controller. This worked, so it seems I have a build controller issues. So I ran Windows update to make sure the OS was patched it to date, it applied a few patches and rebooted. And all was OK my test ran gain.

It does seem that for many build issues the standard switch it off and back on again does the job