What is the lpClass member of SHELLEXECUTEINFO used for?

Raymond Chen

A customer reported problems launching the default Web browser with the Shell­Execute­Ex 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 Shell­Execute­Ex 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 Shell­Execute­Ex 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 Shell­Execute­Ex 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

Discussion is closed.

Feedback usabilla icon