Is it possible to rollback a changeset using Microsoft.TeamFoundation.SourceControl.WebApi? - azure-devops

Following code try to rollback a changeset using Microsoft.TeamFoundation.SourceControl.WebApi. But "The specified change type Rollback is not supported." is raised when calling CreateChangesetAsync. Is this a limitation of Microsoft.TeamFoundation.SourceControl.WebApi? Or I did something wrong?
using System;
using System.Collections.Generic;
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.Client;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
namespace RestRollBackInTFS
{
class Program
{
static void Main(string[] args)
{
const String collectionUri = #"https://myTfs.visualstudio.com/";
VssConnection connection = new VssConnection(new Uri(collectionUri),
new VssClientCredentials()
);
TfvcHttpClient tfsClient = connection.GetClient<TfvcHttpClient>();
int changeSetIdToRollBack = 11651;
var changeSet = tfsClient.GetChangesetAsync(changeSetIdToRollBack, maxChangeCount: 10, includeDetails: true).Result;
foreach (var c in changeSet.Changes)
{
c.ChangeType = VersionControlChangeType.Rollback;
}
TfvcChangeset newC = new TfvcChangeset();
newC.Changes = new List<TfvcChange>(changeSet.Changes);
var ret = tfsClient.CreateChangesetAsync(newC).Result;
}
}
}

Related

TFS 2013 work item change event listener is not working

I'm trying to listen workitem changes in TFS 2013. I created a c# project and build successfully this code below. Then dll located in tfs server:
I restart machine and I checkin a class in tfs for test with a work item. When I control tfs server there is no any Log folder created in C disk like code. TfsEventHandler project builded with .net framework 4.5
My queston is, why plugin is not working?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.Common;
using Microsoft.TeamFoundation.Framework.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Server;
using System.Diagnostics;
using System.IO;
namespace TfsEventHandler
{
public class WorkItemChangedEventHandler : ISubscriber
{
public string Name
{
get
{
return "WorkItemChangedEventHandler";
}
}
public SubscriberPriority Priority
{
get
{
return SubscriberPriority.Normal;
}
}
public EventNotificationStatus ProcessEvent(
TeamFoundationRequestContext requestContext,
NotificationType notificationType,
object notificationEventArgs,
out int statusCode,
out string statusMessage,
out Microsoft.TeamFoundation.Common.ExceptionPropertyCollection properties)
{
statusCode = 0;
properties = null;
statusMessage = String.Empty;
WriteLog("WorkItemChangedEventHandler1");
try
{
if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
{
WorkItemChangedEvent ev = notificationEventArgs as WorkItemChangedEvent;
int workItemId = Convert.ToInt32(ev.CoreFields.IntegerFields[0].NewValue);
WriteLog("WorkItemChangedEventHandler WorkItem " + ev.WorkItemTitle + " - Id " + workItemId.ToString() + " was modified");
EventLog.WriteEntry("WorkItemChangedEventHandler", "WorkItem " + ev.WorkItemTitle + " - Id " + workItemId.ToString() + " was modified");
}
}
catch (Exception)
{
}
return EventNotificationStatus.ActionPermitted;
}
public Type[] SubscribedTypes()
{
return new Type[] { typeof(WorkItemChangedEvent) };
}
public static void WriteLog(string strLog)
{
StreamWriter log;
FileStream fileStream = null;
DirectoryInfo logDirInfo = null;
FileInfo logFileInfo;
string logFilePath = "C:\\Logs\\";
logFilePath = logFilePath + "Log-" + System.DateTime.Today.ToString("MM-dd-yyyy") + "." + "txt";
logFileInfo = new FileInfo(logFilePath);
logDirInfo = new DirectoryInfo(logFileInfo.DirectoryName);
if (!logDirInfo.Exists) logDirInfo.Create();
if (!logFileInfo.Exists)
{
fileStream = logFileInfo.Create();
}
else
{
fileStream = new FileStream(logFilePath, FileMode.Append);
}
log = new StreamWriter(fileStream);
log.WriteLine(strLog);
log.Close();
}
}
}

Npgsql Performance

I am trying to implement Npgsql in our DAL and running into issues under heavy load. the following sample application is a decent representation of just a simple query that under heavy load, throws a 'A command is already in progress' exception. I am assuming this is due to the lack of MARS support so I also tried creating a connection each time with a using statement around each command only to have the performance become unusable. I checked that the username is indexed so that shouldn't be an issue.
Not sure what I am doing wrong here but I need some advice on how to get this performing well.
OS: Docker Container: microsoft/dotnet:2.1.301-sdk
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;
namespace npgsqlTest
{
class Program
{
static async Task Main(string[] args)
{
DAL dal = new DAL();
dal.Prepare();
var tasks = dal.Users.Select(async user =>
{
Console.WriteLine(await dal.RunTest(user));
});
await Task.WhenAll(tasks);
}
}
public class DAL
{
private static string _ConnectionString;
private NpgsqlConnection _Connection;
public List<string> Users { get; set; } = new List<string>();
public DAL()
{
_ConnectionString = $"Host=192.168.1.1;Username=admin;Port=5432;Password=password;Database=BigDB;";
_Connection = new NpgsqlConnection(_ConnectionString);
_Connection.Open();
}
public void Prepare()
{
string query = "SELECT username FROM usertable;";
using (var cmd = new NpgsqlCommand(query, _Connection))
{
var reader = cmd.ExecuteReader();
using (reader)
{
while (reader.Read())
{
Users.Add(reader[0].ToString());
}
}
}
}
public async Task<string> RunTest(string user)
{
var parameters = new Dictionary<string, Object> { { "username", user } };
var query = $"SELECT name FROM usertable WHERE username = (#username);";
var reader = await QueryAsync(query, parameters);
using (reader)
{
if (reader.HasRows)
{
while (await reader.ReadAsync())
{
var name = reader["name"];
if (!(hash is DBNull))
return (string)name;
}
}
}
return String.Empty;
}
public async Task<DbDataReader> QueryAsync(string query, Dictionary<string, Object> parameters)
{
using (var cmd = new NpgsqlCommand(query, _Connection))
{
foreach (var parameter in parameters)
{
cmd.Parameters.AddWithValue(parameter.Key, parameter.Value == null ? DBNull.Value : parameter.Value);
}
cmd.Prepare();
return await cmd.ExecuteReaderAsync();
}
}
}
}

Update VSO history and add attachments

How do I add history records and attachments to a workitem in VSO 2015?
So far I have succeeded in logging in, running a query and retrieve the workitems from the query result.
But the workitem objects doesn't have properties for history or attatchments:
WorkItemTrackingHttpClient witClient = new WorkItemTrackingHttpClient(new Uri(collectionUri), new VssAadCredential("first.last#blablabla.com", "secret"));
List<QueryHierarchyItem> items = witClient.GetQueriesAsync(teamProjectName, QueryExpand.All,2).Result;
QueryHierarchyItem myQueriesFolder = items.FirstOrDefault(qhi => qhi.Name.Equals("Shared Queries"));
if (myQueriesFolder != null)
{
string queryName = "All Workitems";
QueryHierarchyItem newBugsQuery = null;
if (myQueriesFolder.Children != null)
{
newBugsQuery = myQueriesFolder.Children.FirstOrDefault(qhi => qhi.Name.Equals(queryName));
}
WorkItemQueryResult result = witClient.QueryByIdAsync(newBugsQuery.Id).Result;
if (result.WorkItemRelations.Count() > 0)
{
int skip = 0;
const int batchSize = 100;
IEnumerable<WorkItemLink> workItemRefs;
do
{
workItemRefs = result.WorkItemRelations.Skip(skip).Take(batchSize);
if (workItemRefs.Count() > 0)
{
// get details for each work item in the batch
List<WorkItem> workItems = witClient.GetWorkItemsAsync(workItemRefs.Select(wir => wir.Target.Id)).Result;
foreach (WorkItem workItem in workItems)
{
// write work item to console
if ((string)workItem.Fields["System.WorkItemType"] == "Requirement")
{
Console.WriteLine("{0} {1}", workItem.Id, workItem.Fields["System.Title"]);
//workItem doesn't have properties for history or attachmens...
WorkItemHistory history = (WorkItemHistory) workItem.Fields["System.History"];
}
}
}
skip += batchSize;
}
while (workItemRefs.Count() == batchSize);
}
}
In order to retrieve the history you need to loop through the revisions of a work item (WorkItem.Revisions) and output the history field for each revision.
You can't use WorkItem.Revision and instead should use WorkItem.Fields["System.History"].value to retrieve it.
Attachments are in WorkItem.Attachments for both read and write.
Using namespace:
Microsoft.TeamFoundation.Client
Microsoft.TeamFoundation.WorkItemTracking
Refer to following code for details:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
namespace TFSAPI
{
class Program
{
static void Main(string[] args)
{
string project = "https://xxxxxxxx.visualstudio.com/defaultcollection";
NetworkCredential nc = new NetworkCredential("username","pwd");
BasicAuthCredential cred = new BasicAuthCredential(nc);
TfsClientCredentials tc = new TfsClientCredentials(cred);
tc.AllowInteractive = false;
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(project), tc);
WorkItemStore workItemStore = tpc.GetService<WorkItemStore>();
Project teamProject = workItemStore.Projects["Sonar"];
WorkItemType workItemType = teamProject.WorkItemTypes["User Story"];
int workitemid = 2;
WorkItem wi = workItemStore.GetWorkItem(workitemid);
//Update history
wi.Fields["History"].Value = "You comments";
//Add attachment
wi.Attachments.Add(new Attachment("E:\\a\\1.txt"));
wi.Save();
}
}
}

Program crashes when exe is copied to different computer

I have written a program in c# on my Windows 7 computer with .NET 4.0 using Sharp Develop 4.2.
I then changed it to a release within Sharp Develop, built it, and copied the .exe in the bin\Release folder to another Windows 7 computer with .NET 4.0. It crashes immediately without loading the initial form and gives no specific error. My MainForm method is like this:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Drawing.Printing;
using System.Diagnostics;
using System.Text;
namespace BiasTracker1._
{
public partial class MainForm : Form
{
//Here are my initial variables
public static SqlConnectionStringBuilder sqlBldr = new SqlConnectionStringBuilder();
public static DataSet ds = new DataSet();
public static DataTable DisplayTable = ds.Tables.Add("DisplayTable");
SqlDataAdapter RawDataDA;
SqlCommandBuilder RawSampleSCB;
public static DataTable InstrumentDetail = ds.Tables.Add("InstrumentDetail");
public static string DatabaseOwner;
System.Windows.Forms.DataVisualization.Charting.Chart CurrentChart;
public static DataTable ImportDataTable = new DataTable();
public static string NewTransfer;
public static bool ValidatePerCell = true;
public static Image chart1Image;
public static string Title;
public static string NIRLabString;
bool ChangesNotDisplayed = false;
Point PreviousChartLocation;
List<System.Windows.Forms.DataVisualization.Charting.DataPoint> SelectedPoints = new List<System.Windows.Forms.DataVisualization.Charting.DataPoint>();
List<DataRow> SelectedRows = new List<DataRow>();
static double EPS = 2.22045e-016;
double FPMIN = 2.22507e-308 / EPS;
public static CustomPrintDoc pd = new CustomPrintDoc();
int NumOfParametersInReport = 0;
public static SqlConnectionStringBuilder SimPlusConn;
public static string SimPlusProductGUID;
public static string SimPlusSiteCode;
public double[] cof = new double[] {-1.3026537197817904,0.64196979235649026,0.019476473204185836,-0.009561514786808631,-0.000946595344482036,0.000366839497852761,0.000042523324806907,-0.000020278578112534,-0.000001624290004647,0.00000130365583558,0.000000015626441722,-0.000000085238095915,0.000000006529054439,0.000000005059343495,-0.000000000991364156,-0.000000000227365122,0.000000000096467911,0.000000000002394038,-0.000000000006886027,0.000000000000894487,0.000000000000313092,-0.000000000000112708,0.000000000000000381,0.000000000000007106,-0.000000000000001523,-0.000000000000000094,0.000000000000000121,-0.000000000000000028};
Point? prevPosition = null;
ToolTip tooltip = new ToolTip();
public MainForm()
{
try
{
InitializeComponent();
}
catch(Exception ex)
{
MessageBox.Show("Failed in Initialization.\n" + ex.ToString());
}
//Test SQL Connection
FileStream ConnectionStream;
try
{
ConnectionStream = new FileStream(#"C:\BiasTracker\settings.ini",FileMode.OpenOrCreate);
}
catch(DirectoryNotFoundException ex)
{
MessageBox.Show("Not able to find ini... Creating one.");
Directory.CreateDirectory(#"C:\BiasTracker");
ConnectionStream = new FileStream(#"C:\BiasTracker\settings.ini",FileMode.OpenOrCreate);
}
try
{
StreamReader ConnectionRdr = new StreamReader(ConnectionStream);
string line = null;
if((line = ConnectionRdr.ReadLine()) != null)
{
sqlBldr.DataSource = line;
sqlBldr.Password = ConnectionRdr.ReadLine();
sqlBldr.UserID = ConnectionRdr.ReadLine();
sqlBldr.InitialCatalog = ConnectionRdr.ReadLine();
}
else
{
sqlBldr.DataSource = ".\\SQLEXPRESS";
sqlBldr.Password = "password";
sqlBldr.UserID = "sa";
sqlBldr.InitialCatalog = "BiasMaster";
StreamWriter ConnectionWtr = new StreamWriter(ConnectionStream);
ConnectionWtr.WriteLine(".\\SQLEXPRESS");
ConnectionWtr.WriteLine("password");
ConnectionWtr.WriteLine("sa");
ConnectionWtr.WriteLine("BiasMaster");
ConnectionWtr.WriteLine("applications\\SQLEXPRESS");
ConnectionWtr.WriteLine("password");
ConnectionWtr.WriteLine("sa");
ConnectionWtr.WriteLine("BiasMaster");
ConnectionWtr.Dispose();
}
ConnectionStream.Close();
ConnectionStream.Dispose();
ConnectionRdr.Dispose();
}
catch(Exception ex)
{
MessageBox.Show("Not Able to read connection string\n" + ex.ToString());
}
System.Data.SqlClient.SqlConnection tmpConn;
tmpConn = new SqlConnection(sqlBldr.ConnectionString);
try //Test the connection and existence of the database
{
tmpConn.Open();
tmpConn.Close();
}
catch
{
MessageBox.Show("Database Connection not Found.");
tmpConn.Close();
}
SqlDataAdapter SettingsDA = new SqlDataAdapter("SELECT * FROM Settings WHERE SettingDesc = 'Owner'",sqlBldr.ConnectionString);
DataTable SettingsTable = new DataTable();
SettingsDA.Fill(SettingsTable);
DatabaseOwner = SettingsTable.Rows[0][1].ToString();
MakeTreeView();
}
MakeTreeView is surrounded by a try catch with a messagebox.
My Form loads these controls:
privateSystem.Windows.Forms.ToolStripMenuItemsimPlusImportToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripStatusLabeltoolStripStatusLabel1;
privateSystem.Windows.Forms.ToolStripMenuItemsyncWithSharedServerToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemsyncToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemsetDBConnectionToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemtestToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemdetectOutliersToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemsaveToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemexcludeSelectedToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemgraphActionsToolStripMenuItem;
privateSystem.Windows.Forms.ComboBoxcomboBox7;
privateSystem.Windows.Forms.ToolStripMenuItemprintReportToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemaddToReportToolStripMenuItem;
privateSystem.Windows.Forms.DataVisualization.Charting.Chartchart4;
privateSystem.Windows.Forms.DataVisualization.Charting.Chartchart3;
privateSystem.Windows.Forms.Panelpanel2;
privateSystem.Windows.Forms.DataVisualization.Charting.Chartchart2;
privateSystem.Windows.Forms.ComboBoxcomboBox6;
privateSystem.Windows.Forms.Labellabel7;
privateSystem.Windows.Forms.Buttonbutton3;
privateSystem.Windows.Forms.DataVisualization.Charting.Chartchart1;
privateSystem.Windows.Forms.Buttonbutton2;
privateSystem.Windows.Forms.ToolStripMenuItemremoveProductFormInstrumentToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemcopyInstrumentProductListToAnotherInstrumentToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemaddProductToInstrumentToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemaddParameterToProductToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemtablesToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemtXTToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemcSVToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItembiasDataToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemimportToolStripMenuItem;
privateSystem.Windows.Forms.Labellabel1;
privateSystem.Windows.Forms.ComboBoxcomboBox1;
privateSystem.Windows.Forms.Labellabel2;
privateSystem.Windows.Forms.ComboBoxcomboBox2;
privateSystem.Windows.Forms.Labellabel3;
privateSystem.Windows.Forms.ComboBoxcomboBox3;
privateSystem.Windows.Forms.Labellabel4;
privateSystem.Windows.Forms.ComboBoxcomboBox4;
privateSystem.Windows.Forms.Labellabel5;
privateSystem.Windows.Forms.ComboBoxcomboBox5;
privateSystem.Windows.Forms.Labellabel6;
privateSystem.Windows.Forms.DateTimePickerdateTimePicker1;
privateSystem.Windows.Forms.DateTimePickerdateTimePicker2;
privateSystem.Windows.Forms.ToolStripMenuItemparameterToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemproductToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuIteminstrumentToolStripMenuItem1;
privateSystem.Windows.Forms.ToolStripMenuItemlocationToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemcompanyToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemnewToolStripMenuItem;
privateSystem.Windows.Forms.ToolStripMenuItemfileToolStripMenuItem;
privateSystem.Windows.Forms.MenuStripmenuStrip1;
privateSystem.Windows.Forms.StatusStripstatusStrip1;
privateSystem.Windows.Forms.TabPagetabPage2;
privateSystem.Windows.Forms.DataGridViewdataGridView1;
privateSystem.Windows.Forms.TreeViewtreeView1;
privateSystem.Windows.Forms.Buttonbutton1;
privateSystem.Windows.Forms.Panelpanel1;
privateSystem.Windows.Forms.TabPagetabPage1;
privateSystem.Windows.Forms.TabControltabControl1;
The only thing I can think is that I am using a reference to something that the other computer does not have access to. I thought it was the chart controls, but .NET 4.0 has those included. Any help would be immensely appreciated.
I found the culprit. It was the line:
DatabaseOwner = SettingsTable.Rows[0][1].ToString();
I found it using AppDomain.UnhandledException. It was a great tool if anyone else is running into a similar issue.
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

List changed files in TFS but ordered by number of changes applied

Is there a way of listing all the files that have changed on a project, but ordered by the number of changes made to each file?
I want to do a code review but only from a selection of the most active files.
You may try to use Excel as a TFS reporting tool like in this blog post:
http://www.woodwardweb.com/vsts/getting_started.html
ps. I found that link in this question.
I searched different ways and finally I found that best way is using TFS API
here is the code :
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace VControl
{
class Program
{
class SourceElement
{
public string filename;
public int numberOfModification;
}
static void Main(string[] args)
{
TfsTeamProjectCollection projectCollection = new
TfsTeamProjectCollection(new Uri("http://server:8080/tfs/ProjectCollection/"),
new System.Net.NetworkCredential("username", "password"));
projectCollection.EnsureAuthenticated();
Workspace workspace = null;
Boolean createdWorkspace = false;
String newFolder = String.Empty;
VersionControlServer versionControl = projectCollection.GetService<VersionControlServer>();
var teamProjects = new List<TeamProject>(versionControl.GetAllTeamProjects(false));
String workspaceName = String.Format("{0}-{1}", Environment.MachineName, "TestWorkspace");
try
{
workspace = versionControl.GetWorkspace(workspaceName, versionControl.AuthorizedUser);
}
catch (WorkspaceNotFoundException)
{
workspace = versionControl.CreateWorkspace(workspaceName, versionControl.AuthorizedUser);
createdWorkspace = true;
}
var serverFolder = String.Format("$/{0}", teamProjects[0].Name) + "/solutionFolder/";
var localFolder = Path.Combine(Path.GetTempPath(), "localFolder") + "/solutionFolder/";
var workingFolder = new WorkingFolder(serverFolder, localFolder);
// Create a workspace mapping.
workspace.CreateMapping(workingFolder);
if (!workspace.HasReadPermission)
{
throw new SecurityException(
String.Format("{0} does not have read permission for {1}",
versionControl.AuthorizedUser, serverFolder));
}
// Get the files from the repository.
workspace.Get();
string[] directories = Directory.GetDirectories(workspace.Folders[0].LocalItem);
FileStream outputFile = new FileStream("result.txt", FileMode.Create);
StreamWriter writer = new StreamWriter(outputFile);
List<SourceElement> fileLiset = new List<SourceElement>();
foreach (string dir in directories)
{
foreach (string file in Directory.GetFiles(dir))
{
string filenamae = System.IO.Path.GetFileName(file);
Item source = versionControl.GetItem(file);
System.Collections.IEnumerable history = versionControl.QueryHistory(file,
VersionSpec.Latest, 0, RecursionType.Full, null, null, null, 300, true, true, false, false);
int numberOfModification = 0;
foreach (var item in history)
numberOfModification++;
SourceElement fileElement = new SourceElement();
fileElement.filename = filenamae;
fileElement.numberOfModification = numberOfModification;
fileLiset.Add(fileElement);
}
}
var sortedList = fileLiset.OrderBy(x=> x.numberOfModification);
// Loop through keys.
foreach (var key in sortedList)
{
writer.WriteLine("{0}: {1}", key.filename, key.numberOfModification);
}
writer.Close();
}
}
}