I have a program that passes a command line to the explorer process to execute in the user's non-elevated desktop context. Part of doing that requires using IShellWindows::FindWindowSW to search for the desktop window, as can be seen in this ExecInExplorer example from the Windows 7 SDK.
If for some reason explorer is restarted (such as 'Exit Explorer' and restart [2]) and the old explorer doesn't actually exit then FindWindowSW returns S_FALSE for the desktop window. In this case the new explorer process owns the desktop and the old process (which should have terminated) does not. I suspect FindWindowSW is searching only the old explorer process.
If there are multiple explorers running is there any way to search all of them for IDispatch to the desktop?
#include <windows.h>
#include <shlwapi.h>
#include <shlobj.h>
#include <stdio.h>
#include <malloc.h>
#pragma comment(lib, "shlwapi.lib")
int main(int argc, char *argv[]) {
(argv); (argc);
init();
HRESULT hr;
IShellWindows *psw;
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw));
if (SUCCEEDED(hr))
{
HWND hwnd;
IDispatch* pdisp;
VARIANT vEmpty = {}; // VT_EMPTY
HRESULT f = psw->FindWindowSW(&vEmpty, &vEmpty, SWC_DESKTOP, (long*)&hwnd, SWFO_NEEDDISPATCH, &pdisp);
if(f == S_OK)
printf("S_OK, hwnd: 0x%lx\n", *(long*)&hwnd);
else if(f == S_FALSE)
printf("S_FALSE\n");
else
printf("0x%lx\n", f);
}
}
return 0;
}
[2]: (Sometimes when I am developing I will 'Exit Explorer' (Hold down CTRL+SHIFT and right-click on an empty part of the start menu) and then restart it from a command prompt. Occasionally explorer despite exiting (ie the taskbar disappears) doesn't actually terminate which means when I start explorer again then more than one explorer is running. The old explorer still running is not the separate process that can be used for displaying folders. I don't have a way to reproduce this, it seems arbitrary.)