Connection to Windows search?

Options
BCat
edited February 2020 in General

How do I configure LINQPad to connect to Windows Search so I can use LINQ, SQL, and AQS? The connection string would be: Provider=Search.CollatorDSO;Extended Properties=\"Application=Windows\"

Comments

  • You could write a query like this:

    using (var connection = new OleDbConnection ("Provider=Search.CollatorDSO;Extended Properties=\"Application=Windows\""))
    {
        connection.Open();
        var cmd = connection.CreateCommand();
        cmd.CommandText = @"SELECT TOP 10 System.ItemPathDisplay, System.ItemUrl FROM SYSTEMINDEX WHERE System.ItemType = '.config'";
        cmd.ExecuteReader().Dump();   // LINQPad lets you Dump a DataReader
    }
    

    Be sure to add System.Data.OleDb to the Additional Namespace Imports property tab (Ctrl+Shift+M).

    Also note that in LINQPad 6 you will need to add a reference to the NuGet package System.Data.OleDb.

  • Thank you for your help.
    Since the Windows search index allows SQL syntax, can you make this a first class citizen in the next version of LINQPad, so we can enter Search queries into the SQL window? A separate AQS window would be even better!

  • Hi Joe, is this still the only way to do it or does LINQPad support it as a first class citizen yet? I experimented both with the default data context and the LINQ to DB (DataConnection) 3rd-party context and couldn't get it to work... thanks!

  • JoeAlbahari
    edited March 2022

    There's no custom driver for this. You could make it easier to use by writing a query such as this:

    void Main()
    {
        // Test call:
        WinSearch (@"SELECT TOP 10 System.ItemPathDisplay, System.ItemUrl FROM SYSTEMINDEX WHERE System.ItemType = '.config'").Dump();
    }
    
    IEnumerable<IDataRecord> WinSearch (string query)
    {
        var connection = new OleDbConnection ("Provider=Search.CollatorDSO;Extended Properties=\"Application=Windows\"");
        connection.Open();
    
        var cmd = connection.CreateCommand();
        cmd.CommandText = query;
    
        var result = cmd.ExecuteReader (CommandBehavior.CloseConnection).Cast<IDataRecord> ();
    
        return Finally (result, () => connection.Close ());
    
        static IEnumerable<T> Finally<T> (IEnumerable<T> input, Action onFinally)
        {
            try { foreach (var element in input) yield return element; }
            finally { onFinally (); }
        }
    }
    

    Save it to something like WinSearch.linq, then you can access the WinSearch method from any query with #load WinSearch. The advantage of doing this way is that the query can also connect to a database at the same time.

    Here's a demo that gives an interactive experience:

    #load "WinSearch"
    
    var results = new DumpContainer();
    var editor = new LINQPad.Controls.TextArea ("", 100, e => results.Content = Util.Try (() => WinSearch (e.Text))).Dump ("Query");
    editor.Styles["font-family"] = "Consolas";
    
    results.Dump ("Results");
    
  • Thanks Joe! As my workaround I just used Dapper as my ORM and it worked well enough, next best thing to native support, thanks for the code sample though, there's some cool stuff in there!