A customer reported problems launching
the default Web browser with the
ShellExecuteEx function:
int _tmain(int argc, _TCHAR* argv[])
{
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(sei);
sei.nShow = SW_SHOWNORMAL;
sei.lpFile = TEXT("www.microsoft.com");
sei.fMask = SEE_MASK_CLASSNAME;
sei.lpVerb = TEXT("opennew");
sei.lpClass = TEXT("htmlfile");
ShellExecuteEx(&sei);
return 0;
}
This fails with sei.hInstApp = SE_ERR_FNF.
If you don’t pass the SEE_MASK_CLASSNAME flag and
leave lpClass = NULL,
then the ShellExecuteEx function will try to
figure out what your lpFile refers to,
looking at the file extension,
looking for the file on the PATH,
and if all else fails,
trying some autocorrection.
In this case, the customer was relying on the autocorrection,
since they left the http:// prefix off their URL.
One of the default autocorrection rules is that if the item that couldn’t
be launched begins with www, then try again with
http:// in front.
On the other hand,
if you pass an explicit lpClass,
then no name resolution is performed on the lpFile.
You’re saying “Don’t do any sniffing and poking and autocorrection.
I have already determined that this item should be executed according
to the rules specified for
HKEY_CLASSES_ROOT\htmlfile,
so just follow the rules and don’t question me.”
No second-guessing means that the ShellExecuteEx
function shrugged its shoulders and said,
“Well, I don’t see a file called www.microsoft.com
in the current directory, so I will fail with a file-not-found error.”
If you pass an explicit class, then
ShellExecuteEx will
treat your lpFile as if it were a file of that type.
If you have something and you want all the standard detection logic
to kick in, then don’t specify a class.
Bonus reading: The above program is simplified to illustrate the topic. A real-life version of this program needs some other scaffolding.
0 comments