I have been trying to figure out how is possible to create a query folder via VSO api, but I always the "Method not allowed" message.
I'm using Microsoft.TeamFoundationServer.Client package to connect VSO. This page says that this library is needed for me. I can query data, but it seems something is missing to create data. This library is fit for me because I have a WebApi whihch manages the communication to VSO API.
Here is my code:
public QueryHierarchyItem CreateFolderAsync(string folderName)
{
QueryHierarchyItem newFolder = new QueryHierarchyItem()
{
Name = folderName,
IsFolder = true,
//Path = "Queries/Shared Queries/" + folderName,
IsPublic = true
};
QueryHierarchyItem item = witClient.CreateQueryAsync(newFolder, _projectName, null).Result;
return item;
}
I have tried to play with the Path property but it did not help.
I have checked the user rights. My user is member of "Project Administrators", and
rights are also set up to manage query folders (Click the chevron next to the "Shared Queries" folder -> select "Security") as group and as single user. It did not help.
I use a free account. The strange is that I have logged in with the same user from Visual Studio and I can manage the folders. Is this functionality available for free accounts?
You can refer to this blog from MSDN for details: http://blogs.msdn.com/b/team_foundation/archive/2010/06/16/work-item-tracking-queries-object-model-in-2010.aspx
Quote the code here:
using System;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
namespace QueryAPI
{
class Program
{
private static Project myproject = null;
public static QueryFolder GetMyQueriesFolder()
{
foreach (QueryFolder folder in myproject.QueryHierarchy)
{
if (folder.IsPersonal == true)
return folder;
}
throw new Exception("Cannot find the My Queries folder");
}
public static QueryFolder AddNewFolder(string folderName)
{
QueryFolder folder = new QueryFolder(folderName, GetMyQueriesFolder());
myproject.QueryHierarchy.Save();
return folder;
}
static void Main(string[] args)
{
TfsTeamProjectCollection coll = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("Your TFS Server URI"));
WorkItemStore store = new WorkItemStore(coll);
myproject = store.Projects["Your project name"];
QueryFolder myNewfolder = AddNewFolder("Your folder name");
}
}
}
Related
i want to Upload a folder recursivly to an azure-files storage.
The file structure usually has several subfolders.
What is the best way to create the subfolders in azure-files?
foreach (string fullLocalFilename in System.IO.Directory.GetFiles(locationOfFolderToUpload, "*.*", System.IO.SearchOption.AllDirectories))
{
Console.WriteLine(fullLocalFilename);
FileInfo localfile = new FileInfo(fullLocalFilename);
var root = share.GetRootDirectoryReference();
string strPfad = localfile.DirectoryName.Substring(3);
var folder = root.GetDirectoryReference(strPfad);
Console.WriteLine(strPfad);
folder.CreateIfNotExists();
CloudFile file = folder.GetFileReference(localfile.Name);
if (file.Exists() == false) {
file.Create(localfile.Length);
file.UploadFromFile(fullLocalFilename);
Console.WriteLine(fullLocalFilename);
}
}
WebException: The remote server returned an error: (404) Not found.
I suggest you make use of Microsoft.Azure.Storage.DataMovement, it supports uploading directory to azure as well create the same structure like in local path. Please install the latest version 1.0.0 of Microsoft.Azure.Storage.DataMovement here. Note that if you have installed other azure storage sdk, please uninstall them first.
For example, if I have a local folder like below:
Use the code below:
using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Azure.Storage.DataMovement;
using Microsoft.Azure.Storage.File;
namespace AzureDataMovementTest
{
class Program
{
static void Main(string[] args)
{
string storageConnectionString = "xxxx";
CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);
CloudFileClient fileClient = account.CreateCloudFileClient();
CloudFileShare fileShare = fileClient.GetShareReference("t22");
fileShare.CreateIfNotExists();
CloudFileDirectory fileDirectory= fileShare.GetRootDirectoryReference();
//here, I want to upload all the files and subfolders in the follow path.
string source_path = #"F:\temp\1";
//if I want to upload the folder 1, then use the following code to create a file directory in azure.
CloudFileDirectory fileDirectory_2 = fileDirectory.GetDirectoryReference("1");
fileDirectory_2.CreateIfNotExists();
UploadDirectoryOptions directoryOptions = new UploadDirectoryOptions
{
Recursive = true
};
var task = TransferManager.UploadDirectoryAsync(source_path,fileDirectory_2,directoryOptions,null);
task.Wait();
Console.WriteLine("the upload is completed");
Console.ReadLine();
}
}
}
After the code completes running, nav to azure portal -> file storage:
Please let me know if you have more issues.
I want to use the Teamfoundation.SourceControl.WebApi to check for updates or local changes against our TFS Source Control.
I can gather information about changesets from an item which is committed TFS but I am not able to gather this information based on a local file path inside my mapped workspace.
Is it somehow possible without using the ExtendedClient?
I want something like this:
TfvcChangesetSearchCriteria tcsc = new TfvcChangesetSearchCriteria();
tcsc.ItemPath = #"c:\source\mappedtfs\MYPROJECT\src\MainWindow.cs";/*<--- localPath would be nice here*/
List<TfvcChangesetRef> changerefs = tfvcHttpClient.GetChangesetsAsync("MYPROJECT", null, null, null, null, tcsc).Result;
Microsoft.Teamfoundation.SourceControl.WebApi is a webapi which does not interact with local workspaces and files. If you want to get changesets with local items' path, use Microsoft.TeamFoundation.VersionControl.Client in the Client Library.
using Microsoft.TeamFoundation.Client;
using System;
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.TeamFoundation.VersionControl.Client;
using System.Collections.Generic;
namespace ConsoleX
{
class Program
{
static void Main(string[] args)
{
Uri url = new Uri("https://tfsuri");
TfsTeamProjectCollection ttpc = new TfsTeamProjectCollection(url);
VersionControlServer vcs = ttpc.GetService<VersionControlServer>();
IEnumerable<Changeset> cses = vcs.QueryHistory("Path here could be local path or server path", RecursionType.Full);
foreach (Changeset cs in cses)
{
Console.WriteLine(cs.ChangesetId);
Console.WriteLine(cs.Comment);
}
Console.ReadLine();
}
}
}
public ActionResult Connect()
{
List<string> Collected = new List<string>(10);
Uri configurationServerUri = new Uri("xxxxxxtfsurl");
TfsConfigurationServer configurationServer =
TfsConfigurationServerFactory.GetConfigurationServer
(configurationServerUri);
ITeamProjectCollectionService tpcService =
configurationServer.GetService<ITeamProjectCollectionService>();
foreach (TeamProjectCollection tpc in
tpcService.GetCollections())
{
Collected.Add(tpc.Name);
}
ViewBag.List = Collected;
return PartialView();
}
I retrieved the collection using controller in MVC but can any one help me to retrieve the projects from specific collection
If you just want to retrieve the team projects from specific collection, then you can use below code sample:
Install Nuget package Microsoft.TeamFoundationServer.ExtendedClient.
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Client;
class Program
{
static void Main(string[] args)
{
string collection = #"http://ictfs2015:8080/tfs/DefaultCollection";
TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(TfsTeamProjectCollection.GetFullyQualifiedUriForName(collection));
tfs.EnsureAuthenticated();
VersionControlServer vcs = tfs.GetService<VersionControlServer>();
TeamProject[] teamProjects = vcs.GetAllTeamProjects(true);
foreach (TeamProject proj in teamProjects)
{
System.Console.WriteLine(string.Format("Team Project: {0}", proj.Name));
}
System.Console.ReadLine();
}
}
If you want to retrieve all the collections and their team projects, then you can try below code sample:
using System;
using System.Collections.ObjectModel;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Framework.Client;
namespace GetProjectList
{
class Program
{
static void Main(String[] args)
{
// Connect to Team Foundation Server
// Server is the name of the server that is running the application tier for Team Foundation.
// Port is the port that Team Foundation uses. The default port is 8080.
// VDir is the virtual path to the Team Foundation application. The default path is tfs.
Uri tfsUri = (args.Length < 1) ?
new Uri("http://ictfs2015:8080/tfs") : new Uri(args[0]);
TfsConfigurationServer configurationServer =
TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
// Get the catalog of team project collections
ReadOnlyCollection<CatalogNode> collectionNodes = configurationServer.CatalogNode.QueryChildren(
new[] { CatalogResourceTypes.ProjectCollection },
false, CatalogQueryOptions.None);
// List the team project collections
foreach (CatalogNode collectionNode in collectionNodes)
{
// Use the InstanceId property to get the team project collection
Guid collectionId = new Guid(collectionNode.Resource.Properties["InstanceId"]);
TfsTeamProjectCollection teamProjectCollection = configurationServer.GetTeamProjectCollection(collectionId);
// Print the name of the team project collection
Console.WriteLine("Collection: " + teamProjectCollection.Name);
// Get a catalog of team projects for the collection
ReadOnlyCollection<CatalogNode> projectNodes = collectionNode.QueryChildren(
new[] { CatalogResourceTypes.TeamProject },
false, CatalogQueryOptions.None);
// List the team projects in the collection
foreach (CatalogNode projectNode in projectNodes)
{
Console.WriteLine(" Team Project: " + projectNode.Resource.DisplayName);
}
}
// Display the project list on cosole window
Console.ReadLine();
}
}
}
Our company recently updated TFS to 2015 update 1. After that context menu item named Drop folder disappeared from completed builds. I found nothing about it and how to bring it back. When I click Open on completed build, VS opens web version of TFS where I forced to click through the menus and copy drop folder path manually. So I decided to write a simple extension that will add this item to the menu.
Some googling brought me to this page. But it seems that the example code is quite old and not working in VS2015:
IVsTeamFoundationBuild vsTfBuild = (IVsTeamFoundationBuild)GetService(typeof(IVsTeamFoundationBuild));
IBuildDetail[] builds = vsTfBuild.BuildExplorer.CompletedView.SelectedBuilds;
Property SelectedBuilds is always empty. I suppose that it relates to old window from VS2010. It returns items that are instance of IBuildDetail interface.
So I found this piece of code here:
var teamExplorer = (ITeamExplorer)ServiceProvider.GetService(typeof(ITeamExplorer));
var page = teamExplorer.CurrentPage;
var buildsPageExt = (IBuildsPageExt)page.GetExtensibilityService(typeof(IBuildsPageExt));
var build = buildsPageExt.SelectedBuilds[0];
Here build is the instance of IBuildModel interface. It lacks DropLocation property.
Is there any way to found drop location of selected build? Or maybe latest build?
You can use IBuildDedetail.DropLocation in .NET client libraries for Visual Studio Team Services (and TFS). Basic code for your reference:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
namespace BuildAPI
{
class Program
{
static void Main(string[] args)
{
string project = "http://xxx.xxx.xxx.xxx";
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(project));
IBuildServer ibs = tpc.GetService<IBuildServer>();
var builds = ibs.QueryBuilds("TeamProjectName");
foreach (IBuildDetail ibd in builds)
{
Console.WriteLine(ibd.DropLocation);
Console.ReadLine();
}
}
}
}
So, after digging through TFS API, I ended up with this workaround.
private void MenuItemCallback(object sender, EventArgs e)
{
var context = (ITeamFoundationContextManager)ServiceProvider.GetService(typeof(ITeamFoundationContextManager));
IBuildServer buildServer = context.CurrentContext.TeamProjectCollection.GetService<IBuildServer>();
var teamExplorer = (ITeamExplorer)ServiceProvider.GetService(typeof(ITeamExplorer));
var buildsPageExt = (IBuildsPageExt)teamExplorer.CurrentPage.GetExtensibilityService(typeof(IBuildsPageExt));
var menuCommand = (MenuCommand)sender;
if (menuCommand.CommandID.Guid == CommandSetCompleted)
{
foreach (var buildDetail in buildsPageExt.SelectedBuilds)
Process.Start("explorer.exe", GetBuild(buildServer, buildDetail).DropLocation);
}
if (menuCommand.CommandID.Guid == CommandSetFavorite)
{
var definitions = buildsPageExt.SelectedFavoriteDefinitions.Concat(buildsPageExt.SelectedXamlDefinitions).ToArray();
foreach (var build in GetLatestSuccessfulBuild(buildServer, definitions))
Process.Start("explorer.exe", build.DropLocation);
}
}
private IBuildDetail GetBuild(IBuildServer buildServer, IBuildModel buildModel)
{
Uri buildUri = new Uri(buildModel.GetType().GetProperty("UriToOpen").GetValue(buildModel).ToString());
return buildServer.GetBuild(buildUri);
}
private IBuildDetail[] GetLatestSuccessfulBuild(IBuildServer buildServer, IDefinitionModel[] buildDefinitions)
{
var spec = buildServer.CreateBuildDetailSpec(buildDefinitions.Select(bd => bd.Uri));
spec.MaxBuildsPerDefinition = 1;
spec.QueryOrder = BuildQueryOrder.FinishTimeDescending;
spec.Status = BuildStatus.Succeeded;
var builds = buildServer.QueryBuilds(spec);
return builds.Builds;
}
I want to automate testing of newly created build agents in TFS.
Now, I have written code to queue builds of particular build definition on TFS.
Problem I am facing is to queue build definition on agents of given controller.
Previously there was one method which I've commented in my code
for doing this, i.e. IbuildRequest.buildagent, but now it has been deprecated in newer tfs api.
Edit:
I have already tested IbuildRequest.BuildController property which tends to randomly pick agent, which is currently free.
What I want to know is can I force build definition to use one build Agent using tfs api.
using System;
using System.Linq;
using System.Security.Principal;
using System.Collections.Generic;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
namespace BuildAgentsTestApp
{
class Program
{
static void Main(string[] args)
{
Uri collectionURI = new Uri("https://tfs-uri");
var tfsCreds = new TfsClientCredentials(new WindowsCredential(), true);
TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(collectionURI,tfsCreds);
WindowsIdentity user = WindowsIdentity.GetCurrent();
tfs.EnsureAuthenticated();
if (tfs.HasAuthenticated)
{
WorkItemStore workItemStore = tfs.GetService<WorkItemStore>();
Project teamProject = workItemStore.Projects["myProjectName"];
IBuildServer buildServer = (IBuildServer)tfs.GetService(typeof(IBuildServer));
IBuildDefinition buildDef = buildServer.GetBuildDefinition(teamProject.Name, "myBuildDefinitionName");
var controller = GetRequestedController(buildServer, "myControllerName");
var AgentsList = GetAgentCollection(controller);
//Queue each build definition
IBuildRequest buildRequest = buildDef.CreateBuildRequest();
buildRequest.GetOption = GetOption.Custom;
//buildRequest.BuildAgent = AgentsList.First();
buildServer.QueueBuild(buildRequest);
}
Console.WriteLine("Build Queued!");
Console.ReadKey();
}
static IBuildController GetRequestedController(IBuildServer reqBuildServer, string reqControllerName)
{
var requiredController = reqBuildServer.QueryBuildControllers()
.Where(ctrl =>
ctrl.Name == reqControllerName
).FirstOrDefault();
return requiredController;
}
static List<IBuildAgent> GetAgentCollection(IBuildController controller)
{
var ListOfAgents = from agent in controller.Agents
select agent;
return ListOfAgents.ToList();
}
}
}