PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Visual Studio 2008/ATLCOMService/ReadMe.txt

#
Plain Text | 282 lines | 206 code | 76 blank | 0 comment | 0 complexity | 31164c3ef5cce2d820a63582de9f6c95 MD5 | raw file
  1. ========================================================================
  2. ACTIVE TEMPLATE LIBRARY : ATLCOMService Project Overview
  3. ========================================================================
  4. /////////////////////////////////////////////////////////////////////////////
  5. Use:
  6. Acitve Template Library (ATL) is designed to simplify the process of creating
  7. efficient, flexible, lightweight COM components. ATLCOMService provides the
  8. our-of-process server objects that run in a Windows Service.
  9. ATLCOMService exposes the following items:
  10. 1. An ATL STA Simple Object short-named SimpleObject.
  11. Program ID: ATLCOMService.SimpleObject
  12. CLSID_SimpleObject: 388F1C82-ED00-4966-9590-02F6B9CCA41B
  13. IID_ISimpleObject: 1B877090-76CD-4EDE-8115-EC4CCD9676F3
  14. DIID__ISimpleObjectEvents: 7DACF5E9-2885-4E4E-83DD-CA6CC3A88B6D
  15. LIBID_ATLExeCOMServerLib: CC2CA6F0-2220-4D77-BA46-4BCB62156A28
  16. AppID: 5CDE0403-41B3-45F9-8B6F-49E3193B5425
  17. Properties:
  18. // With both get and put accessor methods
  19. FLOAT FloatProperty
  20. Methods:
  21. // HelloWorld returns a BSTR "HelloWorld"
  22. HRESULT HelloWorld([out,retval] BSTR* pRet);
  23. // GetProcessThreadID outputs the running process ID and thread ID
  24. HRESULT GetProcessThreadID([out] LONG* pdwProcessId, [out] LONG* pdwThreadId);
  25. Events:
  26. // FloatPropertyChanging is fired before new value is set to the
  27. // FloatProperty property. The [in, out] parameter Cancel allows the client
  28. // to cancel the change of FloatProperty.
  29. void FloatPropertyChanging(
  30. [in] FLOAT NewValue, [in, out] VARIANT_BOOL* Cancel);
  31. /////////////////////////////////////////////////////////////////////////////
  32. Project Relation:
  33. ATLCOMService - ATLExeCOMServer - ATLDllCOMServer
  34. All are COM components written in ATL. ATLDllCOMServer is an in-process
  35. component in the form of DLL, ATLExeCOMServer is an out-of-process component
  36. in the form of EXE (Local Server), and ATLCOMService is an out-of-process
  37. component in the form of EXE (Local Service).
  38. /////////////////////////////////////////////////////////////////////////////
  39. Deployment:
  40. A. Setup
  41. ATLCOMService.exe /Service
  42. It registers your server in the system registry and as a service.
  43. B. Cleanup
  44. ATLCOMService.exe /Unregserver
  45. It not only removes the server from the system registry, but also deletes it
  46. as a service.
  47. /////////////////////////////////////////////////////////////////////////////
  48. Creation:
  49. A. Creating the project
  50. Step1. Create a Visual C++ / ATL / ATL Project named ATLCOMService in Visual
  51. Studio 2008.
  52. Step2. In the page "Application Settings" of ATL Project Wizard, select the
  53. server type as Service (EXE). It generates the main project: ATLCOMService,
  54. and the proxy/stub project: ATLCOMServicePS.
  55. B. Customizing the service in its Overrides
  56. Some famous Overrides are exposed by the service module. For example,
  57. InitializeSecurity - Override to set security options for the service via
  58. CoInitializeSecurity. ServiceMain - Called when the service is started.
  59. Handler - Called whenever a control request is received from the service
  60. control manager. To override these methods,
  61. Step1. Switch to the Class View of the project, and select the service module
  62. CATLCOMServiceModule.
  63. Step2. In the Properties dialog, turn to the Overrides page. Select the
  64. overridable methods in the list, and add the overrides. The code is generated
  65. in ATLCOMService.cpp. For example,
  66. void CATLCOMServiceModule::ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
  67. {
  68. // TODO: Add your specialized code here and/or call the base class
  69. CAtlServiceModuleT<CATLCOMServiceModule,100>::ServiceMain(
  70. dwArgc, lpszArgv);
  71. }
  72. C. Adding an ATL Simple Object
  73. Step1. In Solution Explorer, add a new ATL / ATL Simple Object class to the
  74. project.
  75. Step2. In ATL Simple Object Wizard, specify the short name as
  76. SimpleObject, and select the threading model as Apartment (corresponding
  77. to STA), select Interface as Dual that supports both IDispatch (late binding)
  78. and vtable binding (early binding). Last, select the Connection points check
  79. box. This creates the _ISimpleObjectEvents interface in the file
  80. ATLCOMService.idl. The Connection points option is the prerequisite for the
  81. component to supporting events.
  82. D. Adding Properties to the ATL Simple Object
  83. Step1. In Class View, find the interface ISimpleObject. Right click it
  84. and select Add / Add Property in the menu.
  85. Step2. In Add Property Wizard, specify the property type as FLOAT, property
  86. name as FloatProperty. Select both Get function and Put function.
  87. SimpleObject therefore exposes FloatProperty with the get&put accessor
  88. methods: get_FloatProperty, put_FloatProperty.
  89. Step3. Add a float field, m_fField, to the class CSimpleObject:
  90. protected:
  91. // Used by FloatProperty
  92. float m_fField;
  93. Implement the get&put accessor methods of FloatProperty to access m_fField.
  94. STDMETHODIMP CSimpleObject::get_FloatProperty(FLOAT* pVal)
  95. {
  96. *pVal = m_fField;
  97. return S_OK;
  98. }
  99. STDMETHODIMP CSimpleObject::put_FloatProperty(FLOAT newVal)
  100. {
  101. m_fField = newVal;
  102. return S_OK;
  103. }
  104. E. Adding Methods to the ATL Simple Object
  105. Step1. In Class View, find the interface ISimpleObject. Right-click it
  106. and select Add / Add Method in the menu.
  107. Step2. In Add Method Wizard, specify the method name as HelloWorld. Add a
  108. parameter whose parameter attributes = retval, parameter type = BSTR*,
  109. and parameter name = pRet.
  110. Step3. Write the body of HelloWorld as this:
  111. STDMETHODIMP CSimpleObject::HelloWorld(BSTR* pRet)
  112. {
  113. // Allocate memory for the string:
  114. *pRet = ::SysAllocString(L"HelloWorld");
  115. if (pRet == NULL)
  116. return E_OUTOFMEMORY;
  117. // The client is now responsible for freeing pbstr
  118. return S_OK;
  119. }
  120. With the almost same steps, the method GetProcessThreadID is added to get the
  121. executing process ID and thread ID.
  122. HRESULT GetProcessThreadID([out] LONG* pdwProcessId, [out] LONG* pdwThreadId);
  123. F. Adding Events to the ATL Simple Object
  124. The Connection points option in B/Step2 is the prerequisite for the component
  125. to supporting events.
  126. Step1. In Class View, expand ATLExeCOMServer and ATLExeCOMServerLib to display
  127. _ISimpleObjectEvents.
  128. Step2. Right-click _ISimpleObjectEvents. In the menu, click Add, and
  129. then click Add Method.
  130. Step3. Select a Return Type of void, enter FloatPropertyChanging in the
  131. Method name box, and add an [in] parameter FLOAT NewValue, and an [in, out]
  132. parameter VARIANT_BOOL* Cancel. After clicking Finish,
  133. _ISimpleObjectEvents dispinterface in the ATLExeCOMServer.idl file
  134. should look like this:
  135. dispinterface _ISimpleObjectEvents
  136. {
  137. properties:
  138. methods:
  139. [id(1), helpstring("method FloatPropertyChanging")] void
  140. FloatPropertyChanging(
  141. [in] FLOAT NewValue, [in,out] VARIANT_BOOL* Cancel);
  142. };
  143. Step4. Generate the type library by rebuilding the project or by
  144. right-clicking the ATLCOMService.idl file in Solution Explorer and clicking
  145. Compile on the shortcut menu. Please note: We must compile the IDL file
  146. BEFORE setting up a connection point.
  147. Step5. Use the Implement Connection Point Wizard to implement the Connection
  148. Point interface: In Class View, right-click the component's implementation
  149. class CSimpleObject. On the shortcut menu, click Add, and then click
  150. Add Connection Point. Select _ISimpleObjectEvents from the Source
  151. Interfaces list and double-click it to add it to the Implement connection
  152. points column. Click Finish. A proxy class for the connection point will be
  153. generated (ie. CProxy_ISimpleObjectEvents in this sample) in the file
  154. _ISimpleObjectEvents_CP.h. This also creates a function with the name
  155. Fire_[eventname] which can be called to raise events in the client.
  156. Step6. Fire the event in put_FloatProperty:
  157. STDMETHODIMP CSimpleObject::put_FloatProperty(FLOAT newVal)
  158. {
  159. // Fire the event, FloatPropertyChanging
  160. VARIANT_BOOL cancel = VARIANT_FALSE;
  161. Fire_FloatPropertyChanging(newVal, &cancel);
  162. if (cancel == VARIANT_FALSE)
  163. {
  164. m_fField = newVal; // Save the new value
  165. } // else, do nothing
  166. return S_OK;
  167. }
  168. G. Configuring and building the project as an ATL COM service
  169. Step1. Open SimpleObject.rgs and add the following value the
  170. ForceRemove {388F1C82-ED00-4966-9590-02F6B9CCA41B} registry key.
  171. val AppID = s '%APPID%'
  172. The result is like
  173. ForceRemove {388F1C82-ED00-4966-9590-02F6B9CCA41B} =
  174. s 'SimpleObject Class'
  175. {
  176. ProgID = s 'ATLCOMService.SimpleObject.1'
  177. VersionIndependentProgID = s 'ATLCOMService.SimpleObject'
  178. ForceRemove 'Programmable'
  179. LocalServer32 = s '%MODULE%'
  180. val AppID = s '%APPID%'
  181. 'TypeLib' = s '{CC2CA6F0-2220-4D77-BA46-4BCB62156A28}'
  182. }
  183. This is a known product issue of ATL Simple template in Visual Studio 2008.
  184. Without the AppID entry, the calls of CoCreateInstance on the client sides
  185. return 0x80080005. Jigar Mehta's article "CoCreateInstance returns 0x80080005
  186. for Visual Studio 2008 based ATL service" illustrates the details of the
  187. issue.
  188. Step2. Right-click the ATLCOMService project and select Properties to open
  189. its Property Pages. Turn to Build Events / Post Build Event, and change the
  190. Command Line value from
  191. "$(TargetPath)" /RegServer
  192. to
  193. "$(TargetPath)" /Service
  194. This registers the server in the system registry and as a service, instead of
  195. as just a plain EXE.
  196. H. Configuring DCOM-specific settings
  197. DCOM-specific settings of the ATL service can be configured in the DCOMCNFG
  198. utility.
  199. http://msdn.microsoft.com/en-us/library/wdyy0xsw.aspx
  200. /////////////////////////////////////////////////////////////////////////////
  201. References:
  202. ATL Services
  203. http://msdn.microsoft.com/en-us/library/74y2334x.aspx
  204. CoCreateInstance returns 0x80080005 for Visual Studio 2008 based ATL service
  205. http://blogs.msdn.com/jigarme/archive/2008/05/08/cocreateinstance-returns-0x80080005-for-visual-studio-2008-based-atl-service.aspx
  206. /////////////////////////////////////////////////////////////////////////////