Find in Files: Search all code in Team Foundation Server

115,248

Solution 1

Team Foundation Server 2015 (on-premises) and Visual Studio Team Services (cloud version) include built-in support for searching across all your code and work items.

You can do simple string searches like foo, boolean operations like foo OR bar or more complex language-specific things like class:WebRequest

screenshot of code search filter syntax

You can read more about it here: https://www.visualstudio.com/en-us/docs/search/overview

Solution 2

In my case, writing a small utility in C# helped. Links that helped me - http://pascallaurin42.blogspot.com/2012/05/tfs-queries-searching-in-all-files-of.html

How to list files of a team project using tfs api?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Framework.Client;
using System.IO;

namespace TFSSearch
{
class Program
{
    static string[] textPatterns = new[] { "void main(", "exception", "RegisterScript" };  //Text to search
    static string[] filePatterns = new[] { "*.cs", "*.xml", "*.config", "*.asp", "*.aspx", "*.js", "*.htm", "*.html", 
                                           "*.vb", "*.asax", "*.ashx", "*.asmx", "*.ascx", "*.master", "*.svc"}; //file extensions

    static void Main(string[] args)
    {
        try
        {
            var tfs = TfsTeamProjectCollectionFactory
             .GetTeamProjectCollection(new Uri("http://{tfsserver}:8080/tfs/}")); // one some servers you also need to add collection path (if it not the default collection)

            tfs.EnsureAuthenticated();

            var versionControl = tfs.GetService<VersionControlServer>();


            StreamWriter outputFile = new StreamWriter(@"C:\Find.txt");
            var allProjs = versionControl.GetAllTeamProjects(true);
            foreach (var teamProj in allProjs)
            {
                foreach (var filePattern in filePatterns)
                {
                    var items = versionControl.GetItems(teamProj.ServerItem + "/" + filePattern, RecursionType.Full).Items
                                .Where(i => !i.ServerItem.Contains("_ReSharper"));  //skipping resharper stuff
                    foreach (var item in items)
                    {
                        List<string> lines = SearchInFile(item);
                        if (lines.Count > 0)
                        {
                            outputFile.WriteLine("FILE:" + item.ServerItem);
                            outputFile.WriteLine(lines.Count.ToString() + " occurence(s) found.");
                            outputFile.WriteLine();
                        }
                        foreach (string line in lines)
                        {
                            outputFile.WriteLine(line);
                        }
                        if (lines.Count > 0)
                        {
                            outputFile.WriteLine();
                        }
                    }
                }
                outputFile.Flush();
            }
        }
        catch (Exception e)
        {
            string ex = e.Message;
            Console.WriteLine("!!EXCEPTION: " + e.Message);
            Console.WriteLine("Continuing... ");
        }
        Console.WriteLine("========");
        Console.Read();
    }

    // Define other methods and classes here
    private static List<string> SearchInFile(Item file)
    {
        var result = new List<string>();

        try
        {
            var stream = new StreamReader(file.DownloadFile(), Encoding.Default);

            var line = stream.ReadLine();
            var lineIndex = 0;

            while (!stream.EndOfStream)
            {
                if (textPatterns.Any(p => line.IndexOf(p, StringComparison.OrdinalIgnoreCase) >= 0))
                    result.Add("=== Line " + lineIndex + ": " + line.Trim());

                line = stream.ReadLine();
                lineIndex++;
            }
        }
        catch (Exception e)
        {
            string ex = e.Message;
            Console.WriteLine("!!EXCEPTION: " + e.Message);
            Console.WriteLine("Continuing... ");
        }

        return result;
    }
}
}

Solution 3

There is another alternative solution, that seems to be more attractive.

  1. Setup a search server - could be any windows machine/server
  2. Setup a TFS notification service* (Bissubscribe) to get, delete, update files everytime a checkin happens. So this is a web service that acts like a listener on the TFS server, and updates/syncs the files and folders on the Search server. - this will dramatically improve the accuracy (live search), and avoid the one-time load of making periodic gets
  3. Setup an indexing service/windows indexed search on the Search server for the root folder
  4. Expose a web service to return search results

Now with all the above setup, you have a few options for the client:

  1. Setup a web page to call the search service and format the results to show on the webpage - you can also integrate this webpage inside visual studio (through a macro or a add-in)
  2. Create a windows client interface(winforms/wpf) to call the search service and format the results and show them on the UI - you can also integrate this client tool inside visual studio via VSPackages or add-in

Update: I did go this route, and it has been working nicely. Just wanted to add to this.

Reference links:

  1. Use this tool instead of bissubscribe.exe
  2. Handling TFS events
  3. Team System Notifications

Solution 4

If you install TFS 2008 PowerTools you will get a "Find in Source Control" action in the Team Explorer right click menu.

TFS2008 Power Tools

Solution 5

We have set up a solution for Team Foundation Server Source Control (not SourceSafe as you mention) similar to what Grant suggests; scheduled TF Get, Search Server Express. However the IFilter used for C# files (text) was not giving the results we wanted, so we convert source files to .htm files. We can now add additional meta-data to the files such as:

  • Author (we define it as the person that last checked in the file)
  • Color coding (on our todo-list)
  • Number of changes indicating potential design problems (on our todo-list)
  • Integrate with the VSTS IDE like Koders SmartSearch feature
  • etc.

We would however prefer a protocolhandler for TFS Source Control, and a dedicated source code IFilter for a much more targeted solution.

Share:
115,248

Related videos on Youtube

Mark Glorie
Author by

Mark Glorie

.Net developer for the mobile social website MOKO.mobi

Updated on January 09, 2020

Comments

  • Mark Glorie
    Mark Glorie over 4 years

    Is there a way to search the latest version of every file in TFS for a specific string or regex? This is probably the only thing I miss from Visual Source Safe...

    Currently I perform a Get Latest on the entire codebase and use Windows Search, but this gets quite painful with over 1GB of code in 75,000 files.

    EDIT: Tried the powertools mentioned, but the "Wildcard Search" option appears to only search filenames and not contents.

    UPDATE: We have implemented a customised search option in an existing MOSS (Search Server) installation.

  • Iain Holder
    Iain Holder over 15 years
    @muerte it's funny that they're called 'power tools'. Some would say doing something like a rollback is 'basic functionality'. :-)
  • Peter Burns
    Peter Burns over 15 years
    well, you can certainly do a rollback manually, it's just not a one-click operation. Perhaps it should be..
  • Mark Glorie
    Mark Glorie over 15 years
    Sorry I don't see where it offers to search inside files?
  • Sandor Davidhazi
    Sandor Davidhazi over 15 years
    Atually I downloaded this plug-in set earlier and it only lets you search by author, label, date etc. but not inside older versions of files... :\
  • Paul Michaels
    Paul Michaels about 14 years
    It's flaky and slow, but seem to do what it says on the tin
  • wcm
    wcm almost 14 years
    Good answer, dead link: microsoft.com/downloads/…
  • sath garcia
    sath garcia almost 14 years
    Any plans to open source the .htm conversion?
  • Kiddo
    Kiddo over 13 years
    i think that only search for file/ folder name
  • Evgeniy Berezovsky
    Evgeniy Berezovsky almost 12 years
    -1 the power tools do not search file contents, only file/folder names.
  • Craig
    Craig over 11 years
    Doesn't address the issue of searching through TFS code versions.
  • strider
    strider over 9 years
    I get an error like these people got in the link below. Anyone else experiencing this? tfssearchcode.codeplex.com/workitem/32475
  • deadlydog
    deadlydog over 8 years
    See my answer below, and upvote it ;) This is now possible as of TFS 2015 by using the Code Search plugin. marketplace.visualstudio.com/items?itemName=ms.vss-code-sear‌​ch
  • Jamie
    Jamie almost 8 years
    Note: Code Search is currently available for only Visual Studio Team Services. Support for Team Foundation Server is under development, and will be included in the next release.
  • Jamie
    Jamie almost 8 years
    Useless for searching contents that you don't have downloaded. Might as well use grep/findstr.
  • paparush
    paparush almost 8 years
    Code Search is currently available for only Visual Studio Team Services. Support for Team Foundation Server is under development, and will be included in the next release.
  • csrowell
    csrowell about 5 years
    Code Search is now available in TFS 2017 or newer.
  • AaronLS
    AaronLS about 5 years
    If you try to switch to the 2015 version of that document: "The requested page is not available for Team Foundation Server 2015."