本码农最近开发一个VS扩展,其中有些功能涉及到文件的签出。我们公司用的是TFS,遇到了一些奇特的现象,将解决过程记录如下。
一、明明在线的连接却Offline属性等于True
public static Workspace GetWorkspace(string slnDir)
{ var projectCollections = new List<RegisteredProjectCollection>((RegisteredTfsConnections.GetProjectCollections()));
var onlineCollections = projectCollections.Where(c => !c.Offline).ToList(); // fail if there are no registered collections that are currently on-line
if (!onlineCollections.Any())
{
return null;
}
Workspace workspace = null;
// find a project collection with at least one team project
foreach (var registeredProjectCollection in onlineCollections)
{
var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(registeredProjectCollection);
projectCollection.EnsureAuthenticated();
var versionControl = (VersionControlServer)projectCollection.GetService(typeof(VersionControlServer));
var teamProjects = new List<TeamProject>(versionControl.GetAllTeamProjects(false));
// if there are no team projects in this collection, skip it
if (teamProjects.Count < ) continue; var dir = new DirectoryInfo(slnDir);
while (workspace == null)
{
workspace = versionControl.TryGetWorkspace(dir.FullName);
if (dir.Parent == null)
break;
dir = dir.Parent;
} if (workspace != null && workspace.HasUsePermission)
break;
}
return workspace;
}
现象就是上面这段代码中
var onlineCollections = projectCollections.Where(c => !c.Offline).ToList();
一句找不到想要的在线的TFS Server
首先尝试了删除Local AppData中(C:\Users\*\AppData\Local\Microsoft\Team Foundation)的Cache,不起作用。
然后找到注册表
HKEY_USERS\S-1-5-21-2532103873-3336248781-2863026242-1503\Software\Microsoft\VisualStudio\11.0\TeamFoundation\Instances\tfs.yintai.org\Collections\PlatformCollection
将此节点下Offline改为0
可以了。
原因不明,可能跟连接了多个TFS有关。
二、TryGetWorkspace方法找不到对应的Workspace
然后又遇到
workspace = versionControl.TryGetWorkspace(dir.FullName);
总是返回null
后改为使用QueryWorkspaces方法遍历所有workspace解决
将这段
var dir = new DirectoryInfo(slnDir);
while (workspace == null)
{
workspace = versionControl.TryGetWorkspace(dir.FullName);
if (dir.Parent == null)
break;
dir = dir.Parent;
}
替换为
try
{
Workspace[] workspaces = versionControl.QueryWorkspaces(null, Environment.UserName,
Environment.MachineName);
foreach (var ws in workspaces)
{
foreach (var folder in ws.Folders)
{
if (slnDir.StartsWith(folder.LocalItem))
{
workspace = ws;
break;
}
}
if (workspace != null && workspace.HasUsePermission)
break;
}
}
catch
{
continue;
}