本码农最近开发一个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 < 1) 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; }