PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Visual Studio 2008/CSDllCOMServer/ReadMe.txt

#
Plain Text | 215 lines | 151 code | 64 blank | 0 comment | 0 complexity | 7bf108986eae4dfecd423e78121fc496 MD5 | raw file
  1. ========================================================================
  2. LIBRARY APPLICATION : CSDllCOMServer Project Overview
  3. ========================================================================
  4. /////////////////////////////////////////////////////////////////////////////
  5. Summary:
  6. This Visual C# sample focuses on exposing .NET Framework components to COM,
  7. which allows us to write a .NET type and consuming that type from unmanaged
  8. code with distinct activities for COM developers.
  9. There are basically three methods to define the class interface for a
  10. component:
  11. 1. Explicitly Define the Class Interface with
  12. [ClassInterface(ClassInterfaceType.None)]
  13. This is the recommended way if you are going to expose your .NET class to COM
  14. aware clients. The code in SimpleObject demonstrates this method.
  15. 2. Implicitly Define the Class Interface with
  16. [ClassInterface(ClassInterfaceType.AutoDual)] or
  17. [ClassInterface(ClassInterfaceType.AutoDispatch)].
  18. Using ClassInterface to expose the public methods of a .NET class is NOT
  19. generally recommended because it's creedless to COM versioning. This method
  20. is not demonstrated in this code sample.
  21. 3. Use Microsoft.VisualBasic.ComClassAttribute
  22. The ComClassAttribute attribute instructs the compiler to add metadata that
  23. allows a class to be exposed as a COM object. It simplifies the process of
  24. exposing COM components from Visual Basic. Without ComClassAttribute, you
  25. need to follow a number of steps to generate a COM object from Visual Basic.
  26. For classes marked with ComClassAttribute, the compiler performs many of
  27. these steps automatically. The sample VBDllCOMServer demonstrates the use of
  28. the attribute. Visual C# can also benefit from ComClassAttribute, as long as
  29. the project references the Microsoft.VisualBasic assembly. This method is
  30. not demonstrated in the code sample.
  31. CSDllCOMServer exposes the following component:
  32. SimpleObject whose class interface is explicitly defined.
  33. Program ID: CSDllCOMServer.SimpleObject
  34. CLSID_CSExplicitInterfaceObject: 4B65FE47-2F9D-37B8-B3CB-5BE4A7BC0926
  35. IID_ICSExplicitInterfaceObject: 32DBA9B0-BE1F-357D-827F-0196229FA0E2
  36. DIID_ICSExplicitInterfaceObjectEvents: 95DB823B-E204-428c-92A3-7FB29C0EC576
  37. LIBID_CSDllCOMServer: F0998D9A-0E79-4F67-B944-9E837F479587
  38. Properties:
  39. // With both get and set accessor methods
  40. float FloatProperty
  41. Methods:
  42. // HelloWorld returns a string "HelloWorld"
  43. string HelloWorld();
  44. // GetProcessThreadID outputs the running process ID and thread ID
  45. void GetProcessThreadID(out uint processId, out uint threadId);
  46. Events:
  47. // FloatPropertyChanging is fired before new value is set to the
  48. // FloatProperty property. The Cancel parameter allows the client to
  49. // cancel the change of FloatProperty.
  50. void FloatPropertyChanging(float NewValue, ref bool Cancel);
  51. NOTE: The GUIDs used in this sample are generated by guidgen.exe (Visual
  52. Studio / Tools / Create GUID). When you write your own COM objects, you need
  53. to generate and use new GUIDs.
  54. NOTE: COM components or ActiveX controls written in .NET languages cannot
  55. be referenced by .NET applications in the form of interop assemblies. If you
  56. "add reference" to such a TLB, or drag & drop such an ActiveX control to your
  57. .NET application, you will get an error "The ActiveX type library 'XXXXX.tlb'
  58. was exported from a .NET assembly and cannot be added as a reference.". The
  59. correct approach is to add a reference to the .NET assembly directly.
  60. /////////////////////////////////////////////////////////////////////////////
  61. Sample Relation:
  62. (Relation of the current sample and other samples in
  63. Microsoft All-In-One Code Framework http://cfx.codeplex.com)
  64. CppCOMClient -> CSDllCOMServer
  65. CppCOMClient consumes this C# component using #import and the smart pointers.
  66. CSDllCOMServer - VBDllCOMServer
  67. These COM samples expose the same set of properties, methods, and events,
  68. but they are implemented in different .NET languages.
  69. CSDllCOMServer - CSCOMService
  70. Both are COM components written in Visual C#. CSDllCOMServer is an in-process
  71. component in the form of DLL. CSCOMService is an out-of-process component in
  72. the form of Windows Service.
  73. /////////////////////////////////////////////////////////////////////////////
  74. Deployment:
  75. A. Setup
  76. Regasm.exe CSDllCOMServer.dll
  77. It registers the types that are COM-visible in CSDllCOMServer.dll.
  78. B. Cleanup
  79. Regasm.exe /u CSDllCOMServer.dll
  80. It unregisters the types that are COM-visible in CSDllCOMServer.dll.
  81. /////////////////////////////////////////////////////////////////////////////
  82. Creation:
  83. A. Creating the project
  84. Step1. Create a Visual C# / Class Library project named CSDllCOMServer in
  85. Visual Studio 2008.
  86. Step2. In order to make the .NET assembly COM-visible, first, open the
  87. property of the project. Click the Assembly Information button in the page,
  88. Application, and select the "Make Assembly COM-Visible" box. This corresponds
  89. to the assembly attribute ComVisible in AssemblyInfo.cs:
  90. [assembly: ComVisible(true)]
  91. The GUID value in the dialog is the libid of the component:
  92. [assembly: Guid("f0998d9a-0e79-4f67-b944-9e837f479587")]
  93. Second, in the Build page of the project's property, select the option
  94. "Register for COM interop". This option specifies whether your managed
  95. application will expose a COM object (a COM-callable wrapper) that allows a
  96. COM object to interact with your managed application.
  97. B. Adding a component whose interface is explicitly defined
  98. Step1. Define a "public" interface ICSExplicitInterfaceObject to describe the
  99. COM interface of the coclass. Specify its GUID, aka IID, using GuidAttribute:
  100. [Guid("32DBA9B0-BE1F-357D-827F-0196229FA0E2")]
  101. In this way, IID of the COM object is a fixed value. By default, the
  102. interfaces used by a .NET Class are transformed to dual interfaces
  103. [InterfaceType(ComInterfaceType.InterfaceIsDual)] in the IDL. This allows the
  104. client to get the best of both early binding and late binding. Other options
  105. are [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] and
  106. [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)].
  107. Step2. Inside the interface ICSExplicitInterfaceObject, define the prototypes
  108. of the properties and methods to be exported. The terms marked as
  109. [ComVisible(false)] are not exported.
  110. Step3. Define a "public" interface ICSExplicitInterfaceObjectEvents to
  111. describe the events the coclass can sink. Specify its GUID, aka the Events Id,
  112. using GuidAttribute:
  113. [Guid("95DB823B-E204-428c-92A3-7FB29C0EC576")]
  114. Decorate the interface as an IDispatch interface:
  115. [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
  116. Step4. Inside the interface ICSExplicitInterfaceObjectEvents, define the
  117. prototype of the events to be exported.
  118. Step5. Define a "public" class CSExplicitInterfaceObject that implements the
  119. interface ICSExplicitInterfaceObject. Attach the attribute
  120. [ClassInterface(ClassInterfaceType.None)] to it, which tells the type-library
  121. generation tools that we do not require a Class Interface. This ensures that
  122. the ICSExplicitInterfaceObject interface is the default interface. In addition,
  123. specify the GUID of the class, aka CLSID, using the Guid attribute:
  124. [Guid("4B65FE47-2F9D-37B8-B3CB-5BE4A7BC0926")]
  125. In this way, CLSID of the COM object is a fixed value. Last, decorate the
  126. class with a ComSourceInterface attribute:
  127. [ComSourceInterfaces(typeof(ICSExplicitInterfaceObjectEvents))]
  128. ComSourceInterfaces identifies a list of interfaces that are exposed as COM
  129. event sources for the attributed class.
  130. Step6. Make sure that the constructor of the class CSExplicitInterfaceObject
  131. is not private (we can either add a public constructor or use the default
  132. one), so that the COM object is creatable from the COM aware clients.
  133. Step7. Inside CSExplicitInterfaceObject, implement the interface
  134. ICSExplicitInterfaceObject by writing the body of the property FloatProperty
  135. and the methods HelloWorld, GetProcessThreadID and HiddenFunction.
  136. Step8. Build the project. If a stand-alone tlb file, CSDllCOMServer.tlb, is
  137. created in the output folder, it basically means that the project is built
  138. successfully.
  139. /////////////////////////////////////////////////////////////////////////////
  140. References:
  141. Exposing .NET Framework Components to COM
  142. http://msdn.microsoft.com/en-us/library/zsfww439.aspx
  143. COM Interop Part 2: C# Server Tutorial
  144. http://msdn.microsoft.com/en-us/library/aa645738.aspx
  145. Building COM Servers in .NET By Lim Bio Liong
  146. http://www.codeproject.com/KB/COM/BuildCOMServersInDotNet.aspx
  147. Understanding Classic COM Interoperability With .NET Applications By Aravind
  148. http://www.codeproject.com/KB/COM/cominterop.aspx
  149. KB: How to develop an in-process COM component
  150. http://support.microsoft.com/kb/976026/en-us
  151. /////////////////////////////////////////////////////////////////////////////