Monday 13 August 2012

Impersonating a SharePoint search

Here is code which will run a SharePoint search and return the results in a StreamWriter object, which can be outputted to a file. Hook it up to a console app and off you go!
Note 
-  you must specify a row limit or it will only return the first 50 results
-  user under which it runs will need to have read access to the content database containing the Central Administration Shared Services. This is usually called SharedServices1_DB or some such variant. Error logs will indicate very clearly if that error occurs so make sure to have good error handling
- Microsoft.Office.Server.Search.Query is another one of those annoying DLLs that is impossible to find. It's not one of the SharePoint dlls - you might find it in the ISAPI folder or otherwise in the list of other .NET dlls.

using System.IO;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.Office.Server;
using Microsoft.Office.Server.Search;
public class SearchResults
    {
        public string errorArgs;
        public SearchResults()
        {
            //constructor don't do nuthin'
            errorArgs = string.Empty;
        }
        protected DataTable ReturnSearchResults(string searchCriterion, string siteUrl)
        {
            DataTable dt = new DataTable();
           
            try
            {
               //Available fields: Title,FileExtension,ContentType,Created,LastModifiedTime,IsDocument,owsStartDate,Path
                
                searchCriterion = searchCriterion.Replace(" ""+");
                string fullTextSQL = "SELECT Title, FileExtension, ContentClass, ContentType, Created, URL FROM SCOPE() ";
                fullTextSQL = fullTextSQL + "WHERE CONTAINS ('" + searchCriterion + "') ";
                //do whole site for the moment
                using (SPSite site = new SPSite(siteUrl))
                {
                    errorArgs = "accessing office search component";
                    Microsoft.Office.Server.Search.Query.FullTextSqlQuery search = newMicrosoft.Office.Server.Search.Query.FullTextSqlQuery(site);
                    Microsoft.Office.Server.Search.Query.ResultTableCollection results;
                    //configure the query - limit it to 50 for the moment
                    errorArgs = "preparing search";
                    search.QueryText = fullTextSQL;
                    search.ResultTypes = Microsoft.Office.Server.Search.Query.ResultType.RelevantResults;
                    search.RowLimit = 1000;
                    search.TrimDuplicates = true;
                    results = search.Execute();
                    errorArgs = "search successful";
                    if (results.Count > 0)
                    {
                        using (Microsoft.Office.Server.Search.Query.ResultTable relevantResults = results[Microsoft.Office.Server.Search.Query.ResultType.RelevantResults])
                        { dt.Load(relevantResults, LoadOption.OverwriteChanges); }
                    }
                    return dt;
                }
            }
            catch (Exception ex)
            {
               //handle error here
                return null;
            }
            finally
            {
            }
        }
        public StreamWriter ReturnResultsInStream(string searchCriterion, string siteUrl,FileStream fs)
        {
            try
            {
                StreamWriter stream = new StreamWriter(fs);
                DataTable results = this.ReturnSearchResults(searchCriterion, siteUrl);
                foreach (DataRow dr in results.Rows)
                {
                    foreach (object field in dr.ItemArray)
                    {
                        if (field is string)
                        {
                            stream.Write(field.ToString());
                            stream.Write(";");
                        }
                    }
                    stream.WriteLine();
                }
                return stream;
            }
            catch(Exception ex)
            {
                //HANDLE YOUR ERROR HERE
                return null;
            }
        }
    }