web打开本地程序,未安装则提示要求安装的实现攻略
2013-07-24 11:59
423 查看
需求:根据需求,在打开商城的需要提供打开客户端功能,比如点击商城的购买,需要提示客户安装客户端程序,如果已经安装,则直接打开客户端,类似于QQ
目前有两种方式来实现该功能
1通过JS调用WScript.shell,检测注册表是否已经安装客户端,如果安装在通过Run打开,并且可以传递参数到客户端程序
打开客户端示例:
1.1该方法的缺点:需要降低IE安全性,对客户对IE的熟悉度有要求,而且只能在IE上实现,其他浏览器不支持
2通过注册表协议,打开客户端
第一步:注册协议到客户端注册表中,下面是注册内容
把这段内容保存成.reg格式的文件,然后双击注册到注册表;也可以通过打包成.reg文件,在程序安装的时候注册到注册表
第二步:制作自定义Activex控件(该内容是网上收集的资料,仅做学习用)
利用VS2010作自定义activex控件
首先在解决方案下建一个Windows控件库项目(windowsfromcontrollibrary),然后增加一个控件UstcOriWebLab.cs。
打开AssemblyInfo.cs修改程序集信息。引用System.Security命名空间,并添加[assembly:AllowPartiallyTrustedCallers()]安全声明,修改[assembly:ComVisible(false)]为[assembly:
ComVisible(true)]使程序集Com可见。
如果此项目向COM公开,则下列GUID用于类型库的ID
[assembly:Guid("F325140B-90E3-42d7-8F27-F1E68E1BD92E")],主要在AssemblyInfo中的GUID应当跟UstcOriWebLabActivex的GUID一致,否则程序会出现问题,惨痛的教训,就这个细节,把哥给整了1天
为ComInterop注册。右键demoActiveX项目属性,在“生成”选项卡里将“为ComInterop注册”打上勾即可。
选择菜单工具->创建Guid工具生成一个新的Guid{F325140B-90E3-42d7-8F27-F1E68E1BD92E},copy下来,加在类头上[Guid("F325140B-90E3-42d7-8F27-F1E68E1BD92E"),ProgId("UstcOriWebLabActivex.UstcOriWebLab"),ComVisible(true)],F325140B-90E3-42d7-8F27-F1E68E1BD92E就是写入注册表的CLSID,UstcOriWebLabActivex.UstcOriWebLab为键名。
实现IObjectSafety接口,把ActiveX控件标记为安全的。
ActiveX危险,那么为什么QQ以及MediaPlayer等都是用ActiveX的方式创建的,却没有问题?原来,这是因为这些ActiveX组件都声明自己是脚本安全的,而IE的中级安全设置上,是允许脚本安全的ActiveX创建,并且不予警告的。
IE怎么知道一个插件是脚本安全的?它是通过以下两个办法。一是查询ActiveX组件是否实现了IObjectSafety接口,并且返回脚本安全;二是查询ActiveX组件是否在注册表的ComponentCategoryManager里表明自己实现了CATID_SafeForInitializing和CATID_SafeForScripting。(参考http://blog.csdn.net/optman/archive/2007/07/18/1698070.aspx)
那么我们就通过实现IObjectSafety接口
建一个接口文件IObjectSafety.cs,内容如下:
在UstcOriWebLab.cs中实现接口
f、开始制作安装包
新建一个安装项目,在项目上点右键,【添加】->【项目输出】,添加刚才的项目,生成项目,这样我们的activex控件就会和客户端程序一起安装到用户的机器上了。会生成两个文件,一个exe文件和一个msi文件。
安装后,就是自动写入注册表键UstcOriWebLabActivex.UstcOriWebLab。
第三步:客户端通过js检查:
目前有两种方式来实现该功能
1通过JS调用WScript.shell,检测注册表是否已经安装客户端,如果安装在通过Run打开,并且可以传递参数到客户端程序
打开客户端示例:
functionopenexe(){ try{ debugger; varwsh=newActiveXObject("WScript.shell"); vars1='123|'; vars2='456|'; varc="file:///C:/Program%20Files%20(x86)/test//StudyActSystem.exe";//路径最后需要空格
wsh.Run(c+s1+s2);//运行程序 } catch(e){ alert(e.message+"\n可能原因如下:\n1、请检测安装路径是否正确\n2、Internet选项->安全->自定义级别->对没有标记为安全的ActiveX控件进行初始化和脚本运行->启用3、请确认是否已经安装客户端"); } }
1.1该方法的缺点:需要降低IE安全性,对客户对IE的熟悉度有要求,而且只能在IE上实现,其他浏览器不支持
2通过注册表协议,打开客户端
第一步:注册协议到客户端注册表中,下面是注册内容
WindowsRegistryEditorVersion5.00 [HKEY_CLASSES_ROOT\test] "URLProtocol"="C:\\ProgramFiles(x86)\\test\\StudyActSystem.exe" @="testProtocol" [HKEY_CLASSES_ROOT\test\DefaultIcon] @="C:\\ProgramFiles(x86)\\test\\StudyActSystem.exe,1" [HKEY_CLASSES_ROOT\test\shell] [HKEY_CLASSES_ROOT\test\shell\open] [HKEY_CLASSES_ROOT\test\shell\open\command] @="\"C:\\ProgramFiles(x86)\\test\\StudyActSystem.exe\"\"%1\""
把这段内容保存成.reg格式的文件,然后双击注册到注册表;也可以通过打包成.reg文件,在程序安装的时候注册到注册表
第二步:制作自定义Activex控件(该内容是网上收集的资料,仅做学习用)
利用VS2010作自定义activex控件
首先在解决方案下建一个Windows控件库项目(windowsfromcontrollibrary),然后增加一个控件UstcOriWebLab.cs。
打开AssemblyInfo.cs修改程序集信息。引用System.Security命名空间,并添加[assembly:AllowPartiallyTrustedCallers()]安全声明,修改[assembly:ComVisible(false)]为[assembly:
ComVisible(true)]使程序集Com可见。
如果此项目向COM公开,则下列GUID用于类型库的ID
[assembly:Guid("F325140B-90E3-42d7-8F27-F1E68E1BD92E")],主要在AssemblyInfo中的GUID应当跟UstcOriWebLabActivex的GUID一致,否则程序会出现问题,惨痛的教训,就这个细节,把哥给整了1天
为ComInterop注册。右键demoActiveX项目属性,在“生成”选项卡里将“为ComInterop注册”打上勾即可。
选择菜单工具->创建Guid工具生成一个新的Guid{F325140B-90E3-42d7-8F27-F1E68E1BD92E},copy下来,加在类头上[Guid("F325140B-90E3-42d7-8F27-F1E68E1BD92E"),ProgId("UstcOriWebLabActivex.UstcOriWebLab"),ComVisible(true)],F325140B-90E3-42d7-8F27-F1E68E1BD92E就是写入注册表的CLSID,UstcOriWebLabActivex.UstcOriWebLab为键名。
实现IObjectSafety接口,把ActiveX控件标记为安全的。
ActiveX危险,那么为什么QQ以及MediaPlayer等都是用ActiveX的方式创建的,却没有问题?原来,这是因为这些ActiveX组件都声明自己是脚本安全的,而IE的中级安全设置上,是允许脚本安全的ActiveX创建,并且不予警告的。
IE怎么知道一个插件是脚本安全的?它是通过以下两个办法。一是查询ActiveX组件是否实现了IObjectSafety接口,并且返回脚本安全;二是查询ActiveX组件是否在注册表的ComponentCategoryManager里表明自己实现了CATID_SafeForInitializing和CATID_SafeForScripting。(参考
那么我们就通过实现IObjectSafety接口
建一个接口文件IObjectSafety.cs,内容如下:
usingSystem; usingSystem.Collections.Generic; usingSystem.Text; usingSystem.Runtime.InteropServices; namespaceUstcOriWebLabActivex { [ComImport,GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")] [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] publicinterfaceIObjectSafety { [PreserveSig] intGetInterfaceSafetyOptions(refGuidriid,[MarshalAs(UnmanagedType.U4)]refintpdwSupportedOptions,[MarshalAs(UnmanagedType.U4)]refintpdwEnabledOptions); [PreserveSig()] intSetInterfaceSafetyOptions(refGuidriid,[MarshalAs(UnmanagedType.U4)]intdwOptionSetMask,[MarshalAs(UnmanagedType.U4)]intdwEnabledOptions); } }
在UstcOriWebLab.cs中实现接口
usingSystem; usingSystem.Collections.Generic; usingSystem.ComponentModel; usingSystem.Drawing; usingSystem.Data; usingSystem.Linq; usingSystem.Text; usingSystem.Windows.Forms; usingSystem.Runtime.InteropServices; namespaceUstcOriWebLabActivex { [Guid("F325140B-90E3-42d7-8F27-F1E68E1BD92E"),ProgId("UstcOriWebLabActivex.UstcOriWebLab"),ComVisible(true)] publicpartialclassUstcOriWebLab:UserControl,IObjectSafety { publicUstcOriWebLab() { InitializeComponent(); } privateconststring_IID_IDispatch="{00020400-0000-0000-C000-000000000046}"; privateconststring_IID_IDispatchEx="{a6ef9860-c720-11d0-9337-00a0c90dcaa9}"; privateconststring_IID_IPersistStorage="{0000010A-0000-0000-C000-000000000046}"; privateconststring_IID_IPersistStream="{00000109-0000-0000-C000-000000000046}"; privateconststring_IID_IPersistPropertyBag="{37D84F60-42CB-11CE-8135-00AA004BB851}"; privateconstintINTERFACESAFE_FOR_UNTRUSTED_CALLER=0x00000001; privateconstintINTERFACESAFE_FOR_UNTRUSTED_DATA=0x00000002; privateconstintS_OK=0; privateconstintE_FAIL=unchecked((int)0x80004005); privateconstintE_NOINTERFACE=unchecked((int)0x80004002); privatebool_fSafeForScripting=true; privatebool_fSafeForInitializing=true; publicintGetInterfaceSafetyOptions(refGuidriid, refintpdwSupportedOptions, refintpdwEnabledOptions) { intRslt=E_FAIL; stringstrGUID=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; } returnRslt; } publicintSetInterfaceSafetyOptions(refGuidriid, intdwOptionSetMask, intdwEnabledOptions) { intRslt=E_FAIL; stringstrGUID=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; } returnRslt; } } }
f、开始制作安装包
新建一个安装项目,在项目上点右键,【添加】->【项目输出】,添加刚才的项目,生成项目,这样我们的activex控件就会和客户端程序一起安装到用户的机器上了。会生成两个文件,一个exe文件和一个msi文件。
安装后,就是自动写入注册表键UstcOriWebLabActivex.UstcOriWebLab。
第三步:客户端通过js检查:
functionopenClient()
{
try
{
debugger;
varwsh=newActiveXObject("UstcOriWebLabActivex.UstcOriWebLab");
window.open("test://hello");
//hello传递的参数,test可以通过正则表达式过滤,客户端能取到hello参数}
catch(e)
{
window.open("/Download.html");
}
}
总结一下思路: 通过写注册表自定义协议,然后通过协议地址打开客户端; 自定义activex控件,并对控件进行安全授权,然后将该控件和客户端程序一起安装,写入注册表; 最后通过js实例化自定义activex控件来检查控件是否安装,从而判断客户端程序是否安装。
相关文章推荐
- 打开本地程序,未安装则提示要求安装的实现攻略
- 打开本地程序,未安装则提示要求安装的实现攻略
- 打开本地程序,未安装则提示要求安装的实现攻略
- 打开本地程序,未安装则提示要求安装的实现攻略
- 打开本地程序,未安装则提示要求安装的实现攻略
- 【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装 【手记】走近科学之为什么明明实现了IEnumerable<T>的类型却不能调用LINQ扩展方法 【手记】手机网页弹出层后屏蔽底层的滑动响应 【手记】ASP.NET提示“未能创建类型”处理 【Web】一个非常简单的移动web消息框 【手记】解决EXCEL跑SQL遇“查询无法运行或数据库表无法打开...”
- “Visual Studio .NET 无法创建或打开应用程序。问题很可能是因为本地WEB本地服务器上没有安装所需的组件。请运行Visual Studio .NET安装程序并添加WEB开发组件“的一种解决方案
- 打开项目时提示如下错误:Visual Studio .NET 无法创建应用程序 。问题很可能是因为本地 Web 服务器上没有安装所需的组件
- Visual Studio .NET 无法创建或打开应用程序。问题很可能是因为本地Web服务器上没有安装所需的组件。请运行 Visual Studio .NET 安装程序并添加Web开发组件。
- Visual Studio .NET 无法创建或打开应用程序。问题很可能是因为本地WEB本地服务器上没有安装所需的组件。请运行Visual Studio .NET安装程序并添加WEB开发组件
- “Visual Studio .NET 无法创建或打开应用程序。问题很可能是因为本地WEB本地服务器上没有安装所需的组件。请运行Visual Studio .NET安装程序并添加WEB开发组件“的一种解决方案
- 打开项目时提示如下错误:Visual Studio .NET 无法创建应用程序 。问题很可能是因为本地 Web 服务器上没有安装所需的组件
- ionic 实现 应用内(webview中html页面点击) 和 应用外 (浏览器html页面点击) 打开本地安装应用
- [转载]Visual Studio .NET 无法创建或打开应用程序。问题很可能是因为本地WEB本地服务器上没有安装所需的组件。请运行Visual Studio .NET安装程序并添加WEB开发组件 收藏
- Visual Studio .NET 无法创建或打开应用程序。问题很可能是因为本地Web服务器上没有安装所需的组件。请运行Visual Studio .NET安装程序并
- Visual Studio .NET 无法创建或打开应用程序。问题很可能是因为本地WEB本地服务器上没有安装所需的组件。请运行Visual Studio .NET安装程序并添加WEB开发组件
- 网页打开客户端本机程序,未安装则提示要求安装
- Win7 64Bit下打开自解压包提示这个程序安装可能不正确 解决方案
- windows下打开软件提示 未找到提供程序 该程序可能未正确安装
- 解决卸载或者安装程序失败的问题,提示:错误 1402。无法打开键UNKNOWN\Components\xxx