Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Collections.ObjectModel;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using System.ComponentModel;
using System.IO;
namespace TFS_Show
{
/// <summary>
/// Stellt Verbindungen und Objekte aus der AD-Domäne und des TFS zur Verfügung
/// </summary>
static class Network
{
#region member
internal static bool _initialized = false;
internal static string _type = "LDAP:";
// internal static string _type = "WinNT:";
internal static string _authUser;
internal static DirectoryEntry _root;
internal static DirectorySearcher _searcher;
internal static string _domain;
internal static TfsConfigurationServer _tfs;
internal static VersionControlServer _vcs;
internal static ReadOnlyCollection<CatalogNode> _cNodes;
internal static CatalogNode _cNode;
internal static List<Changeset> _changes;
internal static SearchResultCollection _allPC;
delegate object WorkDelegate(string server);
#endregion member
#region Initialize()
/// <summary>
/// Holt den Verzeichniseintrag für root aus dem Active Directory
/// </summary>
internal static void Initialize()
{
string aktDom = string.Concat(_type, "//", "RootDSE");
_root = new DirectoryEntry(aktDom);
if (_root == null) // || _root.Container == null)
throw new ApplicationException("Fehler bei Instantiierung auf " + aktDom);
_domain = GetRootDSE();
if (string.IsNullOrEmpty(_domain))
throw new ApplicationException("Fehler bei Ermittlung der root-Domäne");
_initialized = true;
}
#endregion Initialize()
#region GetRootDSE()
/// <summary>
/// Holt den Einstiegspunkt ins Active Directory
/// </summary>
/// <returns>root-Domäne, bei uns: de.***.corp</returns>
internal static string GetRootDSE()
{
string rootDSE = _root.Properties["defaultNamingContext"].Value.ToString();
if (rootDSE.Contains(","))
{
string[] arrSubStrings = rootDSE.Split(',');
rootDSE = string.Empty;
foreach (string item in arrSubStrings)
{
string[] arrParts = item.Split('=');
if (string.IsNullOrEmpty(rootDSE))
{
rootDSE = arrParts[1];
}
else
{
rootDSE = string.Concat(rootDSE, ".", arrParts[1]);
}
}
}
return rootDSE;
}
#endregion GetRootDSE()
#region GetAllChilds()
/// <summary>
/// Füllt als Hintergrundjob eine Collection mit allen PCs der Domäne
/// </summary>
internal static DirectorySearcher GetAllChilds(BackgroundWorker worker, DoWorkEventArgs e)
{
if (!_initialized)
throw new ApplicationException("Klasse ist nicht initialisiert.");
if (worker.CancellationPending)
{
e.Cancel = true;
}
else
{
DirectoryEntry root = new DirectoryEntry(string.Concat(_type, "//", _domain));
_searcher = new DirectorySearcher(root);
// Filter zur Suche angeben, in diesem Fall: alle PCs
_searcher.Filter = "(objectCategory=computer)";
return _searcher;
}
return null;
}
#endregion GetAllChilds()
#region IsComputerValid()
/// <summary>
/// Prüft, ob es einen bestimmten PC in der Domäne gibt
/// </summary>
/// <param name="Computername"></param>
/// <returns>true oder false</returns>
internal static bool IsComputerValid(string computerName)
{
if (!_initialized)
throw new ApplicationException("Klasse ist nicht initialisiert.");
if (string.IsNullOrEmpty(computerName))
return false;
if (_allPC != null)
{
foreach (SearchResult pc in _allPC)
{
string domPC = (pc.GetDirectoryEntry().Name.Substring(0, 3) == "CN=") ? pc.GetDirectoryEntry().Name.Substring(3) : pc.GetDirectoryEntry().Name;
if (computerName.CompareTo(domPC) == 0)
return true;
}
}
return false;
}
#endregion IsComputerValid()
#region GetComputerData()
/// <summary>
/// Liefert Daten zu einem Computer
/// </summary>
/// <param name="computerName"></param>
/// <returns>Eintrag als AD</returns>
internal static DirectoryEntry GetComputerData(string computerName)
{
foreach (SearchResult pc in _allPC)
{
string domPC = (pc.GetDirectoryEntry().Name.Substring(0, 3) == "CN=") ? pc.GetDirectoryEntry().Name.Substring(3) : pc.GetDirectoryEntry().Name;
if (computerName.CompareTo(domPC) == 0)
return pc.GetDirectoryEntry();
}
return new DirectoryEntry();
}
#endregion GetComputerData()
#region CheckTFStatus()
/// <summary>
/// Prüft den Status des übergebenen Computernamens
/// </summary>
/// <param name="server">Computername</param>
/// <returns>Ergebnismeldung</returns>
internal static string CheckTFStatus(string server)
{
try
{
DoWork(server);
}
catch (ApplicationException tfs)
{
return tfs.Message;
}
if (!_tfs.HasAuthenticated)
return string.Format("Authentifizierung für {0} fehlgeschlagen!", server);
try
{
ConnectOptions con = new ConnectOptions();
con = ConnectOptions.None;
_tfs.Connect(con);
_cNode = _tfs.CatalogNode;
}
catch (ApplicationException ctn)
{
return ctn.Message;
}
if (_tfs.CatalogNode == null)
return string.Format("Der Server {0} meldet {1}", server, _tfs.Name);
return string.Format("{0}: Verbindung hergestellt zu {1}", server, _cNode.Resource.DisplayName);
}
#endregion CheckTFStatus()
#region GetProjectCollections()
/// <summary>
/// Gibt die aktuellen Projektsammlungen zurück
/// </summary>
/// <param name="server">TFS</param>
/// <param name="project">Projektname</param>
/// <returns>Projektsammlung</returns>
internal static List<RegisteredProjectCollection> GetProjectCollections(string server, string project)
{
Uri tfsUri = new Uri(string.Concat("http://", server, "/", string.IsNullOrEmpty(project) ? string.Empty : project));
TfsConfigurationServer configurationServer =
TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
Guid guid = new Guid();
TfsTeamProjectCollection tpc = configurationServer.GetTeamProjectCollection(guid);
//ReadOnlyCollection<CatalogNode> collectionNodes = configurationServer.CatalogNode.QueryChildren(
// new[] { CatalogResourceTypes.ProjectCollection },
// false, CatalogQueryOptions.None);
return new List<RegisteredProjectCollection>
{
RegisteredTfsConnections.GetProjectCollection(string.Concat(server, "\\", null ))
};
}
#endregion GetProjectCollections()
#region GetLastChangeSet()
/// <summary>
/// Holt die ID des letzten Changesets
/// </summary>
/// <returns>ChangeSet-ID</returns>
internal static int GetLastChangeSet()
{
var lastID = _vcs.QueryHistory(
"$/",
VersionSpec.Latest,
0,
RecursionType.Full,
string.Empty,
VersionSpec.Latest,
VersionSpec.Latest,
1,
false,
true).Cast<Changeset>().Single().ChangesetId;
return lastID;
}
#endregion GetLastChangeSet()
#region GetAllChanges()
/// <summary>
/// Holt alle Changesets zu einem Teamprojekt
/// </summary>
internal static void GetAllChanges()
{
_changes = new List<Changeset>();
int last = GetLastChangeSet();
try
{
for (int i = 1; i <= last; i++)
{
var change = _vcs.GetChangeset(i, true, true, true);
_changes.Add(change);
}
}
catch (Exception)
{
// Dreckig. Aber so bricht er ab, wenns keine Changesets mehr gibt
}
}
/// <summary>
/// Gibt eine Liste aller Änderungen des betreffenden Nutzers zurück
/// </summary>
/// <param name="tree"></param>
/// <returns>Changesets</returns>
internal static List<Changeset> GetAllChanges(Telerik.WinControls.UI.RadTreeView tree)
{
List<Changeset> retVal = new List<Changeset>();
string tmp = string.Empty;
if (string.IsNullOrEmpty(_authUser))
_authUser = _vcs.AuthorizedUser;
GetAllChanges();
foreach (Telerik.WinControls.UI.RadTreeNode node in tree.CheckedNodes)
{
if (node.Tag.GetType() == typeof(ReadOnlyCollection<CatalogNode>))
{
// Root-Node
retVal.AddRange(_changes.Where(item => item.Committer == _authUser));
}
else if (node.Tag.GetType() == typeof(CatalogNode))
{
retVal.AddRange(_changes.Where(x => x.Committer == _authUser && x.Changes.Where(y => y.Item.ServerItem.Contains((node.Tag as CatalogNode).Resource.DisplayName)).Count() > 0));
tmp = string.Empty;
// Unkenntlich wg. Firma
if ((node.Tag as CatalogNode).Resource.DisplayName.Contains("Projectname"))
tmp = (node.Tag as CatalogNode).Resource.DisplayName.Replace("Projectname", "Projectname");
else if ((node.Tag as CatalogNode).Resource.DisplayName.Contains("Projectname"))
tmp = (node.Tag as CatalogNode).Resource.DisplayName.Replace("Projectname", "Projectname");
else if ((node.Tag as CatalogNode).Resource.DisplayName.Contains("Projectname"))
tmp = (node.Tag as CatalogNode).Resource.DisplayName.Replace("Projectname", "Projectname");
if (!string.IsNullOrEmpty(tmp))
retVal.AddRange(_changes.Where(x => x.Committer == _authUser && x.Changes.Where(y => y.Item.ServerItem.Contains(tmp)).Count() > 0));
}
}
return retVal;
}
#endregion GetAllChanges()
#region DoWork()
/// <summary>
/// Startet timeout-Handler um ggf. einen Abbruch zu erzwingen
/// Geklaut bei: http://www.developerfusion.com/code/4497/i-need-a-timeout/
/// </summary>
/// <param name="server">Zu prüfender Computername</param>
/// <returns></returns>
internal static object DoWork(string server)
{
WorkDelegate d = new WorkDelegate(DoWorkHandler);
IAsyncResult res = d.BeginInvoke(server, null, null);
if (res.IsCompleted == false)
{
res.AsyncWaitHandle.WaitOne(10000, false);
if (res.IsCompleted == false)
throw new ApplicationException(string.Format("Timeout bei Verbindungsversuch zu {0}", server));
}
return d.EndInvoke((AsyncResult)res);
}
#endregion DoWork()
#region DoWorkHandler()
/// <summary>
/// Erledigt die eigentliche Arbeit als Thread
/// </summary>
/// <param name="server">Zu prüfender Computername</param>
/// <returns></returns>
private static object DoWorkHandler(string server)
{
Uri tfsUri = new Uri(string.Concat("http://", server, ":8080/tfs"));
_tfs = null;
_cNode = null;
_tfs = TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);
TeamFoundationIdentity id = _tfs.AuthorizedIdentity;
_tfs.Authenticate();
return true;
}
#endregion DoWorkHandler()
#region FillddnComputer()
/// <summary>
/// Füllt die DropDownListe der Computer
/// </summary>
/// <param name="radDropDownList">Dropdown-Liste</param>
/// <returns>Gefüllte DropDown-Liste</returns>
internal static Telerik.WinControls.UI.RadDropDownList FillddnComputer(Telerik.WinControls.UI.RadDropDownList radDropDownList)
{
Telerik.WinControls.UI.RadDropDownList retVal = radDropDownList;
_allPC = _searcher.FindAll();
foreach (SearchResult pc in _allPC)
{
Telerik.WinControls.UI.RadListDataItem comp = new Telerik.WinControls.UI.RadListDataItem();
comp.Text = pc.GetDirectoryEntry().Name;
// Ausgabe ist normalerweise: "CN=Computername"
comp.Text = (comp.Text.Substring(0, 3) == "CN=") ? comp.Text.Substring(3) : comp.Text;
comp.Value = comp.Text;
retVal.Items.Add(comp);
}
return retVal;
}
#endregion FillddnComputer()
#region FillddnProject()
/// <summary>
/// Füllt die DropDown-Liste der Projekte
/// </summary>
/// <param name="radDropDownList">DropDown-Liste der Projekte</param>
/// <returns>Gefüllte DropDown-Liste der Projekte</returns>
internal static Telerik.WinControls.UI.RadDropDownList FillddnProject(Telerik.WinControls.UI.RadDropDownList radDropDownList)
{
Telerik.WinControls.UI.RadDropDownList retVal = radDropDownList;
if (_cNode == null)
return retVal;
_cNodes = _cNode.QueryChildren(
new[] { CatalogResourceTypes.ProjectCollection },
true, CatalogQueryOptions.None);
foreach (CatalogNode cNode in _cNodes)
{
Telerik.WinControls.UI.RadListDataItem proj = new Telerik.WinControls.UI.RadListDataItem();
// Use the InstanceId property to get the team project collection
Guid cID = new Guid(cNode.Resource.Properties["InstanceId"]);
TfsTeamProjectCollection tPC = _tfs.GetTeamProjectCollection(cID);
_vcs = (VersionControlServer)tPC.GetService(typeof(VersionControlServer));
proj.Value = tPC;
proj.Text = tPC.Name;
retVal.Items.Add(proj);
}
return retVal;
}
#endregion FillddnProject()
#region FilltreParts()
/// <summary>
/// Füllt die Teamprojekte in den TreeViewer
/// </summary>
/// <param name="tfsColl">root vom TFS</param>
/// <param name="treeView">TreeView-Control aus MainForm</param>
internal static void FilltreParts(TfsTeamProjectCollection tfsColl, ref Telerik.WinControls.UI.RadTreeView treeView)
{
treeView.Nodes.Clear();
if (treeView == null || tfsColl == null || tfsColl.GetType() != typeof(TfsTeamProjectCollection))
return;
// Alle Team-Projekte abholen
ReadOnlyCollection<CatalogNode> pNodes = tfsColl.CatalogNode.QueryChildren(
new[] { CatalogResourceTypes.TeamProject },
false, CatalogQueryOptions.None);
int i = 0;
Telerik.WinControls.UI.RadTreeNode node1 = new Telerik.WinControls.UI.RadTreeNode();
node1.Name = "Root";
node1.Tag = pNodes;
node1.CheckType = Telerik.WinControls.UI.CheckType.CheckBox;
node1.Enabled = true;
node1.BackColor = System.Drawing.SystemColors.Control;
node1.ForeColor = System.Drawing.SystemColors.WindowText;
node1.Text = tfsColl.Name;
Telerik.WinControls.UI.RadTreeNode[] nodes = new Telerik.WinControls.UI.RadTreeNode[pNodes.Count];
// List the team projects in the collection
foreach (CatalogNode pNode in pNodes)
{
nodes[i] = new Telerik.WinControls.UI.RadTreeNode();
nodes[i].Name = string.Format("Node{0:###}", i.ToString());
nodes[i].Tag = pNode;
nodes[i].CheckType = Telerik.WinControls.UI.CheckType.CheckBox;
nodes[i].Enabled = true;
nodes[i].Text = pNode.Resource.DisplayName;
i++;
}
for (int j = 0; j <= i-1; j++)
{
node1.Nodes.Add(nodes[j]);
}
treeView.Nodes.Add(node1);
treeView.ExpandAll();
}
#endregion FilltreParts()
internal static void ExportChangeSets(List<Changeset> changes)
{
string msg;
if (changes.Count < 1)
msg = "Keine Changesets ermittelt!";
else
{
try
{
StreamWriter outFile = new StreamWriter(@"C:\TFSout.txt", false, Encoding.Default);
foreach (Changeset cs in changes)
{
outFile.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}",
cs.ChangesetId,
cs.CreationDate,
cs.Committer,
cs.Comment));
foreach (Change ch in cs.Changes)
{
outFile.WriteLine(string.Format("\t\tDatei:\t{0}", ch.Item.ServerItem.Replace("Projectname", "")));
}
}
outFile.Close();
msg = string.Format("Es wurden {0} Changesets nach {1} exportiert.", changes.Count, @"C:\TFSout.txt");
System.Diagnostics.Process excel = new System.Diagnostics.Process();
excel.StartInfo.FileName = "Excel.exe";
excel.StartInfo.Arguments = @"C:\TFSout.txt";
excel.Start();
}
catch (Exception ioex)
{
System.Windows.Forms.MessageBox.Show(ioex.Message);
}
}
}
}
}