/Visual Studio 2008/CSDllCOMServer/ReadMe.txt
Plain Text | 215 lines | 151 code | 64 blank | 0 comment | 0 complexity | 7bf108986eae4dfecd423e78121fc496 MD5 | raw file
- ========================================================================
- LIBRARY APPLICATION : CSDllCOMServer Project Overview
- ========================================================================
-
- /////////////////////////////////////////////////////////////////////////////
- Summary:
-
- This Visual C# sample focuses on exposing .NET Framework components to COM,
- which allows us to write a .NET type and consuming that type from unmanaged
- code with distinct activities for COM developers.
-
- There are basically three methods to define the class interface for a
- component:
-
- 1. Explicitly Define the Class Interface with
- [ClassInterface(ClassInterfaceType.None)]
-
- This is the recommended way if you are going to expose your .NET class to COM
- aware clients. The code in SimpleObject demonstrates this method.
-
- 2. Implicitly Define the Class Interface with
- [ClassInterface(ClassInterfaceType.AutoDual)] or
- [ClassInterface(ClassInterfaceType.AutoDispatch)].
-
- Using ClassInterface to expose the public methods of a .NET class is NOT
- generally recommended because it's creedless to COM versioning. This method
- is not demonstrated in this code sample.
-
- 3. Use Microsoft.VisualBasic.ComClassAttribute
-
- The ComClassAttribute attribute instructs the compiler to add metadata that
- allows a class to be exposed as a COM object. It simplifies the process of
- exposing COM components from Visual Basic. Without ComClassAttribute, you
- need to follow a number of steps to generate a COM object from Visual Basic.
- For classes marked with ComClassAttribute, the compiler performs many of
- these steps automatically. The sample VBDllCOMServer demonstrates the use of
- the attribute. Visual C# can also benefit from ComClassAttribute, as long as
- the project references the Microsoft.VisualBasic assembly. This method is
- not demonstrated in the code sample.
-
- CSDllCOMServer exposes the following component:
-
- SimpleObject whose class interface is explicitly defined.
-
- Program ID: CSDllCOMServer.SimpleObject
- CLSID_CSExplicitInterfaceObject: 4B65FE47-2F9D-37B8-B3CB-5BE4A7BC0926
- IID_ICSExplicitInterfaceObject: 32DBA9B0-BE1F-357D-827F-0196229FA0E2
- DIID_ICSExplicitInterfaceObjectEvents: 95DB823B-E204-428c-92A3-7FB29C0EC576
- LIBID_CSDllCOMServer: F0998D9A-0E79-4F67-B944-9E837F479587
-
- Properties:
- // With both get and set accessor methods
- float FloatProperty
-
- Methods:
- // HelloWorld returns a string "HelloWorld"
- string HelloWorld();
- // GetProcessThreadID outputs the running process ID and thread ID
- void GetProcessThreadID(out uint processId, out uint threadId);
-
- Events:
- // FloatPropertyChanging is fired before new value is set to the
- // FloatProperty property. The Cancel parameter allows the client to
- // cancel the change of FloatProperty.
- void FloatPropertyChanging(float NewValue, ref bool Cancel);
-
- NOTE: The GUIDs used in this sample are generated by guidgen.exe (Visual
- Studio / Tools / Create GUID). When you write your own COM objects, you need
- to generate and use new GUIDs.
-
- NOTE: COM components or ActiveX controls written in .NET languages cannot
- be referenced by .NET applications in the form of interop assemblies. If you
- "add reference" to such a TLB, or drag & drop such an ActiveX control to your
- .NET application, you will get an error "The ActiveX type library 'XXXXX.tlb'
- was exported from a .NET assembly and cannot be added as a reference.". The
- correct approach is to add a reference to the .NET assembly directly.
-
-
- /////////////////////////////////////////////////////////////////////////////
- Sample Relation:
- (Relation of the current sample and other samples in
- Microsoft All-In-One Code Framework http://cfx.codeplex.com)
-
- CppCOMClient -> CSDllCOMServer
- CppCOMClient consumes this C# component using #import and the smart pointers.
-
- CSDllCOMServer - VBDllCOMServer
- These COM samples expose the same set of properties, methods, and events,
- but they are implemented in different .NET languages.
-
- CSDllCOMServer - CSCOMService
- Both are COM components written in Visual C#. CSDllCOMServer is an in-process
- component in the form of DLL. CSCOMService is an out-of-process component in
- the form of Windows Service.
-
-
- /////////////////////////////////////////////////////////////////////////////
- Deployment:
-
- A. Setup
-
- Regasm.exe CSDllCOMServer.dll
- It registers the types that are COM-visible in CSDllCOMServer.dll.
-
- B. Cleanup
-
- Regasm.exe /u CSDllCOMServer.dll
- It unregisters the types that are COM-visible in CSDllCOMServer.dll.
-
-
- /////////////////////////////////////////////////////////////////////////////
- Creation:
-
- A. Creating the project
-
- Step1. Create a Visual C# / Class Library project named CSDllCOMServer in
- Visual Studio 2008.
-
- Step2. In order to make the .NET assembly COM-visible, first, open the
- property of the project. Click the Assembly Information button in the page,
- Application, and select the "Make Assembly COM-Visible" box. This corresponds
- to the assembly attribute ComVisible in AssemblyInfo.cs:
-
- [assembly: ComVisible(true)]
-
- The GUID value in the dialog is the libid of the component:
-
- [assembly: Guid("f0998d9a-0e79-4f67-b944-9e837f479587")]
-
- Second, in the Build page of the project's property, select the option
- "Register for COM interop". This option specifies whether your managed
- application will expose a COM object (a COM-callable wrapper) that allows a
- COM object to interact with your managed application.
-
- B. Adding a component whose interface is explicitly defined
-
- Step1. Define a "public" interface ICSExplicitInterfaceObject to describe the
- COM interface of the coclass. Specify its GUID, aka IID, using GuidAttribute:
-
- [Guid("32DBA9B0-BE1F-357D-827F-0196229FA0E2")]
-
- In this way, IID of the COM object is a fixed value. By default, the
- interfaces used by a .NET Class are transformed to dual interfaces
- [InterfaceType(ComInterfaceType.InterfaceIsDual)] in the IDL. This allows the
- client to get the best of both early binding and late binding. Other options
- are [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] and
- [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)].
-
- Step2. Inside the interface ICSExplicitInterfaceObject, define the prototypes
- of the properties and methods to be exported. The terms marked as
- [ComVisible(false)] are not exported.
-
- Step3. Define a "public" interface ICSExplicitInterfaceObjectEvents to
- describe the events the coclass can sink. Specify its GUID, aka the Events Id,
- using GuidAttribute:
-
- [Guid("95DB823B-E204-428c-92A3-7FB29C0EC576")]
-
- Decorate the interface as an IDispatch interface:
-
- [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
-
- Step4. Inside the interface ICSExplicitInterfaceObjectEvents, define the
- prototype of the events to be exported.
-
- Step5. Define a "public" class CSExplicitInterfaceObject that implements the
- interface ICSExplicitInterfaceObject. Attach the attribute
- [ClassInterface(ClassInterfaceType.None)] to it, which tells the type-library
- generation tools that we do not require a Class Interface. This ensures that
- the ICSExplicitInterfaceObject interface is the default interface. In addition,
- specify the GUID of the class, aka CLSID, using the Guid attribute:
-
- [Guid("4B65FE47-2F9D-37B8-B3CB-5BE4A7BC0926")]
-
- In this way, CLSID of the COM object is a fixed value. Last, decorate the
- class with a ComSourceInterface attribute:
-
- [ComSourceInterfaces(typeof(ICSExplicitInterfaceObjectEvents))]
-
- ComSourceInterfaces identifies a list of interfaces that are exposed as COM
- event sources for the attributed class.
-
- Step6. Make sure that the constructor of the class CSExplicitInterfaceObject
- is not private (we can either add a public constructor or use the default
- one), so that the COM object is creatable from the COM aware clients.
-
- Step7. Inside CSExplicitInterfaceObject, implement the interface
- ICSExplicitInterfaceObject by writing the body of the property FloatProperty
- and the methods HelloWorld, GetProcessThreadID and HiddenFunction.
-
- Step8. Build the project. If a stand-alone tlb file, CSDllCOMServer.tlb, is
- created in the output folder, it basically means that the project is built
- successfully.
-
-
- /////////////////////////////////////////////////////////////////////////////
- References:
-
- Exposing .NET Framework Components to COM
- http://msdn.microsoft.com/en-us/library/zsfww439.aspx
-
- COM Interop Part 2: C# Server Tutorial
- http://msdn.microsoft.com/en-us/library/aa645738.aspx
-
- Building COM Servers in .NET By Lim Bio Liong
- http://www.codeproject.com/KB/COM/BuildCOMServersInDotNet.aspx
-
- Understanding Classic COM Interoperability With .NET Applications By Aravind
- http://www.codeproject.com/KB/COM/cominterop.aspx
-
- KB: How to develop an in-process COM component
- http://support.microsoft.com/kb/976026/en-us
-
-
- /////////////////////////////////////////////////////////////////////////////