Hi ...

I have written a Windows Service using ATL COM (ATL3 / Visual Studio 6.0). The service works fine, I am able to start and stop the service.

I have created a COM Class called CTest with a methof called TestBeep(). I would like to access this object and call the method from the CServiceModule::Run() method.

Below is the CServiceModule::Run() Method.
The code will fail on both attempts to create the ITest* pTest using CoCreateInstance(). The error message are written to the event log
"Error: ITest failed"
"CoCreateInstance failed"

Any help is appreciated,
Thanks,
Chris



Code:
void CServiceModule::Run()
{
    _Module.dwThreadID = GetCurrentThreadId();

    HRESULT hr = CoInitialize(NULL);
//  If you are running on NT 4.0 or higher you can use the following call
//  instead to make the EXE free threaded.
//  This means that calls come in on a random RPC thread
//  HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    _ASSERTE(SUCCEEDED(hr));

    // This provides a NULL DACL which will allow access to everyone.
    CSecurityDescriptor sd;
    sd.InitializeFromThreadToken();
    hr = CoInitializeSecurity(sd, -1, NULL, NULL,
        RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
    _ASSERTE(SUCCEEDED(hr));

    hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);
    _ASSERTE(SUCCEEDED(hr));

    LogEvent(_T("Blue Service started"));
    LogEvent(_T("Message 1"));
    LogEvent(_T("Message 2"));

    if (m_bService)
        SetServiceStatus(SERVICE_RUNNING);

    MSG msg;
    while (GetMessage(&msg, 0, 0, 0))
        DispatchMessage(&msg);

    _Module.RevokeClassObjects();


    // --------------------------------------------
    // We will try to call the COM Object from here 

	char progID[] = "Blue.Test.1";

	// Now make that object.
	CLSID clsid;
	wchar_t wide[80]; 
	mbstowcs(wide, progID, 80);
	CLSIDFromProgID(wide, &clsid);

    LogEvent(_T("Attempt to use ITest"));

	ITest* pTest = NULL;
	if(SUCCEEDED(CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_ITest, (void**)&pTest)))
	{
		pTest->TestBeep(); 
	}
    else
    { 
        LogEvent(_T("Error: ITest failed"));
    } 


    // We will try this another way !! 
    // We have downloaded a ATL COM Server sample and it had 
    // A COM Method in in and it was not called from within the 
    // Service (as we are trying to do) it was called from a
    // Windows Console Application using the following.  
    // We would like to make this call into com from in the 
    // Service !! 

    // Time to write to the CodeGuru
    
	CComPtr<ITest> pObj;
	hr = pObj.CoCreateInstance(OLESTR("Blue.Test.1"));
	if( SUCCEEDED(hr) )
	{
		hr = pObj->TestBeep();
		if( SUCCEEDED(hr) )
        { 
            LogEvent(_T("Call to ITest was successful"));
        }
        else
        { 
            LogEvent(_T("Error: ITest failed"));
        } 
	}

	if( FAILED(hr) )
    { 
        LogEvent(_T("CoCreateInstance failed"));
    }

    CoUninitialize();
}

This is the implementation of the CTest Class and the TestBeep() method


Code:
// Test.h : Declaration of the CTest

#ifndef __TEST_H_
#define __TEST_H_

#include "resource.h"       // main symbols

/////////////////////////////////////////////////////////////////////////////
// CTest
class ATL_NO_VTABLE CTest : 
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CTest, &CLSID_Test>,
	public IDispatchImpl<ITest, &IID_ITest, &LIBID_BLUELib>
{
public:
	CTest()
	{
	}

DECLARE_REGISTRY_RESOURCEID(IDR_TEST)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CTest)
	COM_INTERFACE_ENTRY(ITest)
	COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// ITest
public:
	STDMETHOD(TestBeep)();
	STDMETHOD(GetCount)();
	int nCount;
};

#endif //__TEST_H_



// Test.cpp : Implementation of CTest
#include "stdafx.h"
#include "Blue.h"
#include "Test.h"

/////////////////////////////////////////////////////////////////////////////
// CTest


STDMETHODIMP CTest::GetCount()
{
	// TODO: Add your implementation code here

	return S_OK;
}

STDMETHODIMP CTest::TestBeep()
{
	// TODO: Add your implementation code here
    Beep(4000, 200); 
    Beep(1000, 50); 
    Beep(4000, 200); 
    Beep(1000, 50); 
	return S_OK;
}