所以我试图从TFS中的工作区中检索文件。不幸的是,我所做的每一次尝试都会导致应用程序停滞不前。截至目前,这是代码:
public void GetWorkspaceFiles(string workspaceName)
{
VersionControlServer sourceControl = (VersionControlServer)TfsServer.GetService(typeof(VersionControlServer));
var items = sourceControl.GetItems(workspaceName, VersionSpec.Latest, RecursionType.Full)
.Items
.Where(x => x.ItemType == ItemType.File)
.ToList();
for (int x = 0; x < items.Count; x++)
items[x].DownloadFile();
每次运行此应用程序(在多台计算机上)时,它会在items[x].DownloadFile()
上停止。 TFS中的所有文件都没有锁定,一切都很好。尝试使用Workspace.Get()
方法会产生相同的结果。
如果我点击暂停,x将是一个特定值,但我无法访问items集合,因为当我这样做时,我得到“无法计算表达式,因为当前线程处于休眠状态,等待或加入”。当我评估调用堆栈时,我得到:
[In a sleep, wait, or join]
[External Code]
GetWorkspaceFiles(string workspaceName) Line 55
我不知道该做些什么。每当我暂停应用程序时,x
总是处于相同的值(对于每个运行的应用程序,它停止的值都不同)。
有人有什么想法吗?
<小时/> 编辑:添加诊断逻辑后(基于Grant答案中的链接)我比以往更加困惑。
我传入此方法的工作区是$/QA/Automated Test Scripts/Regression or System Test Scripts/RDE or Condo
(通过调试器验证)。
然而,当我查看tfs日志时,它看起来正在下载我正在运行的代码文件,正如它所说:
02/10/2011 12:26:58 (pid 5808, tid 5968, 42180 ms) Recording OperationStatus.Getting for $/QA/Automated Test Scripts/QA Tools/Test Manager/Test Polling Server/fmMain.cs
在该条目之后:
02/10/2011 12:26:58 (pid 5808, tid 5968, 42180 ms) DownloadFiles: 18 ms
02/10/2011 12:26:58 (pid 5808, tid 5968, 42181 ms) Acknowledgements: 0 ms
之后,日志文件没有进一步的更新,我的应用程序停止了。我感到困惑的是
1)当我指定一个完全不同的TFS工作区时,为什么这会尝试从TFS中提取应用程序代码
2)为什么在尝试检索文件后停止?这可能是因为fmMain.cs
在Visual Studio中是打开的,但它仍然应该例外,并且不会挂起。当文件通过visual studio正常打开时,我能够获得最新信息。
<小时/> <小时/> EDIT2:
好的,所以我正在阅读MSDN,我注意到工作区名称可以是文件的本地路径。所以我将我作为workspaceName
参数传入的内容修改为文件的本地目录。我仍然得到档位,但日志文件不清楚原因。我已经上传了tf.log文件here(我显然已经更改了专有信息,例如服务器和项目名称,但其他一切都没有改动)。在最后一个日志条目之后,没有其他数据写入日志。
答案 0 :(得分:7)
GetItems不使用工作空间名称,它需要服务器路径来获取文件列表。如果你想从特定区域获取文件的副本,你想要做的是:
var items = sourceControl.GetItems("$/Project/Path/subpath"/et cetera", VersionSpec.Latest, RecursionType.Full)
.Items
.Where(x => x.ItemType == ItemType.File)
.ToList();
致电时
items[x].DownloadFile();
它会返回一个流,而不是实际将文件下载到磁盘。如果你想在那时将文件写入磁盘,你需要做普通的流处理工作来写出来。
如果你真的想把文件从TFS拿到工作区,那就有点不同了。
VersionControlServer sourceControl = coll.GetService<VersionControlServer>();
var ws = sourceControl.QueryWorkspaces(workspaceName, null, null);
var status = ws[0].Get();
(添加了错误处理需求)
这将使用服务器中的文件刷新工作区。它将像Visual Studio UI一样工作,因为它将比较当前磁盘上的内容与存储库中的内容,并且如果存在更新的版本,则会更新本地版本。
Get()方法有许多重载可用于指定您要查找的确切行为。
- 编辑 -
当您调用Workspace.Get()时,它首先要做的是转到TFS(使用Web服务调用)并获取文件列表。然后,它遍历这些文件,将您已在该工作区中“获取”的内容与您请求的修订版本进行比较(或者如果您未指定任何其他修订版本,则为VersionSpec.Latest)。
此过程可能需要一段时间。这就像右键单击并获取工作区中每个映射目录的最新信息。
如果您的工作区已映射到$/
,它将遍历TFS中的所有文件。如果您有多个到本地路径的路径映射,它将遍历每个路径,它将在本地检索并保存您尚未获得的任何文件。
刷新整个工作区可能需要很长时间,除非您对所映射的内容保持谨慎。
- 编辑2 -
如果你想限制你得到的东西,你有两个选择。第一个选项是限制您正在访问的工作空间内的映射。例如,如果您的工作区只有一个映射到$/Project/Branch/Source/Utilities/MyUtility
,则只会获取该映射中的文件。
在我们的几家内部公用事业公司,我们甚至可以做到:
如果您只是尝试自动刷新一组文件,那么这是很多工作,所以您可以做的是传递Get()
方法的路径:
var status = ws[0].Get(new GetRequest("$/path/to/subfolder", RecursionType.Full, VersionSpec.Latest),
GetOptions.Overwrite);
答案 1 :(得分:2)
使用TFS命令行工具时,相同的命令/参数是否有效?例如TF.exe get
?
您是否安装了任何防病毒软件?是否有可能阻碍它?尝试暂时禁用它。
您还可以在app.config中启用TFS客户端跟踪,以查看网络上的内容: http://blogs.msdn.com/b/edhintz/archive/2007/03/30/tfs-client-tracing.aspx
答案 2 :(得分:0)
以下是使用该示例的工作示例,您可以从服务器路径
获取最新版本的代码var status = workspace.Get(new GetRequest("$/XXXX/Development/Subfolder/",
RecursionType.Full, VersionSpec.Latest),
GetOptions.GetAll| GetOptions.Overwrite);