Question

I have a requirement to search file in a given location for specified content. These files will be searched via a web-application (which may not necessarily be on the same server), and should update in near realtime.

After looking around for Scanning tools/code, I hit upon this answer that indicated that you can programmatically hook into the built in Windows Search feature of windows.

Using the code below (more or less the answers code with a few minor tweaks), I have been able to successfully make this work on my machine:

public class WindowsSearchScanner
{
    private const string Query = @"SELECT System.ItemName FROM SystemIndex WHERE scope ='file:{0}' and FREETEXT('{1}')";

    public void DoSearch(string criteria, string path)
    {
        string connectionString = "Provider=Search.CollatorDSO;Extended Properties=\"Application=Windows\"";
        using (OleDbConnection connection = new OleDbConnection(connectionString))
        {
            string query = string.Format(Query, path, criteria);
            OleDbCommand command = new OleDbCommand(query, connection);
            connection.Open();

            List<string> result = new List<string>();

            OleDbDataReader reader = command.ExecuteReader();
            int count = 0;
            while (reader.Read())
            {
                result.Add(reader.GetString(0));
                Console.WriteLine(reader.GetString(0));

                count++;
            }
            Console.WriteLine(count + " Records Found");

            connection.Close();
        }
    }
}

I have several queries regarding this:

  1. Is there a better (i.e. more .Net) way of accessing the Windows Search, beyond using string queries?
  2. Is there a way to parameterise the text? I tried straight up adding OleDbParameters to the command, but apparently the CollatorDSO doesn't support it. Obviously, I'd prefer not to have to sanitise the data beforehand - like SQL injection, it's likely I'll miss some potential avenue that will cause problems

    string query = @"SELECT System.ItemName FROM SystemIndex WHERE scope ='file:' + @path and FREETEXT(@text)";
    OleDbCommand command = new OleDbCommand(query, connection);
    
    command.Parameters.Add(new OleDbParameter("path", path));
    command.Parameters.Add(new OleDbParameter("text", criteria));
    
    connection.Open();
    
  3. Can this be accessed from a remote machine?

  4. Will this work even if the server does not have the relevant software installed - i.e. if the directory contains an excel file, will it index even if the server does not have office installed?
Was it helpful?

Solution

for 3) ,4) msdn Using SQL and AQS Approaches to Query the Index for 1) you can try add windows function via import unsafe. for 2) looks wierd old fashioned but i suppose there is no other option for this approach

OTHER TIPS

You can go old-school and use FindStr in a Process/ProcessStartInfo.

Findstr (a command-line tool) is built in to your server and is able to access any location to which the user you are impersonating has access.

I tried this out in a small single-page implementation and i was able to read/ scan files on my local drive as well as UNC paths.

This could be an option for you. The output is text.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top