views:

153

answers:

3

On success, ShellExecute returns a handle.

Do we need to close this handle, and if so, how ?

According to examples published my Microsoft, we need not close this handle. But the doc of ShellExecute itself is mute on the subject. Can you confirm we indeed do not need to close this handle ?

But then, how can a handle be valid and in no need of being closed ??? Which of the following statements is/are true:

  1. the handle is invalid and we can't do anything with it;
  2. the handle is never freed and there is a (Microsoft-sponsored) memory leak (until the caller program ends);
  3. the handle is automatically freed by the system at some time and never reused afterwards (-> another kind of resource leak). Only on trying to use it can we know whether it still points to something.
  4. what else ?
+3  A: 

Taken from: http://msdn.microsoft.com/en-us/library/bb762153%28VS.85%29.aspx

If the function succeeds, it returns a value greater than 32. If the function fails, it returns an error value that indicates the cause of the failure. The return value is cast as an HINSTANCE for backward compatibility with 16-bit Windows applications. It is not a true HINSTANCE, however. It can be cast only to an int and compared to either 32 or the following error codes below.

Jens Granlund
OK thank you. So that's my hypothesis 1.
Looks like I hadn't read all the fine print in Microsoft's documentation ;-) The answer was right under my eyes but didn't get to my brain...
@fred-hh, you´r welcome, it happens to all of us :)
Jens Granlund
+2  A: 

That hinstance is a 16 bit thing, in win32, it is just a number > 32 on success and can't be used for anything other than as an error code when the function fails. On the other hand, if you pass SEE_MASK_NOCLOSEPROCESS to the Ex version, you have a handle you need to close.

Anders
Thank you for your additional remark on the Ex version.
A: 

I clear a little what is HINSTANCE and HMODULE. This are not a HANDLE, but much more as a memory address (pointer). You can understand this if you just cast a hInstance to (IMAGE_DOS_HEADER *) and look inside of the loaded module. You can use VirtualQueryEx (GetCurrentProcess(),...) to receive more information (a size for example) from a memory address.

Look at http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx and http://www.apriorit.com/our-experience/articles/9-sd-articles/74-hmodule-hinstance-handle-from-static-library-in-c and you will be see how you can receive a HINSTANCE from a memory address (__ImageBase).

So if you LoadLibrary for example you receive a HMODULE (it's the same as HINSTANCE). You should use FreeLibrary not to "close handle", but to unload module from memory. If you use GetModuleHandle for example, you receive also the same address (you receive address casted as HMODULE), but you should NOT call FreeLibrary to "close the handle".

If you understand what is HINSTANCE and HMODULE and how they should be used, you will be know how to use HINSTANCE returned from ShellExecute.

Oleg
You are not answering the question... as other answers tell me, the value returned from ShellExecute is not a real handle so knowing how real handles work won't help me! Besides, you're wrong, AFAIK. FreeLibrary only closes a handle (i.e., I guess, decrements the reference count of the object or something similar). Only when all handles are closed is the object itself (here the DLL) freed. GetModuleHandle returns the handle without incrementing the reference count, that's why FreeLibrary should usually not be called on that handle. (see documentation of GetModuleHandle)
You should no time "close" HINSTANCE. It is **not** a Windows handle (see in Task Manager column Handles). ShellExecute is a wrapper to CreateProcess and it gives you back no hProcces handle. It close it for you. If you have an interest to see how approximately implementation of ShellExecute look like see http://svn.reactos.org/svn/reactos/branches/reactx/reactos/dll/win32/shell32/shlexec.c?view=markup from the ReactOS project. The reference counters for DLL (HMODULE) have another nature as handle. Try to find a "close" API for HINSTANCE (like CloseHandle). There are no such API at all!!!
Oleg