我正在使用 TFS 2010 处理受源代码控制的文件的实用程序。
如果项目尚未签出以进行编辑,我会遇到异常,因为文件处于只读模式,所以这绝对是可预测的。
有哪些方法可以签出文件?
PS我想要一些程序化的东西,而不是Process.Start("tf.exe", "...");
如果适用的话。
我正在使用 TFS 2010 处理受源代码控制的文件的实用程序。
如果项目尚未签出以进行编辑,我会遇到异常,因为文件处于只读模式,所以这绝对是可预测的。
有哪些方法可以签出文件?
PS我想要一些程序化的东西,而不是Process.Start("tf.exe", "...");
如果适用的话。
此处提到的其他一些方法仅适用于某些版本的 TFS 或使用过时的方法。如果您收到 404,则您使用的方法可能与您的服务器版本不兼容。
这种方法适用于 2005、2008 和 2010。我不再使用 TFS,所以我没有测试 2013。
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(fileName);
using (var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri))
{
var workspace = workspaceInfo.GetWorkspace(server);
workspace.PendEdit(fileName);
}
private const string tfsServer = @"http://tfsserver.org:8080/tfs";
public void CheckOutFromTFS(string fileName)
{
using (TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(tfsServer)))
{
if (pc != null)
{
WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(fileName);
if (null != workspaceInfo)
{
Workspace workspace = workspaceInfo.GetWorkspace(pc);
workspace.PendEdit(fileName);
}
}
}
FileInfo fi = new FileInfo(fileName);
}
请注意,Microsoft.TeamFoundation.Client.TeamFoundationServerFactory
已过时:TeamFoundationServer
该类已过时。使用TeamFoundationProjectCollection
或TfsConfigurationServer
类与 2010 Team Foundation Server 通信。为了与 2005 或 2008 Team Foundation Server 通信,请使用TeamFoundationProjectCollection
该类。对应的工厂类是TfsTeamProjectCollectionFactory
.
您可以使用 Team Foundation 版本控制客户端 API。方法是PendEdit()
workspace.PendEdit(fileName);
查看 MSDN 上的详细示例 http://blogs.msdn.com/b/buckh/archive/2006/03/15/552288.aspx
首先获取工作空间
var tfs = new TeamFoundationServer("http://server:8080/tfs/collection");
var version = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
var workspace = version.GetWorkspace("WORKSPACE-NAME", version.AuthorizedUser);
使用工作区,您可以签出文件
workspace.PendEdit(fileName);
var registerdCollection = RegisteredTfsConnections.GetProjectCollections().First();
var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(registerdCollection);
var versionControl = projectCollection.GetService<VersionControlServer>();
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(_fileName);
var server = new TeamFoundationServer(workspaceInfo.ServerUri.ToString());
var workspace = workspaceInfo.GetWorkspace(server);
workspace.PendEdit(fileName);
我有两种方法可以做到这一点:简单和高级。
1)。简单的:
#region Check Out
public bool CheckOut(string path)
{
using (TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ConstTfsServerUri)))
{
if (pc == null) return false;
WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(path);
Workspace workspace = workspaceInfo?.GetWorkspace(pc);
return workspace?.PendEdit(path, RecursionType.Full) == 1;
}
}
public async Task<bool> CheckoutAsync(string path)
{
return await Task.Run(() => CheckOut(path));
}
#endregion
2)。高级(有接收状态):
private static string GetOwnerDisplayName(PendingSet[] pending)
{
var result = pending.FirstOrDefault(pendingSet => pendingSet.Computer != Environment.MachineName) ?? pending[0];
return result.OwnerDisplayName;
}
private string CheckoutFileInternal(string[] wsFiles, string folder = null)
{
try
{
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(folder);
var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
var workspace = workspaceInfo.GetWorkspace(server);
var request = new GetRequest(folder, RecursionType.Full, VersionSpec.Latest);
GetStatus status = workspace.Get(request, GetOptions.None);
int result = workspace.PendEdit(wsFiles, RecursionType.Full, null, LockLevel.None);
if (result == wsFiles.Length)
{
//TODO: write info (succeed) to log here - messageText
return null;
}
var pending = server.GetService<VersionControlServer>().QueryPendingSets(wsFiles, RecursionType.None, null, null);
var messageText = "Failed to checkout !.";
if (pending.Any())
{
messageText = string.Format("{0}\nFile is locked by {1}", messageText, GetOwnerDisplayName(pending));
}
//TODO: write error to log here - messageText
return messageText;
}
catch (Exception ex)
{
UIHelper.Instance.RunOnUiThread(() =>
{
MessageBox.Show(Application.Current.MainWindow, string.Format("Failed checking out TFS files : {0}", ex.Message), "Check-out from TFS",
MessageBoxButton.OK, MessageBoxImage.Error);
});
return null;
}
}
public async Task<string> CheckoutFileInternalAsync(string[] wsFiles, string folder)
{
return await Task.Run(() => CheckoutFileInternal(wsFiles, folder));
}