Search code examples
c#apitfslockingworkspace

How to lock a file under local workspace via TFS 2012 API


I am attempting to check-out a single file via workspace.PendEdit with an exclusive lock LockLevel.CheckOut. The following function succeeds (no errors) but it seems to have no effect on the file in TFS (not checked-out and no lock).

public static void Lock(string filePath)
    {
        var workspace = GetWorkspace(filePath);
        workspace.PendEdit(new[] {filePath}, RecursionType.None, null, LockLevel.CheckOut);
    }

I am suspecting that this has something to do with my TFS Workspace being local. However, Visual Studio 2015 seems to have no problem establishing a lock on the file via [Source Control Explorer]->[Right Click Selected File]->[Advanced]->[Lock]. What am I doing that's different than what VS is doing? Am I missing something?


Solution

  • After much trial and error I ended up implementing an event handler for NonFatalError like this:

    private static void VersionControlServer_NonFatalError(object sender, ExceptionEventArgs e)
        {
            if (e.Failure != null && e.Failure.Severity == SeverityType.Error)
                throw new ApplicationException("An internal TFS error occurred. See failure message for details:\r\n"+e.Failure.Message);
        }
    

    Once the event handler was hooked up to the versionControlServer object via versionControlServer.NonFatalError += VersionControlServer_NonFatalError; I was able to see what was going on with my exclusive check-outs. As it turned out, TFS was failing silently with the following error:

    TF400022: The item $/Fake/Server/Path/project.config cannot be locked for checkout in workspace MYWORKSPACE;Dan Lastname. Checkout locks are not supported in local workspaces.
    

    The solution was to change the LockLevel from LockLevel.CheckOut to LockLevel.Checkin. Its a slightly different type of lock but its sufficient for my needs and that's the type of lock VS is using when you attempt to lock a file in a local workspace. So here is my original function with the tiny change in LockLevel that made all the difference.

    public static void Lock(string filePath)
    {
        var workspace = GetWorkspace(filePath);
        workspace.PendEdit(new[] {filePath}, RecursionType.None, null, LockLevel.Checkin);
    }