在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
By 22 Apr 2009 ,IntroductionI wanted to be able to use a pre-built .NET object inside a web browser. After searching the web (including CodeProject), I found that a possible solution would be to create a .NET COM component and use the ActiveXObject in JavaScript to interact with the COM object. A Google search turned up many helpful articles, but nothing that showed how to create a COM component in C#, surface .NET events through COM, and use the COM object in JavaScript to my satisfaction. In this article, I will put together all the pieces to show how to implement a complete solution, to use C# COM objects inside JavaScript. OverviewThis article describes how to create a C# COM Object (using Visual Studio .NET 2005) that can be used in JavaScript inside a web browser (only tested on IE 8 RC on Windows Vista). Complete source code for the COM object, as well as a simple web page that demonstrates how to use the COM object is provided, including how to make calls into the COM Object, and how to handle .NET events raised from the COM object. Creating the C# COM LibraryCreate a new C# Class Library project called
Copy Code
using System; using System.Runtime.InteropServices; namespace MyComComponent { public class MyComObject { } } Add the interfaces that define the operations and events that will be exposed to COM. Add empty interface definitions named
Copy Code
using System; using System.Runtime.InteropServices; namespace MyComComponent { public class MyComObject { } public interface IComObject { } public interface IComEvents { } } Expose the
Copy Code
using System; using System.Runtime.InteropServices; namespace MyComComponent { [ComVisible(true)] public class MyComObject { } [ComVisible(true)] public interface IComObject { } [ComVisible(true)] public interface IComEvents { } } Since we are defining our own custom COM interface, we need to tell the Type Library Exporter to not generate an interface for us. To do this, add the
Copy Code
[ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] public class MyComObject { } We need to tell the Type Library Exporter that the interface for
Copy Code
[ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IComEvents { } Now we can start decorating the
Copy Code
[ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] public class MyComObject : IComObject { } Adding the
Copy Code
[ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [ComSourceInterfaces(typeof(IComEvents))] public class MyComObject : IComObject { } Each type exposed from COM has a globally unique ID. Since we haven't defined the GUID’s, the Type Library Exported will do this for us. However, we want to be able to use this GUID to load the type, so we will now add the GUIDs to all three types. Use the guidgen utility to do this. We now have the code structure in place for a COM object that explicitly implements an interface, and has an events source interface defined. The code at this point should be something like:
Copy Code
using System; using System.Runtime.InteropServices; namespace MyComComponent { [Guid("4794D615-BE51-4a1e-B1BA-453F6E9337C4")] [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [ComSourceInterfaces(typeof(IComEvents))] public class MyComObject : IComObject { } [Guid("4B3AE7D8-FB6A-4558-8A96-BF82B54F329C")] [ComVisible(true)] public interface IComObject { } [Guid("ECA5DD1D-096E-440c-BA6A-0118D351650B")] [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IComEvents { } } Now we will add some methods to the interfaces. To
Copy Code
[Guid("4B3AE7D8-FB6A-4558-8A96-BF82B54F329C")] [ComVisible(true)] public interface IComObject { [DispId(0x10000001)] int MyFirstComCommand(string arg); [DispId(0x10000002)] void Dispose(); } To
Copy Code
[Guid("ECA5DD1D-096E-440c-BA6A-0118D351650B")] [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IComEvents { [DispId(0x00000001)] void MyFirstEvent(string args); } All that’s left to do is to implement the methods and events in the
Copy Code
[ComVisible(false)] public delegate void MyFirstEventHandler(string args); public event MyFirstEventHandler MyFirstEvent; public int MyFirstComCommand(string arg) { if (MyFirstEvent != null) MyFirstEvent(arg); return (int)DateTime.Now.Ticks; } public void Dispose() { System.Windows.Forms.MessageBox.Show("MyComComponent is now disposed"); } Now we have a fully functional COM object, written in C#. The code for the COM object should look like this:
Copy Code
using System; using System.Runtime.InteropServices; namespace MyComComponent { [Guid("4794D615-BE51-4a1e-B1BA-453F6E9337C4")] [ComVisible(true)] [ClassInterface(ClassInterfaceType.None)] [ComSourceInterfaces(typeof(IComEvents))] public class MyComObject : IComObject { [ComVisible(false)] public delegate void MyFirstEventHandler(string args); public event MyFirstEventHandler MyFirstEvent; public int MyFirstComCommand(string arg) { if (MyFirstEvent != null) MyFirstEvent(arg); return (int)DateTime.Now.Ticks; } public void Dispose() { System.Windows.Forms.MessageBox.Show("MyComComponent is now disposed"); } } [Guid("4B3AE7D8-FB6A-4558-8A96-BF82B54F329C")] [ComVisible(true)] public interface IComObject { [DispId(0x10000001)] int MyFirstComCommand(string arg); [DispId(0x10000002)] void Dispose(); } [Guid("ECA5DD1D-096E-440c-BA6A-0118D351650B")] [ComVisible(true)] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IComEvents { [DispId(0x00000001)] void MyFirstEvent(string args); } } Creating an Instance of the COM ComponentTo use the COM component in a web page, embed an
Copy Code
<object name="myComComponent" id="myComComponent" classid="clsid:4794D615-BE51-4a1e-B1BA-453F6E9337C4" /> Hooking Up Events to the COM ComponentHooking up the events from the COM component is a little tricky. What you need to do is embed a
Copy Code
<script for="myComComponent" event="MyFirstEvent(args)" language="javascript"> function myComComponent::MyFirstEvent(args) { } The " Executing Commands on the COM ComponentHere's the JavaScript code to execute
Copy Code
var returnCode = myComComponent.MyFirstComCommand("Hello World!"); Disposing of the COM ComponentIn Internet Explorer 8, the COM component is not destroyed until the web browser is fully closed - closing of the tab that contained the COM component does not dispose of the object! If the user continuously hits the refresh button, new instances of the COM component will be created, but the old instances won't be released until the web browser is closed. You can use the In our example, the Putting it all TogetherBelow is the source code to a web page that creates an instance of the
Copy Code
<html> <head> <title>My Com Component</title> <object id="myComComponent" name="myComComponent" classid="clsid:4794D615-BE51-4a1e-B1BA-453F6E9337C4"></object> <script language="javascript" type="text/javascript"> function myButton_click() { var returnCode = myComComponent.MyFirstComCommand(myArgs.value); var msg = "myComComponent.MyFirstComCommand returned " + returnCode; appendText(msg); appendText("\r\n"); } function setText(txt) { myTextBox.value = txt; } function appendText(txt) { myTextBox.value = myTextBox.value + txt; } function MyComComponent_onload() { setText(""); myComComponent.MyFirstComCommand("Hi"); } function MyComComponent_onunload() { myComComponent.Dispose(); } </script> </head> <body onload="MyComComponent_onload();" onunload="MyComComponent_onunload();"> <h1>My Com Component</h1> <table> <tr> <td> <button id="myButton" onclick="myButton_click();">Com Method</button> <label>Args</label> <textarea id="myArgs" rows="1" cols="16">Hello World!</textarea> </td> </tr> <tr> <td> <textarea id="myTextBox" rows="10" cols="80"></textarea> </td> </tr> </table> <script for="myComComponent" event="MyFirstEvent(args)" language="javascript"> function myComComponent::MyFirstEvent(args) { appendText("myComComponent raised MyFirstEvent. args: "); appendText(args); appendText("\r\n"); } </script> </body> </html> Using the CodeTo use the sample web page, you first need to compile the After building the solution, open the web page MyComComponent.htm in your browser (make sure ActiveX and JavaScript are enabled). Links
History
|
请发表评论