ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

EH搜索     
EH云课堂-专业的职场技能充电站 Excel转在线管理系统,怎么做看这里 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
Excel不给力? 何不试试FoxTable! Excel 2016函数公式学习大典 挑战你的Excel知识,一起测验下 免费下载Excel行业应用视频
300集Office 2010微视频教程 Tableau-数据可视化工具 精品推荐-800套精选PPT模板,点击获取 ExcelHome出品 - VBA代码宝免费下载
你的Excel 2010实战技巧学习锦囊 欲罢不能, 过目难忘的 Office 新界面 Excel VBA经典代码实践指南
查看: 3344|回复: 3

[分享] 注册dll总是失败的原因探讨

[复制链接]

TA的精华主题

TA的得分主题

发表于 2015-4-21 17:47 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:封装
       经常编写一些vba工具,最近在实践采用dll封装vba代码,然后excel去调用dll的方法,不可避免需要注册编写的dll,经常遇到注册失败的情况,现将总结的经验分享给大家。
       vba代码写在excel2007中,dll使用vb6.0开发,操作系统是win7 64位。
       因为在win7下,注册dll需要管理员权限,因此在vba中用shell方法注册dll基本不可行了。最早想到的注册方法是制作批处理文件,用管理员权限运行,但是经历了多次失败。
       本文就是总结多次失败的经验教训,希望能为其他朋友节省一些弯路。
       如果您的操作系统是32位的,大概不会遇到我的问题,因此可不用看本文。

一、注册失败的情况:

最初编写的注册bat文件:
@ ECHO OFF
cd /d %~dp0
copy compdll.dll %windir%\system32\
Regsv*****  %windir%\system32\compdll.dll
注册失败,提示找不到模块。但是在system32目录下compdll.dll文件是存在的。

二、失败原因探讨:

原文链接:http://www.cnblogs.com/hbccdf/p/dllchecktoolandsyswow64.html?utm_source=tuicool
缘生梦  在博文中很详细的讲解了system32目录与syswow64目录的区别,总结如下(win7系统):
1  64位程序访问system32文件夹中的文件,可直接访问(包括拷贝,读取,删除)
2  32位程序访问system32文件夹,会被自动重新定向到syswow64目录(包括拷贝,读取,删除)
3  如:一个32位的软件执行 copy 1.txt  %windir%\system32\    最后1.txt会出现在%windir%\syswow64\  目录
4   system32和syswow64目录下各有一个Regsv*****.exe 文件,这两个Regsv*****.exe分别是64位和32位的程序。没错,system32目录下的Regsv*****.exe是64位的,syswow64下的Regsv*****.exe是32位的。
5   缘生梦的博文中阐述的很详细了,win7的system32文件夹就是设计来放64位程序或者com组件的,syswow64才是系统设计用来放32程序的。

回到实践中的bat文件,注册32位dll失败的原因总结:
1  win7下的cmd程序实际上是64位的程序,因此copy compdll.dll %windir%\system32\  是真正的将dll拷贝到system32文件夹
2  cmd的当前目录不是在syswow64目录下的时候,运行 Regsv*****  %windir%\system32\compdll.dll,会默认调用64位的Regsv*****.exe,因此本指令实际操作是要注册system32目录下的compdll.dll。因为compdll.dll是32位的,放在system32目录下注册,会注册失败,提示找不到模块(应该是操作系统设定的,不允许32位dll在system32目录下进行注册)
3 如果将dll放在非system32目录下,比如放在c:\或者 %windir%或者syswow64或者其他任何目录下,注册会成功。
cd /d %~dp0  
copy compdll.dll %windir%\
Regsv*****  %windir%\compdll.dll
注册成功
4 如果将dll放在syswow64目录下,同时将当前目录调整到syswow64目录下,运行regsv*****程序,这时实际上运行的是32位的regsv*****程序,这时运行以下两个指令都能成功:
cd /d %~dp0  
copy compdll.dll %windir%\syswow64
Regsv*****  %windir%\syswow64\compdll.dll
或者:
cd /d %~dp0  
copy compdll.dll %windir%\syswow64
Regsv*****    %windir%\system32\compdll.dll
都能注册成功。
原因如缘生梦所论述的,这时的regsv*****是32位的程序,注册system32会自动重定向到syswow64目录,因此以上两段代码实际上都是注册的syswow64目录下的dll

总的来说,就是32位的dll不能放在system32下注册。32位和64位的regsv*****都可注册不放在system32目录下的dll。32位和64位的regsv*****的区别就是前者能实现system32重新定向到syswow64,后者不能。
以上提到的bat需要使用管理员权限运行方可正确注册。
因为cmd是64位的,dll是32位的,因此用bat注册就经常会出错。

三、制作安装程序是更好的选择:

最好的方法还是用vb写一个32位的注册程序,如果在32位系统安装就能在system32中注册dll,在64位系统中安装就能自动copy和注册在syswow64目录下。而注册程序中的代码只需要写system32,因此这样的方法比使用bat注册的通用性更好。

制作安装和卸载程序时,vb的工程描述中,写入 setup ,就能编译为带管理员权限的exe。

安装:
Sub Main()
   str1 = Replace(App.Path & "\compdll.dll", "\\", "\")     'replace为了防止app.path是根目录的时候出现"\\"
   str2 = Environ("SystemRoot") & "\system32\compdll.dll"
   FileCopy str1, str2
   Shell "regsv***** /s " & Environ("SystemRoot") & "\system32\compdll.dll"
End Sub
卸载:
Sub Main()
   Shell "regsv***** /u /s " & Environ("SystemRoot") & "\system32\compdll.dll"
End Sub

四、最后请教大家一个问题:
如果我将dll放在了system32目录,并且注册了。随后我将system32中的dll文件剪切到了调用该dll的程序的目录下,我测试的结果应该是不能调用了。有没有什么方法,能够让一个程序,在原注册位置找不到dll的情况下,自动的到本程序目录下找到这个dll呢?

TA的精华主题

TA的得分主题

发表于 2015-4-21 19:57 | 显示全部楼层
有api可以设置dll目录,你看一下知识树
或者用chdir切换程序目录为当前目录也可以试试

TA的精华主题

TA的得分主题

发表于 2017-5-4 20:59 | 显示全部楼层
这个都 是有要管理员权限才能运行,如果封装好DLL,发给别人没有管理员权限,那要怎么注册,还有VBA代码,注册时也要以管理员权限打开EXCEL后才能注册,能不能直接打开EXCEL运行了代码就可以注册,

TA的精华主题

TA的得分主题

发表于 2018-6-19 20:28 | 显示全部楼层
研究中。。。。。封后如何调用呢?
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关注官方微信,高效办公专列,每天发车

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2019-9-20 12:03 , Processed in 0.062449 second(s), 13 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2020 Wooffice Inc.

   

沪公网安备 31011702000001号 沪ICP备11019229号

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:徐怀玉律师 李志群律师

快速回复 返回顶部 返回列表