tags:

views:

169

answers:

2

I'm aware of this question, but I've followed the steps listed there and I'm still stumped.

I've got a class, registered as follows (this is an RGS file):

HKCR
{
    NoRemove CLSID
    {
        ForceRemove {5CB1D770-BF72-4F3D-B4DA-85E0542126F4} = s 'ExamplePlugin Class'
        {
            val AppID = s '%APPID%'
            InprocServer32 = s '%MODULE%'
            {
                val ThreadingModel = s 'Free'
            }
        }
    }
}

I've got an AppID, registered as follows:

HKCR
{
    NoRemove AppID
    {
        '%APPID%' = s 'ExamplePlugin'
        {
            val DllSurrogate = s ''
        }
        'ExamplePlugin.DLL'
        {
            val AppID = s '%APPID%'
        }
    }
}

I'm passing CLSCTX_ALL to CComPtr<IPlugin>::CoCreateInstance.

In short, as far as I can tell, I've followed the checklist:

  1. I have an AppID value specified under my CLSID. I have a corresponding AppID key.
  2. I've included CLSCTX_LOCAL_SERVER in the activation call. My CLSID key does not have any LocalServer keys.
  3. My CLSID key contains an InprocServer32 key.
  4. I assume that when the checklist says "the proxy/stub DLL specified in InprocServer32 exists", it means "the implementing DLL". It does exist. My proxy/stub DLL is correctly registered elsewhere.
  5. I have a DllSurrogate value under my AppID key.

If I look at my class in OLE/COM object viewer, it appears to be correct (the Implementation tab has "Use Surrogate Process" checked).

It's still not working: my DLL is loading into the same process as my host EXE.

A clue: If I run Process Monitor, I can't see it looking for the CLSID\{...}\AppID value. If I pass CLSCTX_LOCAL_SERVER to CoCreateInstance, I get "class not registered" returned.

I'm on Windows 2008 x64, but I've tried with my code compiled for both x86 and x64 with the same result.

What am I missing?

+1  A: 

You have to spefify CLSCTX_LOCAL_SERVER to CoCreateInstance() to enforce out-proc activation. That's peculiarity of DCOM - if your component is registered as an in-proc COM server and you specify a CLSCTX_ mask including any value for in-proc activation the component is activated in-proc - DCOM is not used.

Note that COM+ provides almost the same functionality but if you create a "server application" and add your component there and then specify CLSCTX_ALL the component will be instantiated in COM+ surrogate - out-proc activation will be selected automatically.

sharptooth
It's not that you have to specify CLSCTX_LOCAL_SERVER, it's that you have to explicitly *not* specify any inproc flags.
Roger Lipscombe
...and how do I create a COM+ server application? More to the point: how do I do this from my installer?
Roger Lipscombe
Yeap, I see. Actualy I meant exactly that.
sharptooth
...moreover, having played with DCOMCNFG, it appears that COM+ "applications" need specific activation credentials. I'd like to opt for "whoever created it".
Roger Lipscombe
@sharptooth: They're bitflags. It's not enough to say "specify this flag". You have to say "specify _only_ this flag". The COM documentation makes the same mistake.
Roger Lipscombe
Install Shield surely does that but I don't know the details. As far as I know it works like this: you create a COM+ application, then import it into Install Shield package, then it can deploy the COM+ application on any machine. Server applications can be activated under the "Interactive user" identity - that's the currently logged-in user.
sharptooth
Yeah: I don't want to use "Interactive user". My COM client runs as a service under whatever account's configured for that service. That's the account I'd like the COM class instantiated under. In other words "whoever".
Roger Lipscombe
+1  A: 

It turns out that the documentation is misleading. It's not enough merely to set CLSCTX_LOCAL_SERVER. You also have to remove the CLSCTX_INPROC values from the call to CoCreateInstance. If you don't, COM will always use the in-proc stuff, and will never query for DllSurrogate.

Roger Lipscombe