js调用COM接口说明
我们在开发COM组件给js调用时,需要提供给js的是COM接口的CLASSID,而不是组件的classid。如下为COM组件的一个idl文件:
// ATLProject.idl : ATLProject 的 IDL 源
//
// 此文件将由 MIDL 工具处理以
// 产生类型库(ATLProject.tlb)和封送处理代码。
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(67440A39-00DF-40C4-9E57-6856105F74D5),
dual,
nonextensible,
helpstring("IATLTest 接口"),
pointer_default(unique)
]
interface IATLTest : IDispatch{
};
[
object,
uuid(315CE559-7D6C-4FBB-B9AD-F7DB4D4BC1B6),
dual,
nonextensible,
helpstring("IATLAdd 接口"),
pointer_default(unique)
]
interface IATLAdd : IDispatch{
[id(1), helpstring("方法Add")] HRESULT Add(LONG Data1, LONG Data2, LONG* lSum);
};
[
uuid(991C9BF9-7599-41BA-BB5D-2E6B3E7F994B),
version(1.0),
helpstring("ATLProject 1.0 类型库")
]
library ATLProjectLib
{
importlib("stdole2.tlb");
[
uuid(595C57A7-E16E-4443-803C-50D758B87917),
helpstring("ATLTest Class")
]
coclass ATLTest
{
[default] interface IATLTest;
};
[
uuid(D766CEC3-E2DB-4A83-B40E-5C2D4BE6A828),
helpstring("ATLAdd Class")
]
coclass ATLAdd
{
[default] interface IATLAdd;
};
};
在该idl文件中,定义了COM组件中接口及接口中有哪些方法。外部js是以接口来调用COM组件的。因此需要给外部的classid是接口的classid而不是组件的。如外部js调用COM组件的IATLAdd接口时:其在页面中可以这样加载该接口对象:
<object classid="clsid:D766CEC3-E2DB-4A83-B40E-5C2D4BE6A828" id="Add"
width="100" height="50">
</object>
这里的classid是D766CEC3-E2DB-4A83-B40E-5C2D4BE6A828,即ATLAdd的GUID,而不是组件的guid (即不是991C9BF9-7599-41BA-BB5D-2E6B3E7F994B)。
JS怎样调用c#编写的DLL
js调用COM接口说明
我们在开发COM组件给js调用时,需要提供给js的是COM接口的CLASSID,而不是组件的classid。如下为COM组件的一个idl文件:
// ATLProject.idl : ATLProject 的 IDL 源
//
// 此文件将由 MIDL 工具处理以
// 产生类型库(ATLProject.tlb)和封送处理代码。
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(67440A39-00DF-40C4-9E57-6856105F74D5),
dual,
nonextensible,
helpstring("IATLTest 接口"),
pointer_default(unique)
]
interface IATLTest : IDispatch{
};
[
object,
uuid(315CE559-7D6C-4FBB-B9AD-F7DB4D4BC1B6),
dual,
nonextensible,
helpstring("IATLAdd 接口"),
pointer_default(unique)
]
interface IATLAdd : IDispatch{
[id(1), helpstring("方法Add")] HRESULT Add(LONG Data1, LONG Data2, LONG* lSum);
};
[
uuid(991C9BF9-7599-41BA-BB5D-2E6B3E7F994B),
version(1.0),
helpstring("ATLProject 1.0 类型库")
]
library ATLProjectLib
{
importlib("stdole2.tlb");
[
uuid(595C57A7-E16E-4443-803C-50D758B87917),
helpstring("ATLTest Class")
]
coclass ATLTest
{
[default] interface IATLTest;
};
[
uuid(D766CEC3-E2DB-4A83-B40E-5C2D4BE6A828),
helpstring("ATLAdd Class")
]
coclass ATLAdd
{
[default] interface IATLAdd;
};
};
在该idl文件中,定义了COM组件中接口及接口中有哪些方法。外部js是以接口来调用COM组件的。因此需要给外部的classid是接口的classid而不是组件的。如外部js调用COM组件的IATLAdd接口时:其在页面中可以这样加载该接口对象:
<object classid="clsid:D766CEC3-E2DB-4A83-B40E-5C2D4BE6A828" id="Add"
width="100" height="50">
</object>
这里的classid是D766CEC3-E2DB-4A83-B40E-5C2D4BE6A828,即ATLAdd的GUID,而不是组件的guid (即不是991C9BF9-7599-41BA-BB5D-2E6B3E7F994B)。
一个简单的办法是用WebBrowser做媒介,作为网页的宿主对象,继而通过将控件的ObjectForScripting赋值为当前窗体对象,通过窗体对象去引申调用C#项目里的其他文件。
可是,往往我们不需要通过窗体里面套WebBrowser来解决,那窗体有时候也不需要么。OK,那我隐藏掉窗体,隐藏掉所有……呵呵,太牵强了总也能行可那总归是牵强。
本文给大家提供一种设计思路,不见得完全适用(微软的机器可以),但望能抛砖引玉,期望高人提出更好的解决方案。
下面,引入正题:将C#编写的DLL已COM组件形式注册,再由JS调用:
首先做准备工作:
1、为您的VS添加OLE/COM Object View工具
“工具>>外部工具”,点击添加,选择路径,默认在“C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin\OleView.Exe”(我的版本是VS2005 Team Suit)。填好相应参数就OK了。
3、开始编码,类Demo.cs
代码:
COM组件需要引用接口实现;GUID为COM的clasid;
GUID要通过以下方式创建:
点击“工具>>创建GUID”,如图:
4、设置程序集属性:
勾选“使程序集COM可见”,如下图
或者在AssemblyInfo.cs文件里面修改 “[assembly: ComVisible(true)]”。
同时,在“生成”里面勾选 “为COM Interop注册”。
5、生成项目,这时您就可以通过刚才添加的OLE View工具查看了。注意, COM组件的clsid为C#里面类(Demo.cs)上面的GUID。
默认在".NET Category"节点下查看,名称为您的程序集名称,如“DllCOMDemo.Demo”。
在选中的节点上右键选择“Copy HTML <object> Tag to Clipboard”,将COM组件的html代码复制到剪切板中。
6、创建TestDll.htm
lblinfor.innerHTML += "点击“" + event.srcElement.value + "”>>>"+ csObj.GetManInformation() + "<br />";
7、效果
这样子,我们就可以通过将C#代码注册成COM组件的形式来实现JS调用C#了。
以上是自动注册。
如果要手动注册COM组件(无论哪种注册方式“使程序集COM可见”必须设置为true),需要用到regasm.exe,默认%Windows\\Microsoft.NET\Framework\v2.0.50727%目录下。使用此命令注册时需要首先将程序集定义为“强程序集”,您可以使用al.exe为您的程序集产生一个密钥文件。这样,当您使用regasm注册时会自动在所在文件夹下自动搜索密钥文件注册。
如果使用regasm命令注册失败,请附带 /codebase参数。
如:regasm DllCOMDemo.dll /codebase DllCOMDemo.dll
同样,我们也可以通过这种思路将C#中的自定义控件以COM组件形式注册,然后在html页面内使用。当然,这个意义似乎不重要。
Demo.cs类代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace DllCOMDemo
{
[Guid("369588B3-0AC7-43fb-AB02-D92E9AC744AC")]
public interface IDemo
{
string Name { get;set;}
string Gender { get;set;}
DateTime Birthday { get;set;}
int GetAge();
string GetManInformation();
}
[Guid("437081BB-3023-49e7-9461-55326F08C44E")]
public class Demo : IDemo
{
string name = "华骨龙";
string gender = "男";
DateTime birthday = new DateTime(1987, 2, 8);
public string Name { get { return this.name; } set { this.name = value; } }
public string Gender { get { return this.gender; } set { this.gender = value; } }
public DateTime Birthday { get { return this.birthday; } set { this.birthday = value; } }
public int GetAge() { return DateTime.Now.Year - this.Birthday.Year; }
public string GetManInformation(){
return string.Format("姓名:{0};年龄:{1};性别:{2};生日:{3}", Name,GetAge(),Gender,Birthday);
}
public string SayHello(string name){ return "【Message from C# DLL】Hello " + name ; }
}
}
TestDll.htm代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> JS调用C#编写的DLL测试 </TITLE>
</HEAD>
<BODY>
<script type="text/javascript" language="javascript">
function GetManInfor(){
lblinfor.innerHTML += "点击“" + event.srcElement.value + "”>>>"
+ csObj.GetManInformation() + "<br />";
}
function SetCSObj(){
csObj.Name = "雨露思恋";
csObj.Gender = "男";
csObj.Birthday = "1980-05-20";
lblinfor.innerHTML += "Initialization Success!" + "<br />";
}
function GetAge(){
lblinfor.innerHTML += "点击“" + event.srcElement.value + "”>>>" + csObj.Name
+ "的年龄是:" + csObj.GetAge() + "<br />";
}
function SayHello(){
lblinfor.innerHTML += "点击“" + event.srcElement.value + "”>>>"
+ csObj.SayHello("Tom") + "<br />";
}
</script>
<object id="csObj" classid="clsid:437081BB-3023-49E7-9461-55326F08C44E" style="width:0;height:0"></object>
<input type="button" value="获取默认属性" οnclick="GetManInfor()" />
<input type="button" value="自定义设置" οnclick="SetCSObj()" />
<input type="button" value="重新读取" οnclick="GetManInfor()" />
<input type="button" value="获取年龄" οnclick="GetAge()" />
<input type="button" value="Say Hello To Tom" οnclick="SayHello()" />
<br /><br /><br />
<span id="lblinfor" />
</BODY>
</HTML>