Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结.doc_第1页
Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结.doc_第2页
Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结.doc_第3页
Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结.doc_第4页
Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结.doc_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

开发及测试环境:(1)开发环境: Visual Studio 2008 SP1 cabsdk(下载地址:/kb/310618)(2)测试环境: Windows Server 2003 R2 SP2 IE62、创建项目我这里创建了三个项目:(1)HelloBossma :项目模板:Windows窗体控件库(2)HelloBossmaSetup:项目模板:安装项目(3)Web:项目模板:ASP.NET 网站3、HelloBossma项目这个项目用于编写具体的控件,并生成安装文件所需要的dll。(1)添加用户控件:(2)设计控件:添加Panel、GroupBox、Label 控件。NowTime是一个Label控件,用于显示时间。然后在控件对应的代码文件中编写程序:usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Drawing;usingSystem.Data; usingSystem.Text; usingSystem.Windows.Forms; usingSystem.Runtime.InteropServices;namespaceHelloBossma / / Guid将用作控件的classid / IObjectSafety的是用来标记可安全执行脚本的ActiveX控件 / 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(); / / 设置当前时间 / / public void SetTime(string timeStr) this.label2.Text = timeStr; public int GetInterfaceSafetyOptions(ref Guid riid, 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 Guid riid, 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的实现参考了:/default.aspx/Interfaces/IObjectSafety.htmlusing 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 Guid riid, MarshalAs(UnmanagedType.U4)ref int pdwSupportedOptions, MarshalAs(UnmanagedType.U4) ref intpdwEnabledOptions); PreserveSig() int SetInterfaceSafetyOptions(ref Guid riid, MarshalAs(UnmanagedType.U4)int dwOptionSetMask, MarshalAs(UnmanagedType.U4) int dwEnabledOptions); 这里还包含了一个可以被外部调用的方法,传进来一个字符参数,并显示出来:/ / 设置当前时间 / / public void SetTime(string timeStr) this.label2.Text = timeStr; (3)设置生成属性,勾选:为Com互操作注册(4)生成项目,生成这两个文件:HelloBossma.dllHelloBossma.tlb是必须的,否则生成不成功。4、HelloBossmaSetup项目这是一个安装项目,用来生成安装程序。(1)在项目上点右键,【添加】-【项目输出】,选择上边的HelloBossma项目(2)在安装项目上点右键,属性安装URL:貌似用于查找应用程序更新,具体看:/zh-cn/library/c37e68bc(VS.90).aspx这个目录最好是实际存在的,用来存放生成的安装文件,供客户端下载安装。没有的话就随便输入一个吧。(3)添加卸载程序拷贝文件C:WindowsSystem32msiexec.exe文件,修改文件名为Uninstall.exe,添加到安装项目中,然后创建一个快捷方式。在【用户的“程序”菜单下边】添加一个文件夹HelloBossma,将快捷方式拖动到这里边。在卸载控件上点击右键,属性:设置Arguments,就是指定要卸载的程序,后面的ProductCode可以这样获得:选中项目,然后鼠标放到右侧的“属性”上,就可以看到ProductCode了:(4)最后生成项目5、制作CAB文件(1)为了方便操作,可以将CABARC.EXE添加到环境变量中:桌面上右击“我的电脑”,“属性”,“高级”,“环境变量”,“系统变量”,找到“Path”,在后边把CABARC.EXE所在的路径添加上去,注意用分号隔开新添加的路径。(2)准备好文件install.inf :CAB安装配置文件HelloBossmaSetup.msi:安装程序文件install.inf文件的内容:versionsignature=$CHICAGO$AdvancedINF=2.0 Setup Hookshook1=hook1 hook1run=msiexec.exe /i %EXTRACT_DIR%HelloBossmaSetup.msi /qnrun:一般只需要修改这个就行了(3)执行cabarc命令桌面左下角“开始”,“运行”,输入cmd,打开命令提示符工具,进入准备好的文件的目录,执行命令:cabarc n HelloBossma.cab HelloBossmaSetup.msi install.inf显示“Completed successfully” ,打开所在目录,就可以看到生成的文件了。6、部署到网站在网站中新建一个目录hellobossma,将生成的cab文件拷贝到里边。新建一个网页,将控件添加到页面:!DOCTYPE html PUBLIC -/W3C/DTD XHTML 1.0 Transitional/EN /TR/xhtml1/DTD/xhtml1-transitional.dtdhtml xmlns=/1999/xhtml function SetTime() var d = new Date(); var vYear = d.getFullYear(); var vMon = d.getMonth() + 1; var vDay = d.getDate(); var vHour = d.getHours(); var vMin = d.getMinutes(); var vSec = d.getSeconds(); document.HelloBossma.SetTime(vYear + - + vMon + - + vDay + + vHour + : + vMin + : + vSec) ActiveX控件作为一个object添加到页面中,其classid是在编写HelloBossmaActiveX类时定义好的Guid值,codebase用来指示cab安装文件的路径,还可以设置宽度、高度。另外其中文字受页面中字体样式的影响。因为我们的ActiveX控件没有签名,所以将测试站点加到“本地Intranet”中或者“可信站点”中,并设置安全级别为“低”。然后打开浏览器,提示安装,点击“安装”,稍等下,效果就出来了:点击按钮,就可以通过javascript设置ActiveX控件中的时间了。C#如何在ActiveX控件中调用javascript的函数,这里参考网上的例子介绍两种方法,虽然代码不一样,但是殊途同归。而且都使用了mshtml。1、方法一(1)在VS项目中添加Com对象引用:Microsoft Html Object Library(mshtml.tlb)(2)ActiveX中公开一个方法,传递window对象到ActiveX中ActiveX中公开一个方法,接受传递进来的参数 / / 将window对象传递进来 / / The obj. public void SetHtml(object obj) html = (mshtml.HTMLWindow2Class)obj; 在页面中调用ActiveX的公开方法,传递当前window对象进去:window.onload = function() document.HelloBossma.SetHtml(this); ;(3)在ActiveX控件中添加一个按钮,当点击这个按钮时,触发页面中的javascript。点击按钮的方法:/ / 调用页面Javascript / / / private void button1_Click(object sender, EventArgs e) html.execScript(CallByActiveX();, javascript); 现在卸载掉原来的ActiveX控件,安装新的控件,打开页面,点击按钮,看到如下效果,说明成功。调用javascript时还可以传递参数,这里不做演示了,自己可以试一下。参考:/liubiqu/articles/92632.html2、方法二(1)在VS项目中添加Com对象引用:Microsoft Html Object Library(mshtml.tlb)和第一种方法相同。(2)用c#实现两个COM类,IOleClientSite和IOleContainerusing 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 IOleContainer ppContainer); 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方法:/ / 调用Javascript / / The filenames. private void CallJavaScript(string param) /反射获取当前的控件的ClientSite Type typeIOleObject = this.GetType().GetInterface(IOleObject, true); object oleClientSite = typeIOleObject.InvokeMember(GetClientSite, BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, this, null); /获取Container IOleClientSite oleClientSite2 = oleClientSite as IOleClientSite; IOleContainer pObj; oleClientSite2.GetContainer(out pObj); /参数数组 object args = new object1; args0 = param; /获取页面的Script集合 IHTMLDocument pDoc2 = (IHTMLDocument)pObj; object script = pDoc2.Script; try /调用JavaScript方法OnScaned并传递参数,因为此方法可能并没有在页面中实现,所以要进行异常处理 script.GetType().InvokeMember(ShowNowTime, BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, script, args); catch 点击按钮时的操作:/ / 调用Javascript / / / private void button1_Click(object sender, EventArgs e) CallJavaScript(this.label2.Text); (4)网页中的javascriptfunction ShowNowTime(nowtime) alert(当前时间: + nowtime); 卸载原来的ActiveX控件,重新安装,实际效果:1、更新Activex的版本:(1)在ActiveX项目上点右键,属性,应用程序,程序集信息,最初的版本是,修改为(2)修改控件,以区别版本,修改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安装包cabarc n HelloBossma.cab HelloBossmaSetup.msi install.inf4、修改网站(1)将生成的CAB安装包替换原来的安装包。(2)修改页面控件版本 5、最终效果刷新页面,提示安装新的版本,直接安装就好了。测试ActiveX控件在新版操作系统上运行的问题,并提出解决的办法。主要是ActiveX程序兼容性和CAB文件的安装问题。我在Vitual PC上安装了Windows 7,并且使用IE8浏览器。1、测试环境:Windows 7 + IE82、修改之前,直接访问页面看看,发现出错了:出错行:document.HelloBossma.SetTime(vYear + “-” + vMon + “-” + vDay + ” ” + vHour + “:” + vMin + “:” + vSec)然后到控制面中没有找到安装的ActiveX程序,结合出错行,大致得出结论:ActiveX没有安装成功!3、修改文件install.inf:versionsignature=$CHICAGO$AdvancedINF=2.0Setup Hookshook1=hook1DeploymentInstallScope=machinehook1run=%EXTRACT_DIR%run.bat新加Deployment,关于这个项目看:/zh-cn/library/dd433049(en-us,VS.85).aspxInstallScope=machine 我这里只能用这个,改成user无法安装成功,原因未知。另外在vista以后的版本只能执行cab中的文件了,所以msiexec转移到了bat中执行,添加一个bat文件。run.bat:set CURDIR=%cd%msiexec.exe /i %CURDIR%HelloBossm

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论