Event handle leak for each office idispatch->Invoke() call

D

David Sitsky

Hi,

I have written a very simple test program below which
exhibits an event handle leak (shown with procexp.exe from
http://www.sysinternals.com and with the standard task
manager when viewing handle counts). The program simply
creates a new word instance, then invokes "quit", within a
loop.

I have noticed, that when the Invoke() call is processed,
two port handles and a single event handle are created.
When Release() is called, the two port handles are
removed, but the event handle is not being cleaned up.

This is a problem, as I am working on an application which
performs his loop, potentially up to millions of times.
The application requirements are such that a fresh
instance of word needs to be created for each iteration
(long story). The same behaviour occurs for Excel and
Powerpoint as well.

Can somebody please tell me if am I missing an appropriate
cleanup call of some kind in the code below? The leakage
occurs for both Windows 2000 (SP3) and Windows XP for both
Office 2000 and Office XP.

I have been told that running this same code on a custom
COM object doesn't have this problem, so it appears to be
something specific to the Office COM proxy objects (since
the leak is in my process).

If anyone has some ideas, that would be fantastic.

Cheers,
David

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <windows.h>
#include <oleauto.h>
#include <objbase.h>
#include <cguid.h>

int doit()
{
HRESULT hr;

CLSID clsid;
hr = CLSIDFromProgID(L"Word.Application", &clsid);
if (hr != S_OK)
{
fprintf(stderr, "ProgIDFromCLSID failed, hr = 0x%
x\n", hr);
return 0;
}

IDispatch *dispatch;
hr = CoCreateInstance(clsid, NULL,
CLSCTX_LOCAL_SERVER,
IID_IDispatch,
(void**)&dispatch);
if (hr != S_OK)
{
fprintf(stderr, "CreateInstance failed... hr = 0x%
x\n", hr);
return 0;
}

OLECHAR *arg = L"Quit";

DISPID dispid;
hr = dispatch->GetIDsOfNames(IID_NULL, &arg, 1,
LOCALE_SYSTEM_DEFAULT,
&dispid);
if (hr != S_OK)
{
fprintf(stderr, "GetIds failed, HR = 0x%x\n", hr);
return 0;
}

// Invoke quit.
EXCEPINFO exceptionInfo;
DISPPARAMS params;
VARIANT parm1;
VARIANT result;
unsigned int error;
VariantInit(&result);

memset(&params, 0, sizeof(params));
params.cArgs = 0;

hr = dispatch->Invoke(dispid, IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &params,
&result, &exceptionInfo, &error);
if (hr != S_OK)
{
fprintf(stderr, "Invoke failed, HR = 0x%x\n", hr);
return 0;
}

dispatch->Release();

return 0;
}


int main()
{
HRESULT hr;
hr = CoInitialize(NULL);
if (hr != S_OK && hr != S_FALSE)
{
fprintf(stderr, "CoInitialize() failed, HR = 0x%
x\n", hr);
return 0;
}

for (int i = 0; i < 50; i++)
{
doit();
}
fprintf(stderr, "Finished\n");
Sleep(20000);

CoUninitialize();

}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top