You can use Windows Search to query the Index programmatically in a number of ways:
Note  Microsoft Windows Desktop Search (WDS) 2x compatibility note: In Windows Search on Microsoft Windows XP and Windows Vista,
ISearchDesktop is deprecated. Instead, developers should use
ISearchQueryHelper to get a connection string and to parse the user's query into Structured Query Language (SQL), then query via OLE DB.
Using OLE DB
OLE DB (Object Linking and Embedding Database) is a Component Object Model (COM)Â API that enables you to access different types of data stores uniformly, including non-relational databases like spreadsheets. OLE DB separates the data store from the application accessing it through a set of abstractions that include the datasource, session, command and rowsets. An OLE DB provider is a software component that implements the OLE DB interface in order to provide data from a given data store to other applications.
The Windows Search OLE DB provider is read-only, supporting SELECT and GROUP ON statements. It does not support INSERT and DELETE statements. You can access the Windows Search OLE DB provider programmatically using the OleDbConnection and OleDbSession objects in C# and using the OLE DB support built into Active Template Library (ATL) in C++ (via atlclidb.h). The only property that has to be set is the provider string. You can use the string 'provider=Search.CollatorDSO.1;EXTENDEDÂ PROPERTIES="Application=Windows"' or get the connection string by calling ISearchQueryHelper::get_ConnectionString.
#include <atldbcli.h>
CDataSource cDataSource;
hr = cDataSource.OpenFromInitializationString(L"provider=Search.CollatorDSO.1;EXTENDED PROPERTIES=\"Application=Windows\"");
if (SUCCEEDED(hr))
{
CSession cSession;
hr = cSession.Open(cDataSource);
if (SUCCEEDED(hr))
{
CCommand<CDynamicAccessor, CRowset> cCommand;
hr = cCommand.Open(cSession, pszSQL);
if (SUCCEEDED(hr))
{
for (hr = cCommand.MoveFirst(); S_OK == hr; hr = cCommand.MoveNext())
{
for (DBORDINAL i = 1; i <= cCommand.GetColumnCount(); i++)
{
PCWSTR pszName = cCommand.GetColumnName(i);
// do something with the column here
}
}
cCommand.Close();
}
}
}
For more information on OLE DB, please refer to OLE DB Programming Overview. For information on the .NET Framework Data Provider for OLE DB, refer to System.Data.OleDb namespace documentation.
Using ISearchQueryHelper
You can develop a component or helper class to query the index using the ISearchQueryHelper interface, which enables you to take advantage of some features of the system and simplify your use of Windows Search. This interface helps you:
- Obtain an OLE DB connection string to connect to the Windows Search database.
- Convert user queries from AQS to Windows Search SQL.
This interface is implemented as a helper class to ICatalogSearchManager and is obtained by calling ISearchCatalogManager::GetQueryHelper, as shown in the following C++ snippet.
HRESULT GetQueryHelper(ISearchQueryHelper **ppQueryHelper)
{
*ppQueryHelper = NULL;
// Create an instance of the search manager
ISearchManager *pSearchManager;
HRESULT hr = CoCreateInstance(__uuidof(CSearchManager), NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pSearchManager));
if (SUCCEEDED(hr))
{
// Get the catalog manager from the search manager
ISearchCatalogManager *pSearchCatalogManager;
hr = pSearchManager->GetCatalog(L"SystemIndex", &pSearchCatalogManager);
if (SUCCEEDED(hr))
{
// Get the query helper from the catalog manager
hr = pSearchCatalogManager->GetQueryHelper(ppQueryHelper);
pSearchCatalogManager->Release();
}
pSearchManager->Release();
}
return hr;
}
Please refer to Using the ISearchQueryHelper Interface for more information on implementing the ISearchQueryHelper interface or to ISearchQueryHelper for complete documentation on the interface itself.
Using Windows Search SQL Syntax
The Windows Search SQL query language used by Windows Search extends the standard SQL-92 and SQL-99 database query syntax to enhance its usefulness with text-based searches. All features of Windows Search SQL are compatible with Windows Search on both Windows Vista and Windows XP.
Please refer to Overview of the Search SQL Syntax for detailed information on the Windows Search SQL syntax.
Using the search-ms Protocol
The search-ms application protocol is a convention for launching an application, like Windows Explorer, to query the Windows Search index. It allows queries to be built with parameter-value arguments, including property arguments, previously saved searches, Advanced Query Syntax, Natural Query Syntax, and language code identifiers (LCIDs) for both the Indexer and the query itself.
Please refer to Using the search-ms Protocol for detailed information on the search-ms protocol syntax.
Using Advanced Query Syntax
The Advanced Query Syntax (AQS) is used by Windows Search to help users and programmers better define and narrow their searches. Using AQS is an easy way to narrow searches and deliver better result sets. Searches can be narrowed by the following parameters:
- File kinds: folders, documents, presentations, pictures and so on.
- File stores: specific databases and locations.
- File properties: size, date, title and so on.
- File contents: keywords like "project deliverables," "AQS," "summer vacation 2007," and so on.
Please refer to Advanced Query Syntax for detailed information on the AQS syntax.
Querying Remotely
On Vista, you can query the local index of a remote machine for file system items (items handled by the file: protocol). To retrieve an item by remote query, the item must:
- Be accessible via Universal Naming Convention (UNC) path
- Exist on the remote machine the client has access to
- Have its security set to allow the client read access
The Windows Vista Explorer has features for sharing items including a "Public" share (\\Machine\Public\...) in the Network and Sharing Center and a "Users" share (\\Machine\Users\...) for items shared via the Sharing Wizard. After you share the folder(s), you can query the local index by specifying the remote machine's machine name in the FROM clause and a UNC path on the remote machine in the SCOPE clause:
SELECT System.ItemName FROM MachineName.SystemIndex WHERE SCOPE='file://MachineName/<path>'
Using ADO and ADO.NET
Microsoft ActiveX Data Objects (ADO) and ADO.NET enable you to write client applications to access and manipulate data in a database server through a provider. Windows Search is a read-only technology: you can retrieve data using Desktop Search but you can't change data using Windows Search. You can, however, pass the results of a search over to a technology that can change data.
The following code snippets demonstrate how to open a connection to the data source, create and open a RecordSet with a Windows Search SQL SELECT statement, and get the URLs of the five largest files from the Index.
ADO and VBScript
'To run this snippet, save it to a file and run it using cscript.exe from a command line.
'Running the .vbs file with Windows Script Host may cause dialog boxes to open for each item returned from the index.
On Error Resume Next
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")
objConnection.Open "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
objRecordSet.Open "SELECT Top 5 System.ItemPathDisplay FROM SYSTEMINDEX", objConnection
objRecordSet.MoveFirst
Do Until objRecordset.EOF
Wscript.Echo objRecordset.Fields.Item("System.ItemPathDisplay")
objRecordset.MoveNext
Loop
ADO and C++
#import <msado15.dll> no_namespace rename("EOF", "ADOEOF")
ADODB::_ConnectionPtr connection = NULL;
hr = connection.CreateInstance(__uuidof(ADODB::Connection));
ADODB::_RecordsetPtr recordset = NULL;
hr = recordset.CreateInstance(__uuidof(ADODB::Recordset));
connection->CursorLocation = ADODB::adUseClient;
connection->Open(L"Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
L"Initial Catalog=SYSTEMINDEX;User Id=<username>;Password=<password>;", L"",
L"", ADODB::adConnectUnspecified);
recordset->Open("SELECT Top 5 System.ItemPathDisplay FROM SYSTEMINDEX",
connection.GetInterfacePtr(), ADODB::adOpenForwardOnly, ADODB::adLockReadOnly, ADODB::adCmdText);
while(!recordset->ADOEOF)
{
_variant_t var;
var = recordset->Fields->GetItem(L"System.ItemPathDisplay")->GetValue();
std::cout << static_cast<char *>(_bstr_t(var.bstrVal)) << std::endl;
recordset->MoveNext();
};
recordset->Close();
connection.Close();
ADO.NET and VisualBasic
Dim con As ADODB.Connection
Dim rst As ADODB.Recordset
Set con = New ADODB.Connection
Set rst = New ADODB.Recordset
Dim sConString As String
Dim sSQLString As String
sConString = "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
con.Open sConString
sSQLString = "SELECT Top 5 System.ItemPathDisplay FROM SYSTEMINDEX"
Set rst = con.Execute(sSQLString)
Do Until (rst.EOF)
Print(1, rst("System.ItemPathDisplay").Value);
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing
ADO.NET and C#
OleDbConnection conn = new OleDbConnection(
"Data Source=(local);Initial Catalog=Search.CollatorDSO;Integrated Security=SSPI;User ID=<username>;Password=<password>");
OleDbDataReader rdr = null;
conn.Open();
OleDbCommand cmd = new OleDbCommand("SELECT Top 5 System.ItemPathDisplay FROM SYSTEMINDEX", conn);
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(rdr[0]);
}
rdr.Close();
conn.Close();
Â
Related Topics