views:

48

answers:

1

It's been a while since I touched COM so be nice ;) This is under WindowsCE 5.0 with SQLServerCE 2.0.

After calling this to load SQLServerCE 2.0 : -

IDBInitialize *pIDBInitialize = NULL;
CoCreateInstance(CLSID_SQLSERVERCE_2_0, NULL, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void**)&pIDBInitialize);

Module load occurs for SSCE20.dll which obviously loads the SQLServerCE engine into the process space.

What I don't understand is if I do this immediately after :-

pIDBInitialize->Release();

I don't see a dll module unload, so that SSCE20.dll (and friends) are still loaded into my process.

Now I tried CoFreeUnusedLibraries() which I figure forces COM to purge any unused libraries, but it doesn't seem to do the trick.

At runtime I want to be able to completely unload the SQLServerCE 2.0 dll from the process to streamline an upgrade to 3.5SP1.

I suspect this has something to do with the shared dll model that Microsoft use under WindowsCE... but, I might be wrong :)

Thanks in advance,

David.

A: 

I think CoFreeUnusedLibraries has been stubbed out in later versions of Windows (XP and forward, if I recall correctly). That is, it doesn't do anything.

A KB article mentions undue delays when calling the function, to minimize the risk that one thread forces unload of a DLL that another is concurrently attempting to create an instance from.

It could be that they weren't happy with the delayed unload (I suppose it still presents a possible race condition), and decided to remove the functionality entirely.

You could try calling CoUninitialize and see if that forces an unload.

Kim Gräsman
Of course, CoUninitialize still can't unload if you're in an MTA -- the same restrictions apply, I guess.
Kim Gräsman
CoUninitialize() did the job, but all COM libraries are free, so it's a bit of a sledgehammer.
David Thornley
Yeah, it's not really a solution... I have a slightly sick idea, though. If you are absolutely sure that there are no outstanding references to the DLL, you could call CoLoadLibrary on the DLL filename, and then call CoFreeLibrary _twice_ on the returned handle. Since it's been loaded previously, you should get the same handle as when COM loaded it. This bears the risk that COM tries to do CoFreeLibrary later, and blows up because the handle is invalid, but it might be worth a try.
Kim Gräsman