ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 6304|回复: 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\
Regsvr32  %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目录下各有一个Regsvr32.exe 文件,这两个Regsvr32.exe分别是64位和32位的程序。没错,system32目录下的Regsvr32.exe是64位的,syswow64下的Regsvr32.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目录下的时候,运行 Regsvr32  %windir%\system32\compdll.dll,会默认调用64位的Regsvr32.exe,因此本指令实际操作是要注册system32目录下的compdll.dll。因为compdll.dll是32位的,放在system32目录下注册,会注册失败,提示找不到模块(应该是操作系统设定的,不允许32位dll在system32目录下进行注册)
3 如果将dll放在非system32目录下,比如放在c:\或者 %windir%或者syswow64或者其他任何目录下,注册会成功。
cd /d %~dp0  
copy compdll.dll %windir%\
Regsvr32  %windir%\compdll.dll
注册成功
4 如果将dll放在syswow64目录下,同时将当前目录调整到syswow64目录下,运行regsvr32程序,这时实际上运行的是32位的regsvr32程序,这时运行以下两个指令都能成功:
cd /d %~dp0  
copy compdll.dll %windir%\syswow64
Regsvr32  %windir%\syswow64\compdll.dll
或者:
cd /d %~dp0  
copy compdll.dll %windir%\syswow64
Regsvr32    %windir%\system32\compdll.dll
都能注册成功。
原因如缘生梦所论述的,这时的regsvr32是32位的程序,注册system32会自动重定向到syswow64目录,因此以上两段代码实际上都是注册的syswow64目录下的dll

总的来说,就是32位的dll不能放在system32下注册。32位和64位的regsvr32都可注册不放在system32目录下的dll。32位和64位的regsvr32的区别就是前者能实现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 "regsvr32 /s " & Environ("SystemRoot") & "\system32\compdll.dll"
End Sub
卸载:
Sub Main()
   Shell "regsvr32 /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, 2024-11-21 21:20 , Processed in 0.038020 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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