2

I need to get the revision number from TFS, if i run tf.exe from a Process the process halts. If i run the same command from command promts it works?

int revision;

var repo = "path to repo"

var psi = new ProcessStartInfo("cmd", @"/c ""C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\tf.exe"" properties $/MYProject -recursive /version:W")
{
    UseShellExecute = false,
    ErrorDialog = false,
    CreateNoWindow = false,
    WorkingDirectory = repo,
    RedirectStandardOutput = true,
    RedirectStandardError = true
};

using (var p = Process.Start(psi))
{
    p.WaitForExit();
    if (p.ExitCode != 0)
    {
        using (var standardError = p.StandardError)
        {
            Console.WriteLine(standardError.ReadToEnd());
        }
    } 
    else
    {
        using (var standardOutput = p.StandardOutput)
        {
            revision = int.Parse(standardOutput.ReadToEnd());
        }
    }
}

edit:

I did this, works, should I go with it?

public int GetLatestChangeSet(string url, string project)
{
    var server = new TeamFoundationServer(new Uri(url));
    var version = server.GetService(typeof(VersionControlServer)) as VersionControlServer;

    var items = version.GetItems(string.Format(@"$\{0}", project), RecursionType.Full);
    return items.Items.Max(i => i.ChangesetId);
}
Anders
  • 17,306
  • 10
  • 76
  • 144
  • Why don't you use the SDK? http://msdn.microsoft.com/en-us/library/bb130146(v=vs.100).aspx – Mike Miller Jun 11 '12 at 10:16
  • Agree with @MikeMiller, if you want help use Reflector on the TF tool, internally it uses the TFS SDK. – Matteo Migliore Jun 11 '12 at 10:26
  • In your ProcessStartInfo you are using a wrong syntax for starting a .exe file. (Startb a .exe over "cmd") here is the right syntax for [ProcessStartInfo](http://stackoverflow.com/questions/1538711/passing-paths-to-cmd-using-processstartinfo-not-working-as-intended). – moskito-x Jun 11 '12 at 10:55

3 Answers3

1

you better use the below namespace which contains all you need to achieve that

Microsoft.TeamFoundation.VersionControl.Client 

//this is just an example 

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri("http://myserver:8080/"));
VersionControlServer sourceControl = tpc.GetService<VersionControlServer>();
return sourceControl.GetLatestChangesetId();

http://msdn.microsoft.com/en-us/library/ms228232(v=vs.80)

Massimiliano Peluso
  • 26,379
  • 6
  • 61
  • 70
  • Thanks, you dont happen to know how to choose project? Code above returns latest changset for entire server – Anders Jun 11 '12 at 10:33
  • http://stackoverflow.com/questions/8493762/tfs-2010-getting-list-of-changeset-ids – Massimiliano Peluso Jun 11 '12 at 10:40
  • Sorry just realized that this is not at all what I want, my first code example, uses the local workspace changeset. Your code uses the latest on server. I need the local version, because the Build server is checking out the code, and builds, if someone commits between build and checking version the version will be wrong – Anders Jun 11 '12 at 12:08
1

The error occurs because your StandardOutput stream buffer is full and thus blocks. To read standard input/output it's recommended to subscribe to the OutputDataReceived event. Alternatively, spin up another thread to constantly read the data from the StandardOutput stream.

See the example on the OutputDataReceived event docs for a complete code sample.

A better solution would be to use the TFS API as suggested by Massimiliano Peluso. But this is the reason for your approach failing.

jessehouwing
  • 106,458
  • 22
  • 256
  • 341
1

I ended up with this solution which uses the local workspace revision

public class ReadTfsRevisionTask : Task
{
    public override bool Execute()
    {
        try
        {
            ChangesetId = GetLatestChangeSet(Server, Project);
            return true;
        }
        catch
        {
            return false;
        }
    }

    private int GetLatestChangeSet(string url, string project)
    {
        project = string.Format(@"$/{0}", project);

        var server = new TeamFoundationServer(new Uri(url));
        var version = server.GetService<VersionControlServer>();

        var workspace = version.QueryWorkspaces(null, WindowsIdentity.GetCurrent().Name, System.Environment.MachineName).First();
        var folder = workspace.Folders.First(f => f.ServerItem == project);

        return workspace.GetLocalVersions(new[] { new ItemSpec(folder.LocalItem, RecursionType.Full) }, false)
            .SelectMany(lv => lv.Select(l => l.Version)).Max();
    }

    [Required]
    public string Server { get; set; }

    [Required]
    public string Project { get; set; }

    [Output]
    public int ChangesetId { get; set; }

}
Anders
  • 17,306
  • 10
  • 76
  • 144