Now that Windows XP is dead we can feel free to make wider use of new features of Windows introduced nearly 8 years ago. One of these that I see almost no use of by VB6 programmers is the ability to query the indexes maintained by Windows Search. Sad, because it is really pretty easy.
I think the easiest way to make use of Windows Search programmatically is to use its SQL syntax via ADO and the data source object provided as part of Windows Search in Windows Vista and later. This was even made available for Windows XP SP2 if you had installed Windows Desktop Search 3.x, which might still be available to download for a few months yet.
This can be used to do simple or complex searches of disk files, Outlook email, and offline files. You can search on a number of properties and even do full-text searching of file types that have an appropriate filter installed.
Here are a few links to articles, mostly old now and mostly .Net oriented:
Of course to be of value the data you want to query on needs to be in an indexed location. For example Program Files normally isn't indexed, while the Users area generally is. Indexed locations are determined administratively via the Indexing Options, which you can find in the Control Panel.
Indexing Options
The sample code in the attached demo is an example of some basic use of Windows Search queries. Here you can specify a target folder (or none, meaning all indexed locations on all drives) and an optional list of file names to look for, as well as a limit for the number of hits to report:
Find all "readme.txt" in "d:\Downloads"
When the results are returned the demo lists out the requested property values in a flexgrid:
24 hits
In addition to the documentation on MSDN, I find the propkey.h header file from the Vista SDK quite helpful. The Windows 7 SDK should have a newer version of the same file.
If you want to use this mechanism for Content serching (using the CONTAINS() and FREETEXT() predicates) you may want to add IFilters or "filter packs" for various file formats.
Some versions of Adobe Reader install a PDF IFilter while others don't. For some scenarios you may need the 64-bit version which doesn't install with Reader, and these can be downloaded from Adobe's site.
thank you - this is very interesting and i have it working against my local search index.
Do you know how to query the index from a server too?
i have installed the Windows Search service on a Server2012R2 and can query it from my local explorer, so it must be accessible.
But i did not find how to get the correct connection-string for remote catalogs (and their name?)
Any Ideas welcome.
never mind - i found it myself while further experimenting.
to query indexes of other machines, you just prepend 'SystemIndex' with the machine-name,
and for the scope you use UNC-paths.
so the interesting part looks like:
SELECT ... FROM machinename.SystemIndex WHERE SCOPE='file://unc-path' AND FREETEXT('TextToFind')
Sorry I'm not too familiar with SQL; I understand the need to filters to search within files, but how do you search just the file names? e.g. *.txt
So for file names changing System.ItemNameDisplay= to System.ItemNameDisplay LIKE works. What about searching other columns in comination... like document types, image types, or checking dates? In principle I think you'd just add more System.whatever operators... I'm not too sure on specifics though.. just use standard operators? as in System.Size > n bytes?
Regarding propkey.h... any of those are supposed to be available to search results? Or just the immediate System.x group. Because I tried System.Photo.EXIFVersion and got an error.
Related question: How to get System.x property key from shell32 / ishellfolder GetDetailsOf column id? Alternatively a way to enumerate properties for column selection. I'll make a separate thread about it at some point but since it's a very closely related topic I'll ask here too.
Last edited by fafalone; Nov 15th, 2014 at 05:07 AM.
Regarding propkey.h... any of those are supposed to be available to search results? Or just the immediate System.x group. Because I tried System.Photo.EXIFVersion and got an error.
I don't know of a reason why that should fail, but it seems to. The error seems to indicate that there is "no such column" in the underlying datastore.
Originally Posted by fafalone
Related question: How to get System.x property key from shell32 / ishellfolder GetDetailsOf column id? Alternatively a way to enumerate properties for column selection. I'll make a separate thread about it at some point but since it's a very closely related topic I'll ask here too.
Seems pretty off-topic to me.
However, as pointed out in many other posts here on FolderItem.ExtendedProperty() use you can either pass the imprecise PKEY strings or the exact SCID strings derived from FMTID:
Code:
'From Windows SDK header file propkey.h:
Private Const SCID_Image_BitDepth As String = "{6444048F-4C8B-11D1-8B70-080036B11A03},7"
Private Const SCID_Image_Dimensions As String = "{6444048F-4C8B-11D1-8B70-080036B11A03},13"
Private Const PKEY_Photo_EXIFVersion As String = "System.Photo.EXIFVersion"