Brandon Live!

Desktop Search FAQ   |   Start++   |   Contact Me

Getting the shell to run an application for you - Part 2: How

April 27, 2008 at 2:07 am
Windows Shell, Windows Vista

The key to getting Explorer to do your dirty work lies in the IShellDispatch2 interface.  Particular, the ShellExecute method

IShellDispatch2 is one of the shell automation objects used to support scripting languages.  However, that doesn’t mean you have to use VBScript to gain some value from it.  In this case, IShellDispatch2::ShellExecute is exactly what we want, because it wraps the normal ShellExecute call but runs it from the context of the object implementing the interface - in this case, we want the IShellDispatch2 associated with the desktop shell.

Knowing this is only half the battle, though.  The next trick is to figure out just how to get to the right IShellDispatch2 object (the one for the desktop shell instance of Explorer.exe).

Fortunately, one of our architects, Chris Guzak (seen on C9 here), was able to point me in the right direction and connect up all the dots.

Our hunt begins with the IShellWindows interface, which can be used not only to reliably find the HWND for the desktop shell window, but also to get an IDispatch interface for it:

IShellWindows *psw;
    HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw));
    if (SUCCEEDED(hr))
    {
        HWND hwnd;
        IDispatch* pdisp;
        VARIANT vEmpty = {}; // VT_EMPTY
        if (S_OK == psw->FindWindowSW(&vEmpty, &vEmpty, SWC_DESKTOP, (long*)&hwnd, SWFO_NEEDDISPATCH, &pdisp))
        {

Next, we need the IShellBrowser interface, and we get that by querying for IServiceProvider and asking the SID_STopLevelBrowser service for an IShellBrowser interface.  And from there we can get the IShellView.

IShellBrowser *psb;

hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb));
if (SUCCEEDED(hr))
{
    IShellView *psv;
    hr = psb->QueryActiveShellView(&psv);

From there we need to get to that IShellDispatch2 interface that started this whole adventure. 

IDispatch *pdispBackground;
HRESULT hr = psv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&pdispBackground));
if (SUCCEEDED(hr))
{
    IShellFolderViewDual *psfvd;
    hr = pdispBackground->QueryInterface(IID_PPV_ARGS(&psfvd));
    if (SUCCEEDED(hr))
    {
        IDispatch *pdisp;
        hr = psfvd->get_Application(&pdisp);
        if (SUCCEEDED(hr))
        {
             IShellDispatch2 *psd;
             hr = pdisp->QueryInterface(IID_PPV_ARGS(&psd));

At this point you should be able to figure out where to go from here.

If that’s not easy enough, watch out for Part 3 of this series in the next day or two.  It will contain a sample and describe how the Start++ installer makes use of it.


Getting the shell to run an application for you - Part 1: Why

April 26, 2008 at 5:39 pm
Windows Shell, Windows Vista

Some people seem to think that calling ShellExecute or ShellExecuteEx and passing the path to an executable will have the effect of telling the shell to launch an application for you.  However, that’s not quite what happens.  These functions simply allow your application to take an action (like launching a process) in the manner the shell typically would (for instance, recreating the behavior of using the Run box).

What’s the difference?  Well, child processes inherit several things from their parents.  They inherit processor affinity, for example.  Most important these days, it seems, is the fact that processes inherit Integrity Level from the process that started them.  That is, except in the case of elevation from medium to high IL (the operation that causes the UAC dialog to appear).

So let’s say you write an installer, and you want to run the application installed at the end of the installation process.  Or heck, maybe you just want to call the application once with a special “/setup” parameter that tells it to do something you couldn’t do from your chosen setup utility.

Where do problems begin?  Well, installers typically run with admin rights.  When your installer launches your application as a convenience to the user, it’s now running with admin rights.  The primary concern here isn’t even the security implications of running at high IL.  After all, the next time your program starts it will run at its normal privilege level.

The problem is that your program is now running in a manner you may not have accounted for when writing it.  For example, users won’t be able to drag-and-drop anything to your application from normal processes.  If your program interacts with other non-admin processes, you may face other problems.  My own Start++ application faced this problem, as it needs to inject a small amount of code into Explorer.exe and then communicate with that code to coordinate its magic.  It can’t do this when running as an admin.

The recent 0.8.x release of Start++ solved this issue, and Start++ now runs immediately after install, in the proper non-admin context.  This is accomplished by having Explorer launch the application on the installer’s behalf. 

Others have addressed this problem in the past.  However, the proposed solutions always seem to take one of these forms:

  1. Write an invoker process that runs with non-admin privileges, starts the elevated installer, and then runs your app at the end.
  2. Use the task scheduler to launch the app.
  3. Inject some code into Explorer and launch from there.

I don’t like #1 because it’s cumbersome and limits how you can name your installer.

#2 also seems cumbersome to me, and is a bit hacky.

#3 is totally hacky, and not something I trust people to do without accidentally destabilizing Explorer (there’s a reason the code Start++ injects into Explorer is incredibly tiny and very carefully crafted).  It can also introduce complications when dealing with multiple target platforms (x86 versus x64).  For example, the CodeProject sample linked to above doesn’t even restrict its WH_CALLWNDPROCRET hook to the thread that it’s targetting.  That means this hook code is immediately going to be loaded by every process on the desktop with a window.  Yuck.

Fortunately, there is a better way.

In Part 2, I describe a better way to get Explorer to run code for you, without having to inject anything into Explorer or use cumbersome workarounds like those described above.


Remote Search in Windows Search 4.0

March 29, 2008 at 4:56 pm
Desktop Search, Microsoft, Search, WS4, Windows Shell, Windows Vista

Following up on the Windows Search 4.0 Preview release, I will be writing several posts about some of the new features and changes enabled by this release.  One such feature, and this first one I will dive into here, is the capability to remotely search the index of another Windows PC.

This features isn’t entirely new.  Windows Vista shipped nearly a year and a half ago with the ability to query the index of another Vista machine when searching file shares.  The same capability extends to and from Windows Server 2008.

Windows Search 4.0 brings this capability to Windows XP machines, as well as Server 2003 - and perhaps more importantly, Windows Home Server.

So how does it work?  First let’s take a look at how the user sees it.  Let’s say I have a folder on Machine A called “Cool Stuff” that I want to share out.  One simple way to do that is to browse to the folder in Explorer, select it, and click “Share.”

sharecoolstuff

You’ll then get a friendly dialog that asks you who you’d like to share with.

 ShareCoolStuff2

“Everyone” is a simple answer for information you want to be accessible to everyone.  Select it from the drop-down and click “Add” to add Everyone to the list of people the folder is shared with.

ShareCoolStuff3

What else do I have to do on Machine A?  Nothing!  Windows Search 4.0 will automatically index any folders you share out, on both XP and Vista.

On Machine B, you simply navigate to the share as you normally would.  That could mean typing a UNC like \\MachineA\Cool Stuff\ or it could mean using a mapped drive, redirected User folders, the Network browser, etc.  Once there, just type a query in the Search box (or on XP, click the “Search” button to bring up the Search Pane) and you’re off!

  SearchMachineA

Unfortunately I don’t have any XP machines to get a screenshot from, but I’ll try to add one soon.


Windows Search 4.0 Preview release

March 27, 2008 at 6:21 pm
Desktop Search, Microsoft, News, Search, WDS Development, Windows Shell, Windows Vista

Today we made available the WS 4.0 preview release for Windows XP, Vista, and Server 2003/2008.  You can read details about WS 4.0 at the following sites:

Vista Team Blog - Announcing the Windows Search 4.0 Preview

KB Article describing Windows Search 4.0 (with download links)

This release is mainly an update to the Windows Search indexer, and provides countless performance improvements, bug fixes, and reliability / recoverability features.

The XP/2003 version has been updated with more features previously exclusive to Vista - such as the ability to search remote indexes for network shares, and the ability to host Vista-style preview handlers in the preview pane.

WS4 also provides some cool new query capabilities for developers, which I will describe and give some examples of in future posts.

The most noticeable difference is probably how fast it is.  Those geniuses down the hallway in indexer land really pulled off some impressive feats with this release.

Since there are six different downloads depending on your OS, I’ll just refer you to the KB article for downloading the preview release.

Let us know what you think!


Indexed folders rely on the index being complete

March 16, 2008 at 3:54 pm
Desktop Search, Microsoft, Search, WDS FAQ, Windows Shell, Windows Vista

Let’s say you want to optimize your system by only indexing certain data.  For example, a reader recently e-mailed me and said “I only want to index my media files.”  Seems like a valid choice.  At first glance, it might seem like you could achieve this by telling Windows to only index files with extensions like .mp3 and .avi.  Ultimately, this is a very bad idea.

First, let me tell you why this is a bad idea.  Second, I’ll tell you the right way to achieve what you want.

Let’s begin by looking at how the Windows Vista shell and the indexer work together.

The indexer maintains a list of “start paths” - which are locations in the shell namespace that it cares about.  By default, it is set up to index the x:\Users directory - and thus all of the default Documents / Music / Pictures folders of all user accounts on the system.  When you install Outlook, it sets up a start path for your mail accounts.  OneNote sets one up for your OneNote data.  And so on.  This means that the indexer will try to index all items under that path*, and ignore everything else.

When you browse to a folder in Explorer, the shell asks the indexer if the current path is covered by the index.  If it is, Explorer will use the index exclusively for search / filter / grouping operations against that location.  It does not ask the index if it covers all the file types in that location.  It assumes the index is the authoritative source for information about that part of the namespace.

On the other hand, if the path is not covered by the index, Explorer walks the entire namespace starting at that location (so, the current folder and all subfolders) and enumerates every single item, performing all operations like filtering / sorting / grouping in-memory.  By default, it does not crack open any files being enumerated - so all filtering operations happen only against the basic properties like file name.  You can then click the “Search in File Contents” button (what some of us call the “try harder” button), and it will repeat the operation - stopping at every file and cracking it open with the appropriate IFilter and property handlers, doing essentially the same thing that happens when a file is indexed.  It loads the file, cracks it open, extracts all the properties and content, checks to see if it matches the current filter, and then decides whether or not to add that item to the view or ignore it.  If you change the filter, the whole process starts over again.  Needless to say, this is rather slow if you have to do it for more than a few files.  That’s why the “Search in File Contents” button is there, since in most unindexed locations (like C:\windows) you are probably only searching for a filename.

Armed with this information, let’s take another look at the original question.  Let’s say you go into the Advanced options for the indexer and tell it not to index .doc files at all.  Then you go save a new document called Something.doc inside of your Documents folder, which is still indexed.  The indexer will be notified that a new file was created there, but since you disabled indexing of that extension, it will ignore it.  Then when you go to your user folder or the Documents folder and search for “something” - you don’t find the document.  Even though it’s right there in the name.  The folder said “Hey, I’m indexed” and the file is not in the index, so as far as Explorer is concerned, it doesn’t exist.

A much better approach, if you really don’t care about indexing your .doc files, is to tell Windows not to index the Documents folder (or wherever you keep your .doc files).  That way it will fall back to slow GREP search when you look there, which will at least find what you’re looking for, albeit more slowly.

You can do this from the Indexing Options control panel, and it’s pretty easy to do.  Only want your music and videos indexed?  Then tell the indexer to only crawl the places where you store those files.  That it’s, mission accomplished.

The end result is the same.  The indexer isn’t doing any additional work, unless you mix .doc files and media files in the same folder.  And even then, at least you’ll be able to find them.

Another option available to you is to set certain extensions to “Index File Properties only.”  That way you’ll at least be able to find the item by its name.  Why would you want to do that?  I have no idea.  It’s not like indexing files incurs a significant overhead on any reasonably modern PC.  The option is mainly there because there are some file types the indexer can’t search inside.  So instead it indexes all the basic stuff that applies to every file (like name, date modified, and size).

* = It’s actually more complicated than that, as there can be nested inclusion/exclusion rules, files or folders excluded based on attributes, etc.  But that’s not particularly relevant to this discussion


FAQ: Office 2007 documents, kind:document, and 64-bit Windows

November 29, 2007 at 2:54 pm
Desktop Search, WDS FAQ, Windows Shell, Windows Vista

If you’re running a 64-bit version of Windows Vista, or a 64-bit version of WDS 3.x on Windows XP/2003, you may notice that the new Office 2007 document formats (.docx, .xlsx, etc) don’t show up when you search using the “Documents” filter in the search UI, or the kind:document Advanced Query Syntax.

This is a known issue with the 64-bit property system, and happens because the 64-bit shell only looks in the 64-bit section of the registry for a set of keys that map file extensions to various “kinds” for filetypes that don’t emit their own “kind” information.  Because Office 2007 is a 32-bit application, it registers its kinds in the 32-bit section of the registry, where the shell never sees it.

In a future release, the shell / search engine will be updated to better handle this situation.  For now, I have uploaded a .reg file which will fix the KindMap for Office 2007 documents on 64-bit machines.

Disclaimer Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall your operating system. I cannot guarantee that these problems can be solved. Modify the registry at your own risk.

Click here for the workaround reg file


PDF IFilter for 64-bit Windows

May 2, 2007 at 3:51 pm
Desktop Search, Windows Shell, Windows Vista

Since Adobe has been slacking and not supporting x64 versions of Vista or Windows Desktop Search, it’s very nice to see FoxIt once again stepping up and getting things done.

I’m very pleased to share that FoxIt (creators of the excellent FoxIt PDF Reader) have released version 1.0 of their PDF IFilter, including both 32-bit and 64-bit versions.  They also helped develop a PDF previewer for Outlook 2007.  Go FoxIt!


New Windows Search SDK is live!

March 13, 2007 at 2:03 pm
Desktop Search, News, Search, WDS Development, Windows Shell, Windows Vista

The new Windows Search SDK for Windows Vista and Windows Desktop Search 3.x is now available on MSDN!

We’ve also released a new set of code samples to go along with it.

I’ll be digging in and writing more about building on the SDK very soon!


WDS 3.01 has shipped!

February 20, 2007 at 4:44 pm
Desktop Search, News, Search, WDS Development, Windows Shell

Today we’ve released Windows Desktop Search 3.01 for Windows XP and Windows Server 2003.  This release includes many bug fixes and improvements based on user feedback received since the release of WDS 3.0 last fall.  Some users noticed the lack of UNC / network share indexing support in WDS 3.0 and insisted we put it back.  So we did!  The UNC / network share add-in is no longer a seperate downloaded and is included in WDS 3.01.

WDS 3.01 also brings back full Group Policy support (previously available in the WDS 2.6 Enterprise releases). 

Special congratulations to the indexer team, many of whom worked some pretty heavy hours through January to make sure this release had that extra layer of polish on it.  Thanks guys!  Now go home already!

Download links:

Windows XP 32-bit

Windows Server 2003 (32-bit)

Windows XP/2003 x64 Editions

Group policy ADM file is included in the package.  Run the installer with the /extract parameter to extract the contents directly.

There’s also an updated Advanced Query Reference for 3.x / Vista.

The WDS website and related docs are in the process of being updated as I write this.


Cupertino, start your copiers!

February 11, 2007 at 6:14 pm
Apple, Desktop Search, Macintosh, Windows Shell, Windows Vista

Ryan Faas has an article up highlighting the upgraded Spotlight feature of Apple’s upcoming “Leopard” 10.5 release of OS X.  It’s got some really cool stuff coming, including:

Those are all really great features!  I just can’t put my finger on it, but for some reason I feel like I’ve seen them before.


[powered by WordPress.]

Hi. I'm Brandon. I'm a geek, and I work on Search technology for Windows at Microsoft. This is my blog.

RSS Button

Picture

categories:

archives:

May 2008
M T W T F S S
« Apr    
 1234
567891011
12131415161718
19202122232425
262728293031  

search this site:

The views expressed within my blog are my own - and are not in any way indicative of those of the company I work for, Microsoft, or it's employees. No warranties or other guarantees will be offered as to the quality of the opinions or anything else offered here.

Xbox Live GamerCard

Most popular searches that brought people here today:

search (11)start++ (9)an expression
contains an inva
(2)windows desktop
search rebuild
(2)trackpad driver
macbook pro
(2)brandon live (2)itunes 64 bit
download
(2)brandontools.com (2)Paths regedit wds (2)windows desktop
search shared
(2)