0

Seemingly simple task: I want to open the standard Windows dialog for picking the application to be used for opening the file, and then wait for this application to finish. The internet tells that ShellExecuteEx is the way to go.

Ok, so here's the code:

    SHELLEXECUTEINFO sei;
    ::ZeroMemory(&sei,sizeof(sei));
    sei.cbSize = sizeof(sei);        
    sei.lpFile = L"path/to/document";
    sei.lpVerb = L"openas";
    sei.lpParameters = L"";
    sei.nShow = SW_SHOW;
    sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_INVOKEIDLIST ;
    BOOL ret = ::ShellExecuteEx(&sei);
    DWORD waitResult = ::WaitForSingleObject(sei.hProcess, INFINITE);

But it doesn't work: specifying SEE_MASK_INVOKEIDLIST flag makes hProcess to always be NULL, even if a new process was indeed launched.

How can this be fixed? Thanks in advance!

Alex Jenter
  • 4,324
  • 4
  • 36
  • 61
  • 3
    What you are attempting is impossible. There's no guarantee that a new process will be used. – David Heffernan Aug 07 '15 at 13:05
  • @David: Thanks for the reply! Ok, but would it be possible to get the handle at least in cases when a new process was used? – Alex Jenter Aug 07 '15 at 13:06
  • I don't know about that – David Heffernan Aug 07 '15 at 13:10
  • 3
    @AlexJenter: to be clear, you are expecting the `openas` dialog to actually launch the selected application, and then you want to wait on *that* application? Then it makes sense why `hProcess` is null, because `ShellExecuteEx()` is not the one launching the app, the dialog is. `ShellExecuteEx()` can wait on the `openas` verb to finish running the dialog (via the `SEE_MASK_NOASYNC` flag), but there is nothing to tell the dialog to wait for the launched app to exit before returning control to `ShellExecuteEx()`. Once the user closes the dialog, `openas` is done with its work. – Remy Lebeau Aug 07 '15 at 15:50
  • @RemyLebeau Thanks for the explanation. I decided to go with a different approach: monitor for file changes (to pull up updates) and cleaning up on timer. – Alex Jenter Aug 11 '15 at 04:59

1 Answers1

1

The shell was never designed to do this and even if it was it would not work 100% of the time because not everything launches a new process (DDE, IShellExecuteHook, IDropTarget, IExecuteCommand etc).

If writing your own dialog is acceptable then you might want to take a look at IEnumAssocHandlers. Raymond Chen recently did a blog post about it.

Anders
  • 97,548
  • 12
  • 110
  • 164