使用批处理来注册OCX文件的若干问题
2015-05-19 09:26
295 查看
把每次遇到并解决了的问题记录下来,形成文档,这便是一种财富。--沉森心
问题描述:
客户投诉说,安装完软件包后,打开某个业务模块,点击打印预览按钮时,没反应,不能打印。
原因描述:
对于打印这个功能,PC客户端是通过调用OCX控件来进行打印的,我们采用了批处理脚本的方式来进行OCX文件的注册和反注册。每次程序第一次被安装启动时,系统会自动调用执行一个批处理脚本,从而完成任务。但由于Windows系统环境的复杂,导致了批处理文件执行偶尔会失败。现根据不同的系统环境来分析一下:
批处理脚本:
备注:win7系统分为32位和64位,应该根据它的处理器类型来判断,而regsvr32.exe分别位于system32和syswow64文件夹中。
VC代码:
采用ShellExecute函数来执行该批处理脚本Print.bat。
运行结果:
Win7:
对于没有管理员权限的用户,直接双击bat文件,会提示复制文件失败,拒绝访问。
XP:
弹出Dos命令行窗口,复制并注册文件成功,但是对某些XP系统偶尔会失败。
解决办法1:
既然需要管理员权限,那我能否在程序中使用管理员权限运行这个bat文件呢?修改如下:
VC代码:
结果:复制并注册文件成功,但是对于某些XP系统,偶尔会失败。
解决办法2:
查看bat脚本,发现每次都要把OCX和相关的依赖动态库拷贝到系统目录下的system32\sysWow64文件夹中,然后再进行注册,太麻烦了,能否直接在安装目录下调用批处理文件进行注册呢?修改如下:
结果:复制并注册文件成功,但是对于某些特殊情况,还是偶尔会失败。
解决办法3:
为什么一定要用批处理来执行呢?这对于XP系统来说,每次运行这个文件都要弹出一个dos命令行窗口,用户体验不好。所以,干脆把批处理去掉,直接用ShellExecute函数调用regsvr32.exe来进行ocx文件的注册,写死在客户端代码里。代码如下:
结果:复制并注册文件成功,目前暂时没有遇到失败案例。
注意:ocx文件路径不能包含空格,应该把文件路径用双引号括起来,这样路径中就可以包含空格了。
ps:
判断OCX文件是否已经注册?
要判断是否已经注册,只要判断注册表是否存在该OCX键值就行了。但是我们客户端存在很多版本,又可以同时运行,故不能判断注册表,于是选择了判断OCX某个接口的返回值的办法。但是无论怎样测试,只要没注册的,接口就不往下跑或者返回值异常。正当搔头弄脑之际,我们发现调试程序时,只要打印OCX文件注册不成功的话,程序是不能进入到打印类CPrintDlg的OnInitDialog函数里的。所以我们马上改变了思路和角度,在OnInitDialog函数里设置了一个返回标识,只要打印窗口不返回成功标识,则说明OCX文件注册不成功,搞定。
通过这个例子,我明白了,有时候转换一个角度来思考问题,反而会找到更多的思路和方法。打破思维定式,你我都能做到。
问题描述:
客户投诉说,安装完软件包后,打开某个业务模块,点击打印预览按钮时,没反应,不能打印。
原因描述:
对于打印这个功能,PC客户端是通过调用OCX控件来进行打印的,我们采用了批处理脚本的方式来进行OCX文件的注册和反注册。每次程序第一次被安装启动时,系统会自动调用执行一个批处理脚本,从而完成任务。但由于Windows系统环境的复杂,导致了批处理文件执行偶尔会失败。现根据不同的系统环境来分析一下:
批处理脚本:
@echo off if "%processor_architecture%"=="x86" goto REG32 if "%processor_architecture%"=="AMD64" goto REG64 :REG32 if not exist %systemroot%\system32\Print.OCX COPY MSCHRT20.OCX %systemroot%\system32 %systemroot%\system32\regsvr32.exe -u -s %systemroot%\system32\Print.ocx %systemroot%\system32\regsvr32.exe -s %systemroot%\system32\Print.ocx ...... goto exit :REG64 if not exist %systemroot%\syswow64\Print.OCX COPY MSCHRT20.OCX %systemroot%\syswow64 %systemroot%\syswow64\regsvr32.exe -u -s %systemroot%\system32\Print.ocx %systemroot%\syswow64\regsvr32.exe -s %systemroot%\system32\Print.ocx ...... goto exit :exit exit
备注:win7系统分为32位和64位,应该根据它的处理器类型来判断,而regsvr32.exe分别位于system32和syswow64文件夹中。
VC代码:
采用ShellExecute函数来执行该批处理脚本Print.bat。
ShellExecute(NULL,_T(“open”),strBatFilePath,NULL,SW_SHOW);
运行结果:
Win7:
对于没有管理员权限的用户,直接双击bat文件,会提示复制文件失败,拒绝访问。
XP:
弹出Dos命令行窗口,复制并注册文件成功,但是对某些XP系统偶尔会失败。
解决办法1:
既然需要管理员权限,那我能否在程序中使用管理员权限运行这个bat文件呢?修改如下:
VC代码:
SHELLEXECUTEINFO sei={sizeof(SHELLEXECUTEINFO)}; sei.lpVerb = TEXT("runas"); sei.lpFile = strBatFilePath; sei.nShow = SW_HIDE; sei.lpDirectory=NULL; sei.lpParameters=_T(“”); if (!ShellExecuteEx(&sei)) { DWORD dwStatus = GetLastError(); if (dwStatus == ERROR_CANCELLED) { printf("没有以管理员权限运行"); } else if(dwStatus == ERROR_FILE_NOT_FOUND) { printf("没有找到该文件"); } }
结果:复制并注册文件成功,但是对于某些XP系统,偶尔会失败。
解决办法2:
查看bat脚本,发现每次都要把OCX和相关的依赖动态库拷贝到系统目录下的system32\sysWow64文件夹中,然后再进行注册,太麻烦了,能否直接在安装目录下调用批处理文件进行注册呢?修改如下:
@echo off cd /d %~dp0 if "%processor_architecture%"=="x86" goto REG32 if "%processor_architecture%"=="AMD64" goto REG64 :REG32 %systemroot%\system32\regsvr32.exe -u -s %cd%\Print.ocx %systemroot%\system32\regsvr32.exe -s %cd%\Print.ocx goto exit :REG64 %systemroot%\syswow64\regsvr32.exe -u -s %cd%\Print.ocx %systemroot%\syswow64\regsvr32.exe -s %cd%\Print.ocx goto exit :exit exit
结果:复制并注册文件成功,但是对于某些特殊情况,还是偶尔会失败。
解决办法3:
为什么一定要用批处理来执行呢?这对于XP系统来说,每次运行这个文件都要弹出一个dos命令行窗口,用户体验不好。所以,干脆把批处理去掉,直接用ShellExecute函数调用regsvr32.exe来进行ocx文件的注册,写死在客户端代码里。代码如下:
ShellExecute(NULL,NULL,_T(“regsvr32.exe”),strOCXFilePath,NULL,SW_HIDE);
结果:复制并注册文件成功,目前暂时没有遇到失败案例。
注意:ocx文件路径不能包含空格,应该把文件路径用双引号括起来,这样路径中就可以包含空格了。
strOCXFilePath.Format(_T("/s \"%s\""),strOCXFilePath); // /s参数会隐藏cmd注册控件是否成功的对话框 ShellExecute(NULL,NULL,_T(“regsvr32.exe”),strOCXFilePath,NULL,SW_HIDE);
ps:
判断OCX文件是否已经注册?
要判断是否已经注册,只要判断注册表是否存在该OCX键值就行了。但是我们客户端存在很多版本,又可以同时运行,故不能判断注册表,于是选择了判断OCX某个接口的返回值的办法。但是无论怎样测试,只要没注册的,接口就不往下跑或者返回值异常。正当搔头弄脑之际,我们发现调试程序时,只要打印OCX文件注册不成功的话,程序是不能进入到打印类CPrintDlg的OnInitDialog函数里的。所以我们马上改变了思路和角度,在OnInitDialog函数里设置了一个返回标识,只要打印窗口不返回成功标识,则说明OCX文件注册不成功,搞定。
通过这个例子,我明白了,有时候转换一个角度来思考问题,反而会找到更多的思路和方法。打破思维定式,你我都能做到。
相关文章推荐
- 批处理注册DLL文件或OCX文件让Windows找回“丢失”的DLL,OCX文件
- 现在介绍一种使用资源文件,将dll、ocx打包进exe,点击直接注册的例子:
- cocos2d-x 3.0学习一:cocostudio导出UI界面文件的加载及使用的若干问题
- 使用批处理文件完成注册信息
- Win7如何手动注册DLL文件以解决程序不能使用的问题
- .OCX、.dll文件注册命令Regsvr32的使用
- 关于使用Entity Framework时遇到的问题 未找到具有固定名称“System.Data.SqlClient”的 ADO.NET 提供程序的实体框架提供程序。请确保在应用程序配置文件的“entityFramework”节中注册了该提供程序
- mysql5.7服务注册(使用命令注册服务):解决my.ini配置文件不存在的问题
- vb控件相关ocx文件注册问题
- 使用FFMPEG导出码流到AVI/MP4文件的若干问题
- 用FileMenu Tools玩转系统右键菜单 软件还有其他的内置命令,这里由于篇幅原因不能全部介绍了,比如注册DLL、反注册命令,当注册表中的某个dll或ocx文件受损时,可以使用该命令进行恢
- OCX视频插件问题记录-1 error MSB8011: 未能注册输出。请尝试启用“逐用户重定向”,或者使用提升的权限从命令提示符处注册该组件
- 使用Myeclipse自带的Tomcat出现上传文件无法显示或者找不到的问题
- linux系统中的定时器crontab的使用攻略、常见错误问题和运行.jar文件的具体实例。
- 使用批处理根据项目工程文件生成Nuget包并发布(支持.NET Core)
- Python下使用help(math)提示:'more'不是内部或外部命令,也不是可运行的程序或批处理文件
- 使用shttpd接受上传文件的问题
- 使用eclipse创建多文件java工程出现找不到或无法加载主类问题解决
- 【解决问题】windows下配置Boost提示'cl' 不是内部或外部命令,也不是可运行的程序 或批处理文件
- 在命令行键入“cl”时出现不是内部或外部命令,也不是可运行的程序或批处理文件的问题。