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; }




Reply With Quote