| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6748 人关注过本帖, 2 人收藏
标题:分享:检查OCX控件是否注册,没注册的可以自动注册。
只看楼主 加入收藏
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:191
帖 子:3147
专家分:8408
注 册:2015-3-25
结帖率:98.98%
收藏(2)
已结贴  问题点数:5 回复次数:9 
分享:检查OCX控件是否注册,没注册的可以自动注册。
整理回复后,目前有3种方法检查是否注册。

cFilePath=LEFT(SYS(16),RAT("\",SYS(16)))
SET DEFA TO (cFilePath)
CLEAR
ole_name="
ole_name2="VisualFoxpro.Application"
ocx_name="G:\ComboTree\ComboTree.ocx"
ocx_name2="G:\ComboTree\ComboTree2.ocx"

? DllRegister(ocx_name, .T.) &&注册,返回0表示成功,-1表示文件不存在
? DllRegister(ocx_name, .F.) &&注销,返回0表示成功,-1表示文件不存在
? DllRegister(ocx_name2, .T.) &&注销,返回0表示成功,-1表示文件不存在

? ole_name,IsOleReg1(ole_name)
? ole_name,IsOleReg2(ole_name)
? ole_name,IsOleReg3(ole_name)
? ole_name2,IsOleReg2(ole_name2)

** 用DllRegisterServer() 或者 DllUnregisterServer() 注册 ActiveX控件 **
***********************************************************************
** lpLibFileName 需要注册的ActiveX控件名称,包含路径   **
** isReg         注册或者注销,.T.为注册,.F.为注销    **
** =DllRegister( ocx_name, .T.) &&注册,返回0表示成功,-1表示文件不存在
** =DllRegister( ocx_name, .F.) &&注销,返回0表示成功,-1表示文件不存在
** 来源:出处网上查找
***********************************************************************
Function DllRegister(lpLibFileName,isReg)
IF FILE(lpLibFileName)
   isReg = iif(type("isReg")="U", .T., isReg)
   lpProcName = iif(isReg, "DllRegisterServer", "DllUnregisterServer" )
   Declare INTEGER (lpProcName) in (lpLibFileName)
   return &lpProcName.()
ELSE
   return -1
ENDIF
ENDFUNC

** 用创建对象时通过捕捉异常来判断控件是否已注册 **
** 来源:吹水老斑竹
FUNCTION IsOleReg3(OleClsName)
  LOCAL oApp,oErr
  TRY
    oApp = CREATEOBJECT(OleClsName)
  CATCH TO oErr
  ENDTRY
  RETURN IIF(TYPE("oErr.ErrorNo")="U",.T.,.F.) &&变量不存在,没错误返回 .T.
ENDFUNC

** 用获取类标识符来检测控件是否已注册 **
** 来源:吹水老斑竹
FUNCTION IsOleReg2(OleClsName)
  LOCAL sCLSID
  DECLARE LONG CLSIDFromProgID IN Ole32 STRING@, STRING@
  sCLSID = REPLICATE(0h00, 16)
  RETURN (CLSIDFromProgID(STRCONV(OleClsName + 0h00, 5), @sCLSID) == 0)
ENDFUNC


*本程序也可以检查DLL有没有被注册,以收发邮件的jmail.dll为例
*if IsOleReg('jmail.SMTPMail')   &&参数也可以用jmail.POP3
*   =MessageBox("jmail.dll 已经注册",64,"信息提示")
*else
*   =MessageBox("jmail.dll 没有注册",48,"信息提示")
*endif

** 用检查注册表方法来检测控件是否已注册 **
FUNCTION  IsOleReg1(OleClsName)

DECLARE INTEGER RegOpenKeyEx IN advapi32 INTEGER nKey,STRING @cSubKey,INTEGER nReserved,INTEGER nAccessMask,INTEGER @nResult
DECLARE LONG RegCloseKey IN advapi32 INTEGER nHKey
#DEFINE HKEY_CLASSES_ROOT -2147483648
LOCAL lnHKEY,lnRes,lcName1,lcGUID,guiddesc,OcxFile

*在 HKEY_CLASSES_ROOT\MSComctlLib.TreeCtrl.2中查找控件的名称
lnHKEY=0
lnRes=RegOpenKeyEx(HKEY_CLASSES_ROOT,OleClsName,0,131097,@lnHKey)
IF lnRes<>0
   RETURN .F.
ENDIF
lcName1=GetRegVal(lnHKey,'')
RegCloseKey(lnHKey)
IF ISNULL(lcName1)
   RETURN .F.
ENDIF

*在HKEY_CLASSES_ROOT\MSComctlLib.TreeCtrl.2\CLSID中查找控件的类标识符 GUID
lnRes=RegOpenKeyEx(HKEY_CLASSES_ROOT,OleClsName+'\CLSID',0,131097,@lnHKey)
IF lnRes<>0
   RETURN .F.
ENDIF
lcGUID=GetRegVal(lnHKey,'')
RegCloseKey(lnHKey)
IF ISNULL(lcGUID)
   RETURN .F.
ENDIF

*在 HKEY_CLASSES_ROOT\CLSID\… 中查找控件的类标识符 GUID 的备注
lnRes=RegOpenKeyEx(HKEY_CLASSES_ROOT,'CLSID\'+lcGUID,0,131097,@lnHKey)
IF lnRes<>0
   RETURN .F.
ENDIF
guiddesc=GetRegVal(lnHKey,'')
RegCloseKey(lnHKey)
IF ISNULL(guiddesc)
   RETURN .F.
ENDIF

*在 HKEY_CLASSES_ROOT\CLSID\…\InprocServer32 中查找控件的文件名(含路径)
lnRes=RegOpenKeyEx(HKEY_CLASSES_ROOT,'CLSID\'+lcGUID+'\InprocServer32',0,131097,@lnHKey)
IF lnRes<>0
   RETURN .F.
ENDIF
OcxFile=GetRegVal(lnHKey,'')
RegCloseKey(lnHKey)
IF ISNULL(OcxFile)
   RETURN .F.
ENDIF

IF FILE((OcxFile))
    RETURN .T.
ELSE
    RETURN .F.
ENDIF

ENDFUNC

PROCEDURE GetRegVal(nHKey,cProperty)
LOCAL Result,lcValue,lnValLen,lnType

DECLARE INTEGER RegQueryValueEx IN advapi32 INTEGER nKey,STRING cValueName,INTEGER nReserved,INTEGER @nType,STRING @cBuffer,INTEGER @nBufferSize
IF ISNULL(nHKey)
    RETURN .NULL.
ENDIF
lnType=1
lcValue=space(255)
lnValLen=255
result=RegQueryValueEx(nHKey,@cProperty,0,@lnType,@lcValue,@lnValLen)
IF result=0 and lcValue<>CHR(0)
   lcValue=Left(lcValue,lnValLen-1)
   RETURN lcValue
ELSE
   RETURN .NULL.
ENDIF
ENDPROC

[此贴子已经被作者于2016-3-22 11:53编辑过]

收到的鲜花
  • hu9jj2016-03-21 20:03 送鲜花  50朵   附言:好文章
2016-03-21 17:24
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 
没有测试,先赞一个!

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2016-03-21 20:02
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:5 
多谢分享
调用 DllRegisterServer() 注册,在Win7或更高版本要注意权限问题,要提权执行(以管理员身份运行)。
也可用获取类标识符来检测控件是否已注册,如:
程序代码:
? IsOleReg("VisualFoxpro.Application")

FUNCTION IsOleReg(OleClsName)
    LOCAL sCLSID
    DECLARE LONG CLSIDFromProgID IN Ole32 STRING@, STRING@
    sCLSID = REPLICATE(0h00, 16)
    RETURN (CLSIDFromProgID(STRCONV(OleClsName + 0h00, 5), @sCLSID) == 0)
ENDFUNC


也有用创建对象时通过捕捉异常来判断控件是否已注册。
2016-03-21 21:05
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:191
帖 子:3147
专家分:8408
注 册:2015-3-25
收藏
得分:0 
以下是引用吹水佬在2016-3-21 21:05:34的发言:

多谢分享
调用 DllRegisterServer() 注册,在Win7或更高版本要注意权限问题,要提权执行(以管理员身份运行)。
也可用获取类标识符来检测控件是否已注册,如:
 
? IsOleReg("VisualFoxpro.Application")
 
FUNCTION IsOleReg(OleClsName)
    LOCAL sCLSID
    DECLARE LONG CLSIDFromProgID IN Ole32 STRING@, STRING@
    sCLSID = REPLICATE(0h00, 16)
    RETURN (CLSIDFromProgID(STRCONV(OleClsName + 0h00, 5), @sCLSID) == 0)
ENDFUNC
 
 
也有用创建对象时通过捕捉异常来判断控件是否已注册。
吹版,怎么完善?估计这个很多人用的到
2016-03-21 21:48
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
以下是引用mywisdom88在2016-3-21 21:48:35的发言:

吹版,怎么完善?估计这个很多人用的到

主要是注册时的权限问题,一般做法是将注册模块单独编译成一个EXE文件(myRegsvr.exe),程序中用“以管理员身份”运行外部EXE方式调用myRegsvr.exe,并将要注册的控件文件名作为myRegsvr.exe的命令行参数。

oApp = CREATEOBJECT("Shell.Application")
oApp.ShellExecute("myRegsvr.exe", 控件文件名, "", "runas", 1)

或用 API ShellExecuteEx(pExecInfo)
参数pExecInfo为SHELLEXECUTEINFO结构体地址,其中的lpVerb成员为"runas"。




[此贴子已经被作者于2016-3-22 07:09编辑过]

2016-03-21 22:41
baichuan
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:37
帖 子:953
专家分:589
注 册:2006-3-13
收藏
得分:0 
ocx_name="G:\ComboTree\ComboTree.ocx"


这个是否合理?

2016-03-22 08:26
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:191
帖 子:3147
专家分:8408
注 册:2015-3-25
收藏
得分:0 
以下是引用baichuan在2016-3-22 08:26:13的发言:

ocx_name="G:\ComboTree\ComboTree.ocx"


这个是否合理?

这个是测试数据,是通过的?
2016-03-22 08:49
不懂才问
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:大草原
等 级:贵宾
威 望:29
帖 子:1503
专家分:6593
注 册:2010-7-5
收藏
得分:0 
学习一下

报告老师,我低头不是因为我在装低调,是你问的问题,我真的不会答,,,
2016-03-22 08:52
baichuan
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:37
帖 子:953
专家分:589
注 册:2006-3-13
收藏
得分:0 
以下是引用mywisdom88在2016-3-22 08:49:15的发言:


这个是测试数据,是通过的?


我是说使用绝对地址,是不是好?

2016-03-22 10:13
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:191
帖 子:3147
专家分:8408
注 册:2015-3-25
收藏
得分:0 
回复 9楼 baichuan
这个地址,是你要注册的OCX所在的地址。
使用绝对地址来测试,是能正确注册的。
2016-03-22 10:46
快速回复:分享:检查OCX控件是否注册,没注册的可以自动注册。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023712 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved