-->

How to replicate ShellExecuteEx failure with ERROR

2019-08-31 07:08发布

问题:

My application displays a report to its end-users by composing it into an .htm file that is placed into a user's temp folder (that is derived by calling GetTempPath API). It is then shown to the user with the code as such:

//strCmd == file:///C:/Users/UserName/AppData/Local/Temp/My_Report.htm

SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_FLAG_NO_UI;
sei.nShow = SW_SHOW;
sei.lpVerb = L"open";
sei.lpFile = strCmd.GetBuffer();
sei.hwnd = hParentWnd;

BOOL bInitialized = SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE));

if(ShellExecuteEx(&sei))
{
    //Success
}
else
{
    //Failed
    REPORT_ERROR(GetLastError());
}

if(bInitialized)
{
    CoUninitialize();
}

I just got a bug report from a customer that shows that the code above reports ERROR_NO_ASSOCIATION. The OS from the picture I got looks like Windows 8.1, or maybe Windows 7.

So I've been trying to replicate it in a VM by removing all file associations for the .htm and .html file extensions, but ShellExecuteEx never seems to fail. On Windows 10 it always opens up Edge and on Win 8.1 it showed this popup:

Does anyone know how I can replicate that error?

回答1:

Removing .htm[l] probably has no effect because file:// is a protocol so you probably have to remove it as well.

You should try to remove HKCR\file.

This is as far as the documentation can take you but there are other undocumented keys involved in the default association selection.

For file extensions you need to remove HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.htm (or as a minimum, the UserChoice subkey)

and for protocols you need to remove HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\file. This key can exist under HKLM as well.

There might be other keys involved, you can find out where Windows looks by monitoring your application with Process Monitor from SysInternals.