Author Topic: EA process remains after releasing COM interface in C++, version 12.1.0.1229  (Read 6433 times)

mateiacd

  • EA User
  • **
  • Posts: 24
  • Karma: +0/-0
    • View Profile
Hello,

I am using Enterprise Architect 12.1.0.1229

I would like to use the Automation API in Visual C++ 2010. I created a simple Win32 console project.

After trying a simple code like below for a console application, releasing the COM pointer I still see an EA process left running in the Windows task manager.

I am only trying to launch the Enterprise Architect COM server using the EA.App ProgID

HKEY_CLASSES_ROOT\EA.App\CLSID
    {3A9E4F92-8D27-495B-8B22-1D702B3F0C83}

I succeed, but  even after exiting the console application I see the EA.exe *32 in the list of processes

Can anybody help ? Thanks !
Code: [Select]
CoInitialize(NULL);

CLSID clsid;
OLECHAR wb[] = L"EA.App";
CLSIDFromProgID(wb, &clsid);


IDispatch* pDispatch;
HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pDispatch);
if (FAILED(hr))
{
MessageBox(NULL,_T("CoCreateInstance failed"),_T("Enterprise Architect"),MB_OK);
return;
}

pDispatch->Release();
CoUninitialize();

I also tried this variation with the same result. After the application closes, I still have the problem of getting rid of the EA.exe *32 process
Code: [Select]
IUnknown* pUnknown;
HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pUnknown);
if (FAILED(hr))
{
    MessageBox(NULL,_T("CoCreateInstance failed"),_T("Enterprise Architect"),MB_OK);
    return;
}


IDispatch* pDispatch;

cout << "Client: Calling QueryInterface() for IDispatch on " << pUnknown << endl;
hr = pUnknown->QueryInterface(IID_IDispatch, (void**)&pDispatch);

if (FAILED(hr))
{
MessageBox(NULL,_T("QueryInterface failed"),_T("Enterprise Architect"),MB_OK);
pUnknown->Release();
return;
}

pDispatch->Release();
pUnknown->Release();


P.S. Can I attach files to this post ? I would like to attach some screen captures.
« Last Edit: October 03, 2016, 08:08:42 pm by mateiacd »

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13404
  • Karma: +567/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: EA process remains after releasing COM interface in C++
« Reply #1 on: October 03, 2016, 07:18:39 pm »
there is a code tag that makes reading code a bit easier on the eye.
If you want to attach images you have to upload them to a public image server such as imgur.com and then include them in an img tag.

Have you tried the Repository.Exit function?

Geert

mateiacd

  • EA User
  • **
  • Posts: 24
  • Karma: +0/-0
    • View Profile
Re: EA process remains after releasing COM interface in C++
« Reply #2 on: October 03, 2016, 07:41:25 pm »
In C++ I see no such functionality like Repository.Exit()
Can you explain how ? Thank you.

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13404
  • Karma: +567/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: EA process remains after releasing COM interface in C++
« Reply #3 on: October 03, 2016, 07:44:09 pm »
See http://sparxsystems.com/enterprise_architect_user_guide/12.1/automation_and_scripting/repository3.html
The main API object EA.Repository has an operation Exit() that should kill the process completely.

Geert

Uffe

  • EA Practitioner
  • ***
  • Posts: 1859
  • Karma: +133/-14
  • Flutes: 1; Clarinets: 1; Saxes: 5 and counting
    • View Profile
Re: EA process remains after releasing COM interface in C++
« Reply #4 on: October 03, 2016, 07:44:41 pm »
Repository.Exit() is contraindicated in this situation, as the API documentation lists is explicitly for use from .NET.

But it appears as if you're using EA.App rather than EA.Repository. Why is that?

The normal way to use the EA API from a stand-alone application is to create an instance of EA.Repository, call OpenFile() to connect to a repository, and then when you're finished call CloseFile().

The undocumented, or poorly documented, EA.App is a reference to a running instance of the client, which is not typically what you want when writing a stand-alone application. If you want your code to run within the context of an EA client, the normal way is to create an Add-In instead.

HTH,


/Uffe
My theories are always correct, just apply them to the right reality.

mateiacd

  • EA User
  • **
  • Posts: 24
  • Karma: +0/-0
    • View Profile
All right, I tried also EA.Repository

HKEY_CLASSES_ROOT\EA.Repository\CLSID
    {67F4E0FA-46A7-4255-B084-69A9433D08C3}

and still the instance of EA.exe *32 appears in Task Manager after closing my application.

However a colleague using Enterprise Architect version 10.0.1006 does not have this problem !

On his computer, my code works as expected, everything is cleaned up properly...

So it appears to be a case only for me using Enterprise Architect version 12.1.0.1229


« Last Edit: October 03, 2016, 08:05:47 pm by mateiacd »

mateiacd

  • EA User
  • **
  • Posts: 24
  • Karma: +0/-0
    • View Profile
Thank you very much Uffe for pointing me to use EA.Repository as a ProgID!!!

It seems that  EA.exe *32 is closed properly in Task Manager only if we explicitly call all three methods below:
OpenFile
CloseFile
ExitFile

Here is the relevant code, I hope it will be useful for other programmers  working with C++.

Code: [Select]
void Test1()
{
CLSID clsid;
CLSIDFromProgID(L"EA.Repository", &clsid);

IRepository* pRepository;
HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDualRepository, (void**)&pRepository);
if (FAILED(hr))
{
MessageBox(NULL,_T("CoCreateInstance failed"),_T("Testing app"),MB_OK);
return;
}

_variant_t fileName(_T("D:\\Temp\\getting-started.eap"));

pRepository->OpenFile(fileName);
_variant_t pg = pRepository->GetProjectGUID();
pRepository->CloseFile();
pRepository->Exit();

pRepository->Release();
}


and the other relevant code:

Code: [Select]
#include "stdafx.h"
#include <comdef.h>
#include <iostream>

using namespace std;

#import "C:\\Program Files (x86)\\Sparx Systems\\EA\\EA.tlb" no_namespace named_guids

void Test1();

int _tmain(int argc, _TCHAR* argv[])
{
 HRESULT hr = CoInitialize(NULL);
 if(FAILED(hr))
 {
MessageBox(NULL,_T("CoInitialize failed"),_T("Testing app"),MB_OK);
cout << " failed" << endl;
 }

 Test1();

 CoUninitialize();

 MessageBox(NULL,_T("Finish"),_T("Testing app"),MB_OK);
 return 0;

}

« Last Edit: October 04, 2016, 02:19:00 am by mateiacd »