3
votes

Using TFS 2015 update 2, an agent was installed in a machine, the agent creates its workspace:

enter image description here

Some custom MSBuild tasks developed InHouse were implemented in the build definition that will run on the agent. Those tasks perform some operations against the TFS server.

When the build definition is queued for a new build here is what I got:

enter image description here

In the build machine I proceed to run the following script, in order to verify the existence of the workspace :

# Script to find a Team Foundation workspace
param(
    [string] $workspaceHint = $(get-location).Path
)

begin
{
    # load the needed client dll's
    [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
    [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.VersionControl.Client")

    # fetches a Workspace instance matching the WorkspaceInfo found in the cache file
    function getWorkspaceFromWorkspaceInfo($wsInfo)
    {
        $tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($wsInfo.ServerUri.AbsoluteUri)
        $vcs = $tfs.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
        $vcs.GetWorkspace($wsInfo)
        # TODO: likely add some convenience properties/methods for easier scripting support
    }
}

process
{
    # is there only 1 workspace in our cache file?  If so, use that one regardless of the hint
    $workspaceInfos = [Microsoft.TeamFoundation.VersionControl.Client.Workstation]::Current.GetAllLocalWorkspaceInfo()
    if ($workspaceInfos.Length -eq 1)
    {
        return getWorkspaceFromWorkspaceInfo($workspaceInfos[0])
    }

    if (test-path $workspaceHint)
    {
        # workspace hint is a local path, get potential matches based on path
        $workspaceInfos = [Microsoft.TeamFoundation.VersionControl.Client.Workstation]::Current.GetLocalWorkspaceInfoRecursively($workspaceHint)
    }
    else
    {
        # workspace hint is NOT a local path, get potential matches based on name
        $workspaceInfos = @($workspaceInfos | ?{ $_.name -match $workspaceHint })
    }

    if ($workspaceInfos.Length -gt 1)
    {
        throw 'More than one workspace matches the workspace hint "{0}": {1}' -f
                $workspaceHint, [string]::join(', ', @($workspaceInfos | %{ $_.Name}))
    }
    elseif ($workspaceInfos.Length -eq 1)
    {
        return getWorkspaceFromWorkspaceInfo($workspaceInfos[0])
    }
    else
    {
        throw "Could not figure out a workspace based on hint $workspaceHint"
    }
}

The script is not able to find any workspace.

Then, the TFS 2015 Power tools were installed with its powershell cmdlets in the machine and run the following script:

if ( (Get-PSSnapin -Name Microsoft.TeamFoundation.PowerShell -ErrorAction SilentlyContinue) -eq $null )
        {
            Add-PSSnapin -Name Microsoft.TeamFoundation.PowerShell
        }
$ws = Get-TfsWorkspace -Path C:\t\1\s 

$ws.Folders

Showing the workspace and the items mapped.

Queuing new builds, keep showing the same error. The workspace is a public server one, and following some ancient post in msdn forums, I clean the TFS cache in the machine.

Any clue how to make the Microsoft.TeamFoundation.VersionControl.Client be able to recognize the workspace?

3
The error tells that there's no working folder mapping "C:\t\1\s", did you check on your build agent, if there any workspaces created on it? It seems that there's no workspace which map the path "C:\t\1\s". First check if the build agent server has any workspaces(you could run the tf workspaces command on build agent machine). Then check each workspace, if there any mappings about "C:\t\1\s ". You could use tf workfold command to check each workspace's mappings.Tingting0929
Thanks for your comments, I know that my post is TL;DR. But as I state in the post: The workspace was created, also the its mapping.XtianGIS
Did you test the code in build agent server manually not using TFS? If still can't get that workspace. Could you please try use vcs.GetWorkspace(string localPath) this method to get that workspace without using workspace info.Tingting0929
Yes I did it, it does not appear thereXtianGIS

3 Answers

4
votes

I fixed the ItemNotMappedException problem on my machine by running something like the following PowerShell script;

$localReference = "C:\Repository\Project\Project.sln"
$teamProjectCollection="http://tfsserver:8080/tfs/projectcollection"
$username = $env:UserName


Add-type -AssemblyName "Microsoft.TeamFoundation.Client, Version=12.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
Add-type -AssemblyName "Microsoft.TeamFoundation.Common, Version=12.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
Add-type -AssemblyName "Microsoft.TeamFoundation.VersionControl.Client, Version=12.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
Add-type -AssemblyName "Microsoft.TeamFoundation.VersionControl.Common, Version=12.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"

$folder = [System.IO.Path]::GetDirectoryName($localReference);
Push-Location $folder;

$tfsTeamProjectCollection = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection($teamProjectCollection)
$versioncontrolServer = $tfsTeamProjectCollection.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
[Microsoft.TeamFoundation.VersionControl.Client.Workstation]::Current.EnsureUpdateWorkspaceInfoCache($versionControlServer, $username); 
$workspace = $versioncontrolServer.GetWorkspace($localReference)
echo $workspace

Pop-Location 

You will need to change the initial variables to match your environment.

Hope it helps

2
votes

Recently I ran into a similar issue where it was throwing the error saying "There is no working folder mapping for 'Mapped path'"

Tried using below command to get the workspace path.

tf workspaces /format:detailed /owner:UserName /collection:http://TFSurl:8080/tfs

Mapping seemed to be fine.

using Workstation.EnsureUpdateWorkspaceInfoCache worked with like a gem.

Use the following link for sample code: How to call GetWorkspace in TFS properly?

-1
votes

Please add the Microsoft.TeamFoundation.Common assembly in your script and try again.

 # load the needed client dll's
        [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")    
        [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Common")
        [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.VersionControl.Client")