• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 470
  • Last Modified:

Use of connection points in MFC program running as service

I have an MFC-based program that needs to receive events from a COM object via a connection point. I have therefore implemented this connection point in a COM object within the MFC code. This all works fine when I run it normally. However, I now have a client who wants to run this as a service. But as soon as I try to instantiate my local COM object, my process hangs. I guess it's some kind of security issue, but nothing I've tried fixes it. Help!
0
beardyjon
Asked:
beardyjon
  • 7
  • 7
1 Solution
 
beardyjonAuthor Commented:
Hmmm. Has anyone looked at this yet? One further point - when I say "run as a service" above, what I mean is that I've added some code to the module so that it can self-install as a service. This code is actually in an underlying API that I have developed and which is used by many other similar modules (ones which don't try to instatiate local COM objects).

So to sum up:

1) MFC program needs to instantiate local COM object in order to receive real-time events from another external system.
2) Works fine when running as a standard EXE.
3) However, when it installs itself as a service, it hangs on instantiating the local COM object when it is run.

Please ask me some questions if there's anything you don't understand about this.
0
 
itsmeandnobodyelseCommented:
Did you run the service under local system account or a valid user account?

What kind of COM object is it? Does it need any user information e. g. license data?

How does it send the events? AFAIK, the 'normal' event management uses Windows messages. Hence your service would need a valid window to receive messages?

I think your service must need to establish a valid user login and a valid desktop to make it work.  But I have little knowledge of that stuff.

You should try to get a response from jkr who is the top expert on such issues. As your initial question is slightly misleading (perhaps only for me) you may consider to add a new pointer question, e. g. asking 'How to turn a MFC app to a service so that it still could invoke a COM server and receive COM events from it? '



0
 
beardyjonAuthor Commented:
Thanks for getting back to me. OK, let's unpick this a little:

1) The software that I have written comes in two parts: a generic API and some application-specific code. Both parts are (for historical reasons) written in MFC. The generic API has its own GUI, but can be installed as a windows service by running it with a command-line option. This works very well for all the other applications that I have built on top of it. They all make use of the MSXML API, and so there is clearly no problem in instantiating COM objects hosted in other DLLs.

2) The particular application that is causing me grief interfaces to a real-time feed for which the interface is implemented as a COM object, which raises events which need to be caught by implementing a connection point. I have done this by creating my own COM object that implements this connection point. Because the connection point needs to talk back to my application-specific code, it is hosted within the application executable.

3) This all works fine and dandy when I run the thing as a normal executable. However, as soon as I install it as a service, and start the service, it hangs at the precise point at which I instantiate my own local COM object.

Does that explain things any better?
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
itsmeandnobodyelseCommented:
>>>> I have done this by creating my own COM object that implements this connection point.

A COM object has no advantage over a built-in solution or a own dll beside you want it to use by more than one application, thus prefering the generic approach. But if using COM and an event sink you need an appropriate environment which surely is given when you run the executable from an active user session. But from a service you normally have no valid user account, nor a user registry which both may be responsible that the initialization failed.
0
 
beardyjonAuthor Commented:
Hang on, though. How do I implement a connection point other than in a COM object? If it isn't a COM object, surely the remote COM object won't be able to call back to it?

I'm using IDispEventSimple::DispEventAdvise to establish the connection to the remote object, BTW. How would you connect a non-COM object?
0
 
itsmeandnobodyelseCommented:
>>>> If it isn't a COM object, surely the remote COM object won't be able to call back to it?

You probably know much more about COM than me. But the 'remote' COM object had brought up an idea. Did you run your service on Local System Account? If yes, it has no network access what may have impacts on the connection between the local and the remote COM object as well.
0
 
beardyjonAuthor Commented:
Just to repeat, the problem has nothing to do with access to the remote COM object. The problem is with instantiating the COM object that is hosted in the process that is running as a service itself. Is there anyone there who has some in-depth knowledge of COM that can help me out?
0
 
itsmeandnobodyelseCommented:
>>>> the problem has nothing to do with access to the remote COM object.
How do you know? Problems with instantiating a COM object means that the COM object was not able to overcome its initialization phase, maybe because of a not working network access or some missing registry information as there was no user-login.

>>>> Did you run the service under local system account or a valid user account?
You didn't answer this question though it might be crucial.

>>>> Is there anyone there who has some in-depth knowledge of COM that can help me out?

As already told, you may ask a new pointer question where you especially give weight to the service and COM aspect.

It is not much likely that an expert who already decided not to participate will return to the thread and read your more specialized questions.  
0
 
beardyjonAuthor Commented:
In answer to your questions:

1) I know, because the process is hanging on the instantiation of the local object, before there is any reference made to the remote one.

2) I've tried running it under a user account, but if I do that, the GUI fails to appear, so I'm back to running it under the local system account. Here's the snippet of code that I use to install the service:

      SC_HANDLE hService = ::CreateService (hSCM, m_csFullName, m_csFullName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szFilePath, NULL, NULL, NULL, NULL, NULL);

If I start the service as installed, then the GUI appears fine. If I change it to run under a specific account, it starts up, but there's no GUI. I'd appreciate any suggestions with that. Maybe that might help.

3) I'm not sure what you mean when you say a new pointer question. Do you mean start a new thread altogether?
0
 
beardyjonAuthor Commented:
Quick update to the above: I've now managed to run it under a specific account so that it attempts to instantiate the local object, and it hangs there as well.
0
 
itsmeandnobodyelseCommented:
>>>> but if I do that, the GUI fails to appear,
Sorry, but a service should run without GUI. If you need a window for message exchange use a pseudo window as made with CreateThread.
0
 
itsmeandnobodyelseCommented:
>>>> Do you mean start a new thread altogether?
Yes add a new thread with a more specific question - with only little points awarded or with text 'please do not answer to this question' - and put a link to the question here to that.
0
 
itsmeandnobodyelseCommented:
>>>> so that it attempts to instantiate the local object, and it hangs there as well.

Can you post the code sequence which 'hang'?
0
 
beardyjonAuthor Commented:
As it happens, this service has a GUI that disappears when you minimise it, and all you see is an icon in the systray. Then you can log out and it still works, log in again and restore the GUI. Trust me, it works.

Anyway, earlier on I tried instantiating the COM object by simply creating it rather than CoCreateInstance and it now seems to work. So I think I may have solved my own problem. But thanks for your time anyway :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

  • 7
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now