Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
platform
active.directory
adsi
adsi.iis-admin
base
com_ole
complus_mts
component_svcs
database
directx
gdi
graphics_mm
internet.client
internet.server
internet.server.isapi-dev
localization
mapi
messaging
msi
mslayerforunicode
multimedia
networking
networking.ipv6
sdk_install
security
shell
telephony.tapi_2
telephony.tapi_3
telephony.tsp
telephony.wte
tools
ui
ui_shell
win_base_svcs
win16
  
 
date: Fri, 17 Aug 2007 20:00:08 -0400,    group: microsoft.public.platformsdk.com_ole        back       


CoRegisterClassObject() in an NT service   
The platform is 32bit XP PRO SP2. I wrote a simple NT
service that uses CoRegisterClassObject() in its main
thread. More or less the pseudo-code is the following:

main_thread()
{
    CoInitialize();
    CoRegisterClassObject(CLSCTX_INPROC_SERVER,REGCLS_MULTIPLEUSE);
    CoCreateInstance(CLSCTX_INPROC_SERVER); >>> S_OK
    wait_for_service_main_to_complete();
}

service_main_thread()
{
    CoInitialize();
    CoCreateInstance(CLSCTX_INPROC_SERVER); >>>
REGDB_E_CLASSNOTREG
}

Why does CoCreateInstance() fail with REGDB_E_CLASSNOTREG in
the service main thread but succeeds in the process main
thread? Both thread are running under the same account
according to GetSecurityInfo()+LookupAccountSid() and the
service is running as LocalSystem.

-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Fri, 17 Aug 2007 20:00:08 -0400   author:   Alessandro Angeli

Re: CoRegisterClassObject() in an NT service   
CoInitialize initializes a STA. One of the requirements for STA objects to 
interop with objects in other STA threads is that all the threads involved 
must pump messages.

Now, if I understand your sample correctly :
ServiceMain is run in a thread that is launched when 
wait_for_service_main_to_complete calls StartServiceCtrlDispatcher. 
StartServiceCtrlDispatcher does not pump messages. This means that the 
service_main_thread() call to CoCreateInstance will time out when trying to 
access the class factory registered in the main_thread. Which will probably 
prompt COM to try an create the object from scratch from the registry, and, 
given that you're trying to register the inproc server manually like this - 
will fail with REGDB_E_CLASSNOTREG because you probably havnt got a 
inprocserver32 dll entry.

"Alessandro Angeli"  wrote in message 
news:%23P39OwS4HHA.1208@TK2MSFTNGP03.phx.gbl...
> The platform is 32bit XP PRO SP2. I wrote a simple NT
> service that uses CoRegisterClassObject() in its main
> thread. More or less the pseudo-code is the following:
>
> main_thread()
> {
>    CoInitialize();
>    CoRegisterClassObject(CLSCTX_INPROC_SERVER,REGCLS_MULTIPLEUSE);
>    CoCreateInstance(CLSCTX_INPROC_SERVER); >>> S_OK
>    wait_for_service_main_to_complete();
> }
>
> service_main_thread()
> {
>    CoInitialize();
>    CoCreateInstance(CLSCTX_INPROC_SERVER); >>>
> REGDB_E_CLASSNOTREG
> }
>
> Why does CoCreateInstance() fail with REGDB_E_CLASSNOTREG in
> the service main thread but succeeds in the process main
> thread? Both thread are running under the same account
> according to GetSecurityInfo()+LookupAccountSid() and the
> service is running as LocalSystem.
>
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm
>
>
>
date: Mon, 20 Aug 2007 11:21:26 +0200   author:   Chris Becke

Re: CoRegisterClassObject() in an NT service   
From: "Chris Becke"

> CoInitialize initializes a STA. One of the requirements
> for STA objects to interop with objects in other STA
> threads is that all the threads involved must pump
> messages.
[...]

Thanks for your reply. I changed the code as following:

main_thread()
{
    CoInitialize();
    wait_for_message_thread_to_be_ready();
    CoCreateInstance(CLSCTX_INPROC_SERVER);
        >>> REGDB_E_CLASSNOTREG
    wait_for_service_main_to_complete();
}

message_thread()
{
    CoInitialize();
    CoRegisterClassObject(CLSCTX_INPROC_SERVER,REGCLS_MULTIPLEUSE);
    signal_readiness();
    while(GetMessage()) DispatchMessage();
        >>> no message is ever dispatched here
}

service_main_thread()
{
    CoInitialize();
    CoCreateInstance(CLSCTX_INPROC_SERVER);
        >>> REGDB_E_CLASSNOTREG
}

However the result is the same in the service main thread 
and now the creation elso fails in the process main thread.

-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Mon, 20 Aug 2007 15:08:11 -0400   author:   Alessandro Angeli

Re: CoRegisterClassObject() in an NT service   
Well, damn.
 I have experience with using CoRegisterClassObject this way in regular 
applications - Perhaps the requirements for COM objects in services is 
greater.

Reading http://msdn2.microsoft.com/en-us/library/ms809975.aspx might help 
more than I can at this point in terms of getting registration to succeed.


"Alessandro Angeli"  wrote in message 
news:uCDV7114HHA.2312@TK2MSFTNGP06.phx.gbl...
> From: "Chris Becke"
>
>> CoInitialize initializes a STA. One of the requirements
>> for STA objects to interop with objects in other STA
>> threads is that all the threads involved must pump
>> messages.
> [...]
>
> Thanks for your reply. I changed the code as following:
>
> main_thread()
> {
>    CoInitialize();
>    wait_for_message_thread_to_be_ready();
>    CoCreateInstance(CLSCTX_INPROC_SERVER);
>        >>> REGDB_E_CLASSNOTREG
>    wait_for_service_main_to_complete();
> }
>
> message_thread()
> {
>    CoInitialize();
>    CoRegisterClassObject(CLSCTX_INPROC_SERVER,REGCLS_MULTIPLEUSE);
>    signal_readiness();
>    while(GetMessage()) DispatchMessage();
>        >>> no message is ever dispatched here
> }
>
> service_main_thread()
> {
>    CoInitialize();
>    CoCreateInstance(CLSCTX_INPROC_SERVER);
>        >>> REGDB_E_CLASSNOTREG
> }
>
> However the result is the same in the service main thread and now the 
> creation elso fails in the process main thread.
>
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm
>
>
>
date: Tue, 21 Aug 2007 11:25:11 +0200   author:   Chris Becke

Re: CoRegisterClassObject() in an NT service   
Actually, two other things.
CoCreateInstance on an object that was registered via CoRegisterClassObject 
in the same thread is very likley to work as there is no marshling required 
and COM doesnt need to check anything about the object in the registry.

If you are passing any sort of custom interface to CoCreateInstance then COM 
will absolutley require that the marshling object be registered.

Even if you just ask for IUnknown, there is a strong liklyhood that COM 
*needs* some registry entries to exist when trying to connect to a class 
factory in a different apartment.

To debug this you need to get this scenario working first in a simple 
desktop application with two threads. Then add the additional debugging and 
development complexity of instantiating as a service.

"Alessandro Angeli"  wrote in message 
news:uCDV7114HHA.2312@TK2MSFTNGP06.phx.gbl...
> From: "Chris Becke"
>
>> CoInitialize initializes a STA. One of the requirements
>> for STA objects to interop with objects in other STA
>> threads is that all the threads involved must pump
>> messages.
> [...]
>
> Thanks for your reply. I changed the code as following:
>
> main_thread()
> {
>    CoInitialize();
>    wait_for_message_thread_to_be_ready();
>    CoCreateInstance(CLSCTX_INPROC_SERVER);
>        >>> REGDB_E_CLASSNOTREG
>    wait_for_service_main_to_complete();
> }
>
> message_thread()
> {
>    CoInitialize();
>    CoRegisterClassObject(CLSCTX_INPROC_SERVER,REGCLS_MULTIPLEUSE);
>    signal_readiness();
>    while(GetMessage()) DispatchMessage();
>        >>> no message is ever dispatched here
> }
>
> service_main_thread()
> {
>    CoInitialize();
>    CoCreateInstance(CLSCTX_INPROC_SERVER);
>        >>> REGDB_E_CLASSNOTREG
> }
>
> However the result is the same in the service main thread and now the 
> creation elso fails in the process main thread.
>
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm
>
>
>
date: Tue, 21 Aug 2007 11:35:56 +0200   author:   Chris Becke

Re: CoRegisterClassObject() in an NT service   
I suspect your problem is due to wrong apartment model.
Switch to MTA and your current troubles will cease to
exist (to be replaced with a whole new set of troubles to
make your objects thread safe to be sure...)

-- 
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@mvps.org
MVP VC FAQ: http://vcfaq.mvps.org
=====================================

"Alessandro Angeli"  wrote in message 
news:uCDV7114HHA.2312@TK2MSFTNGP06.phx.gbl...
> From: "Chris Becke"
>
>> CoInitialize initializes a STA. One of the requirements
>> for STA objects to interop with objects in other STA
>> threads is that all the threads involved must pump
>> messages.
> [...]
>
> Thanks for your reply. I changed the code as following:
>
> main_thread()
> {
>    CoInitialize();
>    wait_for_message_thread_to_be_ready();
>    CoCreateInstance(CLSCTX_INPROC_SERVER);
>        >>> REGDB_E_CLASSNOTREG
>    wait_for_service_main_to_complete();
> }
>
> message_thread()
> {
>    CoInitialize();
>    CoRegisterClassObject(CLSCTX_INPROC_SERVER,REGCLS_MULTIPLEUSE);
>    signal_readiness();
>    while(GetMessage()) DispatchMessage();
>        >>> no message is ever dispatched here
> }
>
> service_main_thread()
> {
>    CoInitialize();
>    CoCreateInstance(CLSCTX_INPROC_SERVER);
>        >>> REGDB_E_CLASSNOTREG
> }
>
> However the result is the same in the service main thread and now the 
> creation elso fails in the process main thread.
>
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm
>
>
>
date: Tue, 21 Aug 2007 11:15:25 -0700   author:   Alexander Nickolov

Re: CoRegisterClassObject() in an NT service   
From: "Alexander Nickolov"

> I suspect your problem is due to wrong apartment model.
> Switch to MTA and your current troubles will cease to
> exist (to be replaced with a whole new set of troubles to
> make your objects thread safe to be sure...)

Thanks, I'll try this first which is easy (my objects are 
always born thread-safe out of habit :-)), then Chris' 
suggestion if this doesn't work.

Just a very dumb question since the naming has always 
confused me:

STA = COINIT_APARTMENTTHREADED
    requires marshalling and it's CoInitialize()'s
    and OleInitialize()'s choice
MTA = COINIT_MULTITHREADED
    CoInitializeEx()'s default

So, if I want free threading without any marshalling, where 
thread safety is implemented by the objects, I should always 
use CoInitializeEx(COINIT_MULTITHREADED) instead of 
CoInitialize(), right?


-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Tue, 21 Aug 2007 15:35:07 -0400   author:   Alessandro Angeli

Re: CoRegisterClassObject() in an NT service   
Correct.

-- 
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@mvps.org
MVP VC FAQ: http://vcfaq.mvps.org
=====================================

"Alessandro Angeli"  wrote in message 
news:ub8DxpC5HHA.4676@TK2MSFTNGP05.phx.gbl...
> From: "Alexander Nickolov"
>
>> I suspect your problem is due to wrong apartment model.
>> Switch to MTA and your current troubles will cease to
>> exist (to be replaced with a whole new set of troubles to
>> make your objects thread safe to be sure...)
>
> Thanks, I'll try this first which is easy (my objects are always born 
> thread-safe out of habit :-)), then Chris' suggestion if this doesn't 
> work.
>
> Just a very dumb question since the naming has always confused me:
>
> STA = COINIT_APARTMENTTHREADED
>    requires marshalling and it's CoInitialize()'s
>    and OleInitialize()'s choice
> MTA = COINIT_MULTITHREADED
>    CoInitializeEx()'s default
>
> So, if I want free threading without any marshalling, where thread safety 
> is implemented by the objects, I should always use 
> CoInitializeEx(COINIT_MULTITHREADED) instead of CoInitialize(), right?
>
>
> -- 
> // Alessandro Angeli
> // MVP :: DirectShow / MediaFoundation
> // mvpnews at riseoftheants dot com
> // http://www.riseoftheants.com/mmx/faq.htm
>
date: Tue, 21 Aug 2007 13:22:07 -0700   author:   Alexander Nickolov

Re: CoRegisterClassObject() in an NT service   
From: "Alexander Nickolov"

> I suspect your problem is due to wrong apartment model.
> Switch to MTA and your current troubles will cease to
> exist (to be replaced with a whole new set of troubles to
> make your objects thread safe to be sure...)

It looks like it was a problem of interface marshalling (I
have a custom interface) like Chris supposed. In fact,
following Alexander's suggestion to go from STA to MTA to
get rid of marshalling, everything seems to work as
exptected now.

Thank you both for your help!


-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Tue, 21 Aug 2007 18:05:59 -0400   author:   Alessandro Angeli

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us