How to use Windows Search Service in c#
Asked Answered
B

1

9

I'm working on an application, an user can search for files or folders either on the local computer or on the network. I am using DirectoryInfo.GetDirecotories().

  1. But I also want to add the functionality that windows 7 uses for searching, I believe that uses indexing. I also saw Windows Searching Service on msdn, but I'm not sure which way is best: querying the indexed catalog or using the search service. Any suggestions?

Provide a small example in C# that searches the indexed catalog?

Bindery answered 17/12, 2015 at 15:38 Comment(4)
You mean something like this: full text search in c#?Christman
@Christman do you mean searching a "text file", if yes, then no I'm not looking for searching text in a document.Bindery
@Christman I am checking the link on your reply, yes thats what I am looking for, it is searching for files only, is it possible to leverage the scope to search for folders? and also is it possible to search the network drives?Bindery
I will come up with an example in few minutes.Christman
C
14

See the below example:

static void Main(string[] args)
{
    var connection = new OleDbConnection(@"Provider=Search.CollatorDSO;Extended Properties=""Application=Windows""");

    // File name search (case insensitive), also searches sub directories
    var query1 = @"SELECT System.ItemName FROM SystemIndex " +
                @"WHERE scope ='file:C:/' AND System.ItemName LIKE '%Test%'";

    // File name search (case insensitive), does not search sub directories
    var query2 = @"SELECT System.ItemName FROM SystemIndex " +
                @"WHERE directory = 'file:C:/' AND System.ItemName LIKE '%Test%' ";

    // Folder name search (case insensitive)
    var query3 = @"SELECT System.ItemName FROM SystemIndex " +
                @"WHERE scope = 'file:C:/' AND System.ItemType = 'Directory' AND System.Itemname LIKE '%Test%' ";

    // Folder name search (case insensitive), does not search sub directories
    var query4 = @"SELECT System.ItemName FROM SystemIndex " +
                @"WHERE directory = 'file:C:/' AND System.ItemType = 'Directory' AND System.Itemname LIKE '%Test%' ";           

    connection.Open();

    var command = new OleDbCommand(query4, connection);

    using (var r = command.ExecuteReader())
    {
        while (r.Read())
        {
            Console.WriteLine(r[0]);
        }
    }

    connection.Close();

    Console.ReadKey();
}

It's using OLE DB api to connect to the indexer service and use a SQL-like syntax to search System objects in its SystemIndex table. You have 4 example queries which do different things. All example queries will search in the c:\ folder for items that contain Test in their names.

You can search for files, folders mails and possibly other media (depending on OS) on local or other machines. From what I have researched network drives are not supported since they can't be indexed but you can connect to other machines for which I assume RPC is used in the background which means you have to supply network credentials using a different api (e.g. System.Net).

Note that for any of this to work your indexing must be fully operational on the target machine (which it is by default). The api is corresponding to whatever you specify in your Indexing Options. This is the screen in question:

indexing options

The full list of properties for the System object can be found here: Property System Reference. This object contains things such as URL, Path, Name, Date etc.

More interesting examples using different predicates (e.g. scope and directory) can be found here: Windows Vista Search Syntax. There is also a crude MSDN documentation: SCOPE and DIRECTORY Predicates

I recommend you check out the documentation because you can do a lot of stuff with this api.

Christman answered 17/12, 2015 at 17:4 Comment(5)
i know its been a while, but I'm reaching out to you again. You have already mentioned about searching network machine, but I was looking at windows dev network, To query the local catalog of a remote computer, include the computer name before the catalog and a Universal Naming Convention (UNC) path on the remote computer in the SCOPE or DIRECTORY clause.Bindery
and found this example ` SELECT System.ItemName FROM zarasmachine.SystemIndex WHERE SCOPE='file://zarasmachine/C:/Files/Reports' `, my question is, if i have access to the remote machine, this query won't work ?Bindery
A little late to the party here, but one interesting about using this API is that I haven't found a way to have it return results with partial numbers in it. For example, if I have a file named "abc12345.txt", and I use the search clause "WHERE System.FileName LIKE '%123%'", the file won't be returned. However LIKE '%12345%' would.Royceroyd
Theoretically.. Could someone write their own indexing service to replace Microsofts? Since Microsoft do not support Windows Search on Server 2012 / Server 2016 - and it's absolutely crap?Hardihood
They do support windows search, not indexing services which was deprecated as of windows 2008. Windows Search is the replacer.Oldie

© 2022 - 2024 — McMap. All rights reserved.