C# 如何使用 Team Foundation Server SDK 获取最新版本的源代码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1827651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you get the latest version of source code using the Team Foundation Server SDK?
提问by John Rasch
I'm attempting to pull the latest version of source code out of TFS programmatically using the SDK, and what I've done somehow does not work:
我正在尝试使用 SDK 以编程方式从 TFS 中提取最新版本的源代码,但我所做的以某种方式不起作用:
string workspaceName = "MyWorkspace";
string projectPath = "/TestApp";
string workingDirectory = "C:\Projects\Test\TestApp";
VersionControlServer sourceControl; // actually instantiated before this method...
Workspace[] workspaces = sourceControl.QueryWorkspaces(workspaceName, sourceControl.AuthenticatedUser, Workstation.Current.Name);
if (workspaces.Length > 0)
{
sourceControl.DeleteWorkspace(workspaceName, sourceControl.AuthenticatedUser);
}
Workspace workspace = sourceControl.CreateWorkspace(workspaceName, sourceControl.AuthenticatedUser, "Temporary Workspace");
try
{
workspace.Map(projectPath, workingDirectory);
GetRequest request = new GetRequest(new ItemSpec(projectPath, RecursionType.Full), VersionSpec.Latest);
GetStatus status = workspace.Get(request, GetOptions.GetAll | GetOptions.Overwrite); // this line doesn't do anything - no failures or errors
}
finally
{
if (workspace != null)
{
workspace.Delete();
}
}
The approach is basically creating a temporary workspace, using the Get()
method to grab all the items for this project, and then removing the workspace. Is this the correct way to do this? Any examples would be helpful.
该方法基本上是创建一个临时工作区,使用该Get()
方法抓取该项目的所有项,然后删除该工作区。这是正确的方法吗?任何示例都会有所帮助。
回答by joerage
Your approach is valid.
你的方法是有效的。
Your error is in your project path. Use something like this instead:
您的错误在您的项目路径中。使用类似这样的东西:
string projectPath = "$/PathToApp/TestApp";
回答by Richard Berg
I agree with Joerage that your server path is probably the culprit. To get more insight into what's happening, you need to wire up some events on the VersionControlServer object. At minimum you'll want Getting, NonFatalError, and Conflict.
我同意乔拉奇的观点,你的服务器路径可能是罪魁祸首。为了更深入地了解正在发生的事情,您需要在 VersionControlServer 对象上连接一些事件。至少,您需要 Getting、NonFatalError 和 Conflict。
Complete list: http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.versioncontrolserver_events(VS.80).aspx
完整列表:http: //msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.versioncontrolserver_events(VS.80).aspx
回答by John Rasch
I ended up using a different approach that seems to work, mainly taking advantage of the Item.DownloadFile()
method:
我最终使用了一种似乎有效的不同方法,主要是利用该Item.DownloadFile()
方法:
VersionControlServer sourceControl; // actually instantiated...
ItemSet items = sourceControl.GetItems(sourcePath, VersionSpec.Latest, RecursionType.Full);
foreach (Item item in items.Items)
{
// build relative path
string relativePath = BuildRelativePath(sourcePath, item.ServerItem);
switch (item.ItemType)
{
case ItemType.Any:
throw new ArgumentOutOfRangeException("ItemType returned was Any; expected File or Folder.");
case ItemType.File:
item.DownloadFile(Path.Combine(targetPath, relativePath));
break;
case ItemType.Folder:
Directory.CreateDirectory(Path.Combine(targetPath, relativePath));
break;
}
}
回答by Stefan
I completed and implemented the code into a button as web asp.net solution.
我完成了代码并将其实现为一个按钮作为 web asp.net 解决方案。
For the project to work in the references should be added the Microsoft.TeamFoundation.Client
and Microsoft.TeamFoundation.VersionControl.Client
references and in the code the statements using Microsoft.TeamFoundation.Client;
and using Microsoft.TeamFoundation.VersionControl.Client;
对于在引用中工作的项目,应该添加Microsoft.TeamFoundation.Client
和Microsoft.TeamFoundation.VersionControl.Client
引用,并在代码中添加语句using Microsoft.TeamFoundation.Client;
和using Microsoft.TeamFoundation.VersionControl.Client;
protected void Button1_Click(object sender, EventArgs e)
{
string workspaceName = "MyWorkspace";
string projectPath = @"$/TeamProject"; // the container Project (like a tabel in sql/ or like a folder) containing the projects sources in a collection (like a database in sql/ or also like a folder) from TFS
string workingDirectory = @"D:\New1"; // local folder where to save projects sources
TeamFoundationServer tfs = new TeamFoundationServer("http://test-server:8080/tfs/CollectionName", System.Net.CredentialCache.DefaultCredentials);
// tfs server url including the Collection Name -- CollectionName as the existing name of the collection from the tfs server
tfs.EnsureAuthenticated();
VersionControlServer sourceControl = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
Workspace[] workspaces = sourceControl.QueryWorkspaces(workspaceName, sourceControl.AuthenticatedUser, Workstation.Current.Name);
if (workspaces.Length > 0)
{
sourceControl.DeleteWorkspace(workspaceName, sourceControl.AuthenticatedUser);
}
Workspace workspace = sourceControl.CreateWorkspace(workspaceName, sourceControl.AuthenticatedUser, "Temporary Workspace");
try
{
workspace.Map(projectPath, workingDirectory);
GetRequest request = new GetRequest(new ItemSpec(projectPath, RecursionType.Full), VersionSpec.Latest);
GetStatus status = workspace.Get(request, GetOptions.GetAll | GetOptions.Overwrite); // this line doesn't do anything - no failures or errors
}
finally
{
if (workspace != null)
{
workspace.Delete();
Label1.Text = "The Projects have been brought into the Folder " + workingDirectory;
}
}
}
回答by Sourav Kundu
I had a similar situation where I needed to download contents of 'a' folder from tfs into an existing workspace, without creating a new workspace. With help from the above answers, I was able to put something together that works fine for me as of now. There is however a limitation. This works for contents of 'a' folder with just files and not another folder inside it -I have not tried that out. Maybe that would involve some minor updates. Sharing code, just in case someone is searching for this. I really like the fact that this approach does not deal with workspace [-create and delete], since that is not desired.
我遇到了类似的情况,我需要将 'a' 文件夹中的内容从 tfs 下载到现有工作区,而无需创建新工作区。在上述答案的帮助下,我能够将一些目前对我来说效果很好的东西放在一起。但是有一个限制。这适用于“a”文件夹中只有文件而不是其中的另一个文件夹的内容 - 我还没有尝试过。也许这会涉及一些小的更新。共享代码,以防万一有人正在搜索。我真的很喜欢这种方法不处理工作区 [ -create 和 delete]的事实,因为这是不希望的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Configuration;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Client;
using System.IO;
namespace DownloadFolder
{
class Program
{
static void Main(string[] args)
{
string teamProjectCollectionUrl = "http://<YourTFSUrl>:8080/tfs/DefaultCollection"; // Get the version control server
TfsTeamProjectCollection teamProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(teamProjectCollectionUrl));
VersionControlServer vcs = teamProjectCollection.GetService<VersionControlServer>();
String Sourcepath = args[0]; // The folder path in TFS - "$/<TeamProject>/<FirstLevelFolder>/<SecondLevelFolder>"
String DestinationPath = args[1]; //The folder in local machine - "C:\MyTempFolder"
ItemSet items = vcs.GetItems(Sourcepath, VersionSpec.Latest, RecursionType.Full);
String FolderName = null;
foreach (Item item in items.Items)
{
String ItemName = Path.GetFileName(item.ServerItem);
switch (item.ItemType)
{
case ItemType.File:
item.DownloadFile(Path.Combine(DestinationPath, FolderName, ItemName));
break;
case ItemType.Folder:
FolderName = Path.GetFileName(item.ServerItem);
Directory.CreateDirectory(Path.Combine(DestinationPath, ItemName));
break;
}
}
}
}
}
While running this from the command prompt copy all the supporting dlls along with exe
cmd>> DownloadFolder.exe "$/<TeamProject>/<FirstLevelFolder>/<SecondLevelFolder>" "C:\MyTempFolder"
从命令提示符运行它时,复制所有支持的 dll 以及 exe cmd>> DownloadFolder.exe "$/<TeamProject>/<FirstLevelFolder>/<SecondLevelFolder>" "C:\MyTempFolder"