您的位置:首页 > 编程语言 > C#

C#开发ActiveX控件及制作CAB包

2010-09-29 15:00 495 查看
一个项目要用到ActiveX控件,参照网上众多的例子,ActiveX控件倒是很容易就搞出来了;

然后做了一个【安装项目】,倒是可以使用,只不过需要在客户端手动点击安装,下一步,下一步…觉得不是很爽;

又试了试【CAB项目】,好像没人用VS2008来做,费了点功夫,终于找到解决办法。

特将此经验与大家分享。

开发工具:VisualStudio2008

.NET版本:2.0

开发语言:C#

一、编写ActiveX控件

1、新建一个【Windows窗体控件库项目】



2、添加一个【用户控件】



3、拖两个Label控件到界面上



4、为控件添加一个方法,用来设置在Label中显示当前时间

查看源代码
打印
?


//设置当前时间


public

void

SetTime(

string

timeStr)



{



this

.label2.Text=timeStr;



}


5、新建一个接口:

据说实现该接口的目的就是提高程序的安全性,以便客户端IE在不更改设置的情况下可以预行该ActiveX控件。

关于这个有篇文章,推荐大家看看:
http://blog.csdn.net/optman/archive/2007/07/18/1698070.aspx
查看源代码
打印
?

using

System;


using

System.Collections.Generic;


using

System.Text;


using

System.Runtime.InteropServices;


namespace

HelloBossma


{



[ComImport,GuidAttribute(

"CB5BDC81-93C1-11CF-8F20-00805F2CD064"

)]



[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]



public

interface

IObjectSafety



{



[PreserveSig]



int

GetInterfaceSafetyOptions(

ref

Guidriid,[MarshalAs(UnmanagedType.U4)]

ref

int

pdwSupportedOptions,[MarshalAs(UnmanagedType.U4)]

ref

int

pdwEnabledOptions);



[PreserveSig()]



int

SetInterfaceSafetyOptions(

ref

Guidriid,[MarshalAs(UnmanagedType.U4)]

int

dwOptionSetMask,[MarshalAs(UnmanagedType.U4)]

int

dwEnabledOptions);



}


}


6、让我们的控件实现这个接口

关于实现这个接口,篇幅较长,可以在这篇文章找到:
http://www.pinvoke.net/default.aspx/Interfaces/IObjectSafety.html
7、为我们的控件添加Guid、ProgId和ComVisible属性

查看源代码
打印
?

namespace

HelloBossma


{



[Guid(

"636B8CE1-7512-464C-B63C-FC75BDCA21DB"

),ProgId(

"HelloBossma.HelloBossmaActiveX"

),ComVisible(

true

)]



public

partial

class

HelloBossmaActiveX:UserControl,IObjectSafety



{


...



}


}


8、打开项目属性,在生成里边,勾选【为Com互操作注册】



9、生成项目,进入到bin/Release目录下可以看到

HelloBossma.dll

HelloBossma.tlb

这两个文件时必须的,否则生成不成功。

二、制作ActiveXSetup安装文件

1、新建一个安装项目



2、在项目上点右键,【添加】->【项目输出】,选择上边的项目



3、打开安装项目的属性页面,设置安装URL

这里设置为:http://localhost/hellobossma

这个目录必须是实际存在的,用来存放生成的安装文件,供客户端下载安装。

4、生成项目

会生成两个文件,一个exe文件和一个msi文件

5、新建一个网站,添加如下代码到网页中。

其中classid即为控件的Guid。

查看源代码
打印
?

<

object

classid

=

"clsid:636B8CE1-7512-464C-B63C-FC75BDCA21DB"

codebase

=

"hellobossma/setup.exe"

width

=

"442"

height

=

"49"

id

=

"helloBossma"

></

object

>


解压这个文件,里边有详细的使用说明。

6、将安装项目生成的exe和msi文件拷贝到网站hellobossma目录中。

HelloBossmaSetup.msi

setup.exe

7、启动网站,确保访问setup.exe的目录与【安装项目】中的【安装URL】一致。

8、一般情况下,网页会弹出提示,是否安装ActiveX控件等,如果提示了也不能安装,需要将网站添加到信任站点,并允许下载不安全和未签名控件。关于控件的签名和认证,本文不做说明,需要的请自行搜索。



使用这种安装方法,会在客户端弹出安装软件的界面,对客户来说,不太友好。

三、制作ActiveXCAB安装包

尝试了VS中的【CAB项目】模板,但是不幸的是,控件怎么也安装不上,放弃。

在网上看到很多人使用CABARC.EXE,试了一下,居然成功了,特将过程记录下来。

1、下载这个程序包,可以从微软下载,地址:

2、【开始】-【运行】,输入“CMD”,在打开的命令提示符界面中,进入解压后文件的BIN目录,

这里需要加入两个文件:

HelloBossmaSetup.msi

install.inf

HelloBossmaSetup.msi是上边的安装项目生成的安装程序。

install.inf是一个文本文件,指定运行控件所需要下载或者呈交的文件。

关于inf文件的书写规范,这里不做介绍,有需要的可以自己搜一下。

这个例子中install.inf文件的内容

查看源代码
打印
?

[version]


signature="$CHICAGO$"


AdvancedINF=2.0


[SetupHooks]


hook1=hook1


[hook1]


run=msiexec.exe/i"%EXTRACT_DIR%/HelloBossmaSetup.msi"/qn


有了这两个文件,运行下边的命令,成功的话会在当前目录生成HelloBossma.cab文件。



3、把这个文件放到控件下载目录中,然后修改网页中的调用方式。

查看源代码
打印
?

<

object

classid

=

"clsid:636B8CE1-7512-464C-B63C-FC75BDCA21DB"

codebase

=

"hellobossma/HelloBossma.CAB"

width

=

"442"

height

=

"49"

id

=

"helloBossma"

>


</

object

><

input

onclick

=

"helloBossma.SetTime((newDate()).getTime())"

type

=

"button"

value

=

"Click"

/>


这里还添加了一个按钮,点击时触发一个事件,调用控件的显示时间方法,点击按钮,你会发现控件上时间的变化。



OK,这篇文章到这里正文就结束了。

只是简单了解下使用C#开发ActiveX控件,很多东西还没弄清楚,有问题的话,欢迎提出来。

1、开发及测试环境:

(1)开发环境:

VisualStudio2008SP1

cabsdk(下载地址:http://support.microsoft.com/kb/310618
)

(2)测试环境:

WindowsServer2003R2SP2

IE6

2、创建项目



我这里创建了三个项目:

(1)HelloBossma:

项目模板:Windows窗体控件库

(2)HelloBossmaSetup:

项目模板:安装项目

(3)Web:

项目模板:ASP.NET网站

3、HelloBossma项目

这个项目用于编写具体的控件,并生成安装文件所需要的dll。

(1)添加用户控件:



(2)设计控件:



添加Panel、GroupBox、Label控件。NowTime是一个Label控件,用于显示时间。

然后在控件对应的代码文件中编写程序:

查看源代码
打印
?

using

System;


using

System.Collections.Generic;


using

System.ComponentModel;


using

System.Drawing;


using

System.Data;


using

System.Text;


using

System.Windows.Forms;


using

System.Runtime.InteropServices;


namespace

HelloBossma


{



///<summary>



///Guid将用作控件的classid



///IObjectSafety的是用来标记可安全执行脚本的ActiveX控件



///</summary>



[Guid(

"636B8CE1-7512-464C-B63C-FC75BDCA21DB"

),ProgId(

"HelloBossma.HelloBossmaActiveX"

),ComVisible(

true

)]



public

partial

class

HelloBossmaActiveX:UserControl,IObjectSafety



{



private

const

string

_IID_IDispatch=

"{00020400-0000-0000-C000-000000000046}"

;



private

const

string

_IID_IDispatchEx=

"{a6ef9860-c720-11d0-9337-00a0c90dcaa9}"

;



private

const

string

_IID_IPersistStorage=

"{0000010A-0000-0000-C000-000000000046}"

;



private

const

string

_IID_IPersistStream=

"{00000109-0000-0000-C000-000000000046}"

;



private

const

string

_IID_IPersistPropertyBag=

"{37D84F60-42CB-11CE-8135-00AA004BB851}"

;



private

const

int

INTERFACESAFE_FOR_UNTRUSTED_CALLER=0x00000001;



private

const

int

INTERFACESAFE_FOR_UNTRUSTED_DATA=0x00000002;



private

const

int

S_OK=0;



private

const

int

E_FAIL=

unchecked

((

int

)0x80004005);



private

const

int

E_NOINTERFACE=

unchecked

((

int

)0x80004002);



private

bool

_fSafeForScripting=

true

;



private

bool

_fSafeForInitializing=

true

;



public

HelloBossmaActiveX()



{



InitializeComponent();



}



///<summary>



///设置当前时间



///</summary>



///<paramname="timeStr"></param>



public

void

SetTime(

string

timeStr)



{



this

.label2.Text=timeStr;



}



public

int

GetInterfaceSafetyOptions(

ref

Guidriid,



ref

int

pdwSupportedOptions,



ref

int

pdwEnabledOptions)



{



int

Rslt=E_FAIL;



string

strGUID=riid.ToString(

"B"

);



pdwSupportedOptions=INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA;



switch

(strGUID)



{



case

_IID_IDispatch:



case

_IID_IDispatchEx:



Rslt=S_OK;



pdwEnabledOptions=0;



if

(_fSafeForScripting==

true

)



pdwEnabledOptions=INTERFACESAFE_FOR_UNTRUSTED_CALLER;



break

;



case

_IID_IPersistStorage:



case

_IID_IPersistStream:



case

_IID_IPersistPropertyBag:



Rslt=S_OK;



pdwEnabledOptions=0;



if

(_fSafeForInitializing==

true

)



pdwEnabledOptions=INTERFACESAFE_FOR_UNTRUSTED_DATA;



break

;



default

:



Rslt=E_NOINTERFACE;



break

;



}



return

Rslt;



}



public

int

SetInterfaceSafetyOptions(

ref

Guidriid,



int

dwOptionSetMask,



int

dwEnabledOptions)



{



int

Rslt=E_FAIL;



string

strGUID=riid.ToString(

"B"

);



switch

(strGUID)



{



case

_IID_IDispatch:



case

_IID_IDispatchEx:



if

(((dwEnabledOptions&dwOptionSetMask)==INTERFACESAFE_FOR_UNTRUSTED_CALLER)&&



(_fSafeForScripting==

true

))



Rslt=S_OK;



break

;



case

_IID_IPersistStorage:



case

_IID_IPersistStream:



case

_IID_IPersistPropertyBag:



if

(((dwEnabledOptions&dwOptionSetMask)==INTERFACESAFE_FOR_UNTRUSTED_DATA)&&



(_fSafeForInitializing==

true

))



Rslt=S_OK;



break

;



default

:



Rslt=E_NOINTERFACE;



break

;



}



return

Rslt;



}



}


}


关于IObjectSafety的实现参考了:http://www.pinvoke.net/default.aspx/Interfaces/IObjectSafety.html

查看源代码
打印
?

using

System;


using

System.Collections.Generic;


using

System.Text;


using

System.Runtime.InteropServices;


namespace

HelloBossma


{



[ComImport,GuidAttribute(

"CB5BDC81-93C1-11CF-8F20-00805F2CD064"

)]



[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]



public

interface

IObjectSafety



{



[PreserveSig]



int

GetInterfaceSafetyOptions(

ref

Guidriid,[MarshalAs(UnmanagedType.U4)]

ref

int

pdwSupportedOptions,[MarshalAs(UnmanagedType.U4)]

ref

int

pdwEnabledOptions);



[PreserveSig()]



int

SetInterfaceSafetyOptions(

ref

Guidriid,[MarshalAs(UnmanagedType.U4)]

int

dwOptionSetMask,[MarshalAs(UnmanagedType.U4)]

int

dwEnabledOptions);



}


}


这里还包含了一个可以被外部调用的方法,传进来一个字符参数,并显示出来:

查看源代码
打印
?

///<summary>



///设置当前时间



///</summary>



///<paramname="timeStr"></param>



public

void

SetTime(

string

timeStr)



{



this

.label2.Text=timeStr;



}


(3)设置生成属性,勾选:为Com互操作注册



(4)生成项目,生成这两个文件:

HelloBossma.dll

HelloBossma.tlb

是必须的,否则生成不成功。

4、HelloBossmaSetup项目

这是一个安装项目,用来生成安装程序。

(1)在项目上点右键,【添加】->【项目输出】,选择上边的HelloBossma项目



(2)在安装项目上点右键,属性



安装URL:貌似用于查找应用程序更新,具体看:http://msdn.microsoft.com/zh-cn/library/c37e68bc(VS.90).aspx

这个目录最好是实际存在的,用来存放生成的安装文件,供客户端下载安装。没有的话就随便输入一个吧。

(3)添加卸载程序

拷贝文件C:/Windows/System32/msiexec.exe文件,修改文件名为Uninstall.exe,添加到安装项目中,然后创建一个快捷方式。

在【用户的“程序”菜单下边】添加一个文件夹HelloBossma,将快捷方式拖动到这里边。



在卸载控件上点击右键,属性:



设置Arguments,就是指定要卸载的程序,后面的ProductCode可以这样获得:



选中项目,然后鼠标放到右侧的“属性”上,就可以看到ProductCode了:



(4)最后生成项目

5、制作CAB文件

(1)为了方便操作,可以将CABARC.EXE添加到环境变量中:桌面上右击“我的电脑”,“属性”,“高级”,“环境变量”,“系统变量”,找到“Path”,在后边把CABARC.EXE所在的路径添加上去,注意用分号隔开新添加的路径。



(2)准备好文件

install.inf:CAB安装配置文件

HelloBossmaSetup.msi:安装程序文件

install.inf文件的内容:

查看源代码
打印
?

[version]


signature="$CHICAGO$"


AdvancedINF=2.0


[SetupHooks]


hook1=hook1


[hook1]


run=msiexec.exe/i"%EXTRACT_DIR%/HelloBossmaSetup.msi"/qn


run:一般只需要修改这个就行了

(3)执行cabarc命令

桌面左下角“开始”,“运行”,输入cmd,打开命令提示符工具,进入准备好的文件的目录,执行命令:

cabarcnHelloBossma.cabHelloBossmaSetup.msiinstall.inf



显示“Completedsuccessfully”,打开所在目录,就可以看到生成的文件了。

6、部署到网站

在网站中新建一个目录hellobossma,将生成的cab文件拷贝到里边。

新建一个网页,将控件添加到页面:

查看源代码
打印
?

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""<

a

href

=

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"

>http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</

a

>">


<

html

xmlns

=

"<ahref="

http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</

a

>">


<

head

runat

=

"server"

>



<

title

></

title

>



<

script

type

=

"text/javascript"

>



functionSetTime(){



vard=newDate();



varvYear=d.getFullYear();



varvMon=d.getMonth()+1;



varvDay=d.getDate();



varvHour=d.getHours();



varvMin=d.getMinutes();



varvSec=d.getSeconds();



document.HelloBossma.SetTime(vYear+"-"+vMon+"-"+vDay+""+vHour+":"+vMin+":"+vSec)



}



</

script

>


</

head

>


<

body

style

=

"font-size:12px;color:black"

>



<

form

id

=

"form1"

runat

=

"server"

>



<

div

>



<

object

classid

=

"clsid:636B8CE1-7512-464C-B63C-FC75BDCA21DB"

codebase

=

"hellobossma/HelloBossma.CAB"

width

=

"442"

height

=

"87"

id

=

"HelloBossma"

name

=

"HelloBossma"

>



</

object

>



<

br

/>



<

br

/>



<

input

type

=

"button"

value

=

"显示当前时间"

onclick

=

"SetTime()"

/>



</

div

>



</

form

>


</

body

>


</

html

>


ActiveX控件作为一个object添加到页面中,其classid是在编写HelloBossmaActiveX类时定义好的Guid值,codebase用来指示cab安装文件的路径,还可以设置宽度、高度。另外其中文字受页面中字体样式的影响。

因为我们的ActiveX控件没有签名,所以将测试站点加到“本地Intranet”中或者“可信站点”中,并设置安全级别为“低”。



然后打开浏览器,提示安装,点击“安装”,稍等下,效果就出来了:



点击按钮,就可以通过javascript设置ActiveX控件中的时间了。

Over!

这篇文章是一个简单的例子,没有进行更广范围平台的测试,后续文章会逐渐加入。

1、方法一

(1)在VS项目中添加Com对象引用:MicrosoftHtmlObjectLibrary(mshtml.tlb)



(2)ActiveX中公开一个方法,传递window对象到ActiveX中

ActiveX中公开一个方法,接受传递进来的参数

查看源代码
打印
?


///<summary>



///将window对象传递进来



///</summary>



///<paramname="obj">Theobj.</param>



public

void

SetHtml(

object

obj)



{



html=(mshtml.HTMLWindow2Class)obj;



}


在页面中调用ActiveX的公开方法,传递当前window对象进去:

查看源代码
打印
?

window.onload=

function

(){



document.HelloBossma.SetHtml(

this

);



};


(3)在ActiveX控件中添加一个按钮,当点击这个按钮时,触发页面中的javascript。



点击按钮的方法:

查看源代码
打印
?

///<summary>



///调用页面Javascript



///</summary>



///<paramname="sender"></param>



///<paramname="e"></param>



private

void

button1_Click(

object

sender,EventArgse)



{



html.execScript(

"CallByActiveX();"

,

"javascript"

);



}


现在卸载掉原来的ActiveX控件,安装新的控件,打开页面,点击按钮,看到如下效果,说明成功。



调用javascript时还可以传递参数,这里不做演示了,自己可以试一下。

参考:http://www.cnblogs.com/liubiqu/articles/92632.html

2、方法二

(1)在VS项目中添加Com对象引用:MicrosoftHtmlObjectLibrary(mshtml.tlb)

和第一种方法相同。

(2)用c#实现两个COM类,IOleClientSite和IOleContainer

查看源代码
打印
?

using

System;


using

System.Collections.Generic;


using

System.Text;


using

System.Runtime.InteropServices;


namespace

HelloBossma


{



[ComImport,



Guid(

"00000118-0000-0000-C000-000000000046"

),



InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]



public

interface

IOleClientSite



{



void

SaveObject();



void

GetMoniker(

uint

dwAssign,

uint

dwWhichMoniker,

object

ppmk);



void

GetContainer(

out

IOleContainerppContainer);



void

ShowObject();



void

OnShowWindow(

bool

fShow);



void

RequestNewObjectLayout();



}



[ComImport,



Guid(

"0000011B-0000-0000-C000-000000000046"

),



InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]



public

interface

IOleContainer



{



void

EnumObjects([In,MarshalAs(UnmanagedType.U4)]

int

grfFlags,



[Out,MarshalAs(UnmanagedType.LPArray)]

object

[]ppenum);



void

ParseDisplayName([In,MarshalAs(UnmanagedType.Interface)]

object

pbc,



[MarshalAs(UnmanagedType.BStr)]

string

pszDisplayName,



[Out,MarshalAs(UnmanagedType.LPArray)]

int

[]pchEaten,



[Out,MarshalAs(UnmanagedType.LPArray)]

object

[]ppmkOut);



void

LockContainer([In,MarshalAs(UnmanagedType.I4)]

int

fLock);



}


}


(3)在ActiveX中编写CallJavascript方法:

查看源代码
打印
?

///<summary>



///调用Javascript



///</summary>



///<paramname="Filenames">Thefilenames.</param>



private

void

CallJavaScript(

string

param)



{



//反射获取当前的控件的ClientSite



TypetypeIOleObject=

this

.GetType().GetInterface(

"IOleObject"

,

true

);



object

oleClientSite=typeIOleObject.InvokeMember(

"GetClientSite"

,



BindingFlags.Instance|BindingFlags.InvokeMethod|BindingFlags.Public,



null

,



this

,



null

);



//获取Container



IOleClientSiteoleClientSite2=oleClientSite

as

IOleClientSite;



IOleContainerpObj;



oleClientSite2.GetContainer(

out

pObj);



//参数数组



object

[]args=

new

object

[1];



args[0]=param;



//获取页面的Script集合



IHTMLDocumentpDoc2=(IHTMLDocument)pObj;



object

script=pDoc2.Script;



try



{



//调用JavaScript方法OnScaned并传递参数,因为此方法可能并没有在页面中实现,所以要进行异常处理



script.GetType().InvokeMember(

"ShowNowTime"

,BindingFlags.Instance|BindingFlags.InvokeMethod|BindingFlags.Public,



null

,



script,



args);



}



catch

{}



}


点击按钮时的操作:

查看源代码
打印
?

///<summary>



///调用Javascript



///</summary>



///<paramname="sender"></param>



///<paramname="e"></param>



private

void

button1_Click(

object

sender,EventArgse)



{



CallJavaScript(

this

.label2.Text);



}


(4)网页中的javascript

查看源代码
打印
?

function

ShowNowTime(nowtime){



alert(

"当前时间:"

+nowtime);



}


卸载原来的ActiveX控件,重新安装,实际效果:



1、更新Activex的版本:

(1)在ActiveX项目上点右键,属性,应用程序,程序集信息,最初的版本是1.0.0.0,修改为1.0.1.0



(2)修改控件,以区别1.0.0.0版本,修改V1.0.0为V1.0.1



(3)然后重新生成。

2、修改安装程序

(1)添加注册表项

在项目上点右键,视图,注册表:



在HKEY_CLASSES_ROOT下创建CLSID/{ActiveX的GUID}/InstalledVersion/,

在InstalledVersion下新建字符串值,修改字符串的值为”1,0,1,0″,

注意:删除名称中的值,自动会显示“(默认值)”,这样才能设置注册表中默认值,不要自己输入“默认值”。



(2)修改安装程序版本



修改Version为”1.0.1″,修改RemovePreviousVersions为”True”。

(3)重新生成安装程序

3、重新制作CAB安装包

cabarcnHelloBossma.cabHelloBossmaSetup.msiinstall.inf

4、修改网站

(1)将生成的CAB安装包替换原来的安装包。

(2)修改页面控件版本

查看源代码
打印
?

<

object

classid

=

"clsid:636B8CE1-7512-464C-B63C-FC75BDCA21DB"

codebase

=

"hellobossma/HelloBossma.CAB#version=1,0,1,0"

width

=

"442"

height

=

"116"

id

=

"HelloBossma"

name

=

"HelloBossma"

>



</

object

>


5、最终效果

刷新页面,提示安装新的版本,直接安装就好了。



1、测试环境:Windows7+IE8

2、修改之前,直接访问页面看看,发现出错了:



出错行:document.HelloBossma.SetTime(vYear+“-”+vMon+“-”+vDay+””+vHour+“:”+vMin+“:”+vSec)

然后到控制面中没有找到安装的ActiveX程序,结合出错行,大致得出结论:ActiveX没有安装成功!

3、修改文件

install.inf:

查看源代码
打印
?

[version]


signature="$CHICAGO$"


AdvancedINF=2.0


[SetupHooks]


hook1=hook1


[Deployment]


InstallScope=machine


[hook1]


run=%EXTRACT_DIR%/run.bat


新加[Deployment],关于这个项目看:http://msdn.microsoft.com/zh-cn/library/dd433049(en-us,VS.85).aspx

InstallScope=machine我这里只能用这个,改成user无法安装成功,原因未知。

另外在vista以后的版本只能执行cab中的文件了,所以msiexec转移到了bat中执行,添加一个bat文件。

run.bat:

查看源代码
打印
?

setCURDIR=%cd%


msiexec.exe/i"%CURDIR%/HelloBossmaSetup.msi"/qn


4、制作CAB包

重新制作CAB包,添加一个run.bat:

查看源代码
打印
?

cabarcnHelloBossma.cabHelloBossmaSetup.msiinstall.infrun.bat


5、在浏览器安装

输入网址,提示安装,然后出现命令运行框,然后消失。

如果安装成功,会出现控件界面。



6、一个兼容性问题

这时候会发现,浏览器左下角有javascript错误,同时点击CallJavascript发生异常。



无法将类型为“Systerm._ComObject”的COM对象强制转换为类类型“mshtml.HTMLWindow2Class”。

在XP、WindowsServer2003中都没有问题,Windows7上出现问题,可能是权限设置问题。

按照上边的提示,找到出现问题的地方:

Default.aspx:

查看源代码
打印
?

window.onload=

function

(){



document.HelloBossma.SetHtml(

this

);



};


HelloBossmaActiveX.cs

查看源代码
打印
?

publicvoidSetHtml(objectobj)



{


//问题出在这里,类型转换的问题



html=(mshtml.HTMLWindow2Class)obj;



}


按照提示,我们可以把它转换为接口试试,在网上找到了HTMLWindow2Class的定义,

查看源代码
打印
?

public

class

HTMLWindow2Class
:System.__ComObject,MSHTML.IHTMLFramesCollection2,
MSHTML.IHTMLWindow2,mshtml.IHTMLWindow3,mshtml.IHTMLWindow4,
mshtml.DispHTMLWindow2,mshtml.HTMLWindowEvents_Event,
mshtml.HTMLWindowEvents2_Event,mshtml.HTMLWindow2


{


}


经过测试,IHTMLWindow2定义了execScript,所以修改SetHtml为:

查看源代码
打印
?

privatemshtml.IHTMLWindow2html=

null

;


publicvoidSetHtml(objectobj)



{



html=objasmshtml.IHTMLWindow2;



}


如果你需要其它的方法,换换接口试试。

重新编译,重新安装控件,OK了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: