一、问题引入
有几年没有用过VS编程了,最近对Winlicense感兴趣,就试着运行其提供的WinLicenseSDK\ExamplesSDK\Get HardwareID\Proyecto1.sln,遇到DLL引用问题,把解决的过程记录在本文。
我的编译环境是:Win7,64位系统,Visual studio enterprise 2015,.net framework 4.8
WinLicenseSDK目录如下:
其下面Lib目录如下:
要打开运行的项目如下图:
双击打开Proyecto1.sln解决方案,内部含VB.net项目Proyecto1.vbproj,如下图:
最初创建项目时采用的.net framework版本如下:
该项目会引用WinlicenseSDK.dll,这是非.net开发的dll文件,即非托管代码。
二、DLL相关知识和工具
1、非托管DLL引用
.net项目引用非托管dll有两个方法:
(1)采用Declare,参考演练:调用 Windows API - Visual Basic | Microsoft Docs
(2)参考使用非托管 DLL 函数 - .NET Framework | Microsoft Docs
创建用于容纳 DLL 函数的类 - .NET Framework | Microsoft Docs
本项目中采用的是第2个方法,即使用DLLImport引入并封装为一个引用类,如下图:
2、Windows搜索DLL路径
动态链接库搜索顺序 - Win32 apps | Microsoft Docs
以下因素会影响系统是否搜索 DLL:
- 如果内存中已加载同一模块名称的 DLL,则系统只会在解析到加载的 DLL 之前检查重定向和清单,而不管该 DLL 位于哪个目录中。 系统不搜索 DLL。
- 如果 DLL 位于运行应用程序的 Windows 版本的已知 DLL 列表中,则系统将使用已知 DLL (的副本和已知 DLL 的依赖 DLL(如果有) ),而不是搜索 DLL。 有关当前系统上的已知 DLL 的列表,请参阅以下注册表项 :HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs。
- 如果 DLL 具有依赖项,则系统会搜索依赖 DLL,就像它们仅用模块名称加载一样。 即使通过指定完整路径加载了第一个 DLL,也是如此。
桌面应用程序缺省的DLL搜索路径为:
- 从其中加载应用程序的目录。
- 系统目录。 使用 GetSystemDirectory 函数获取此目录的路径。
- 16 位系统目录。 没有函数可获取此目录的路径,但会进行搜索。
- Windows 目录。 使用 GetWindowsDirectory 函数获取此目录的路径。
- 当前目录。
- PATH 环境变量中列出的目录。
注:“加载应用程序的目录”和“当前目录”的区别
举例说明:
3、查看dll内部函数工具
Visual studio.net安装目录下面的dumpbin.exe和link.exe命令,我机器上安装的是Visual studio.net 2015版,安装目录为C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin
dll函数信息导入文件1.txt,打开内容如下:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin>link /dump /exports C:\V
MWareMachines\share\WinLicenseDemo32_64_3.0.4.0\WinlicenseSDK.dll > 1.txt
和上面的命令效果一样。
为方便今后的使用,为了方便大家,我把相关命令最小集合整理成文件包dlldump,和4、5中提到的工具打包在一起,下载地址: Windows平台DLL工具集1.0-WindowsServer文档类资源-CSDN下载
4、查看系统已注册dll工具
RegDllView1.6 下载地址:Windows平台DLL工具集1.0-WindowsServer文档类资源-CSDN下载
5、查看dll依赖工具
dependence walker 2.2.6000 下载地址:Windows平台DLL工具集1.0-WindowsServer文档类资源-CSDN下载
二、操作步骤及问题描述
1、直接编译
2、 Debug配置下启动运行
3、点击任一按键
遇到问题如下:
问题1-报告“试图加载格式不正确的程序”
问题1-解决:
在网上找到参考:试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B) - sundajade - 博客园
目前的编译环境是64位系统,而要引用的WinlicenseSDK.dll是32位系统上开发的,需要将编译配置设置为x86即32位模式,如下图:
再次启动调试:
报告问题2-无法加载“WinlicenseSDK.dll” :找不到指定的模块
问题2尝试解决步骤:
尝试在项目里添加显式引用,如下图:
报告问题3-未能添加...的引用。请确保此文件可访问并且是一个有效的程序集或COM组件。
对于问题2,网上也有说是需要用regsvr32.exe对要引用的dll注册一下,我尝试了没有解决我这个项目的问题。
用法: regsvr32 [/u] [/s] [/n] [/i[:cmdline]] dllname
操作和结果如下:
但结果中提示检查“相关的DLL文件是否有问题”
从 Dependency Walker (depends.exe) Home Page 下载DLL检查工具depends.exe对WinlicenseSDK.dll进行检查,如下图:
上图显示我的电脑上缺少一些Winlicense.dll会引用到的dll组件。到 https://www.jb51.net/dll/ 下载然后拷贝至项目可执行程序目录下。再次运行,结果如下:
把WinlicenseSDK.ini也拷贝到可执行程序目录,再次运行则成功,如下图:
把depends.exe报告的所缺少的那7个dll从可执行程序所在目录删除,重启发现,依然能成功运行。说明WinlicenseSDK.dll并没有真正用到那7个dll。所以真正解决问题起作用的就是修改程序生成运行平台为X86、把WinlicenseSDK.dll和配置文件WinlicenseSDK.ini拷贝到可执行程序目录。
三、结论
1、对于本文所涉及WinlicenseSDK项目除了把配置模式运行平台设置为x86外不需要做其他修改,把WinlicenseSDK.dll和配置文件WinlicenseSDK.ini拷贝到可执行程序目录,便能成功运行。程序开发方说明文档没有说明WinlicenseSDK.dll和配置文件WinlicenseSDK.ini的关系,导致误解其为dll相关生成文件,其实际是dll的配置文件,属于应用程序数据文件。
2、我的电脑Microsoft.net framework版本或某些地方存在问题,导致VS 2015项目不能成功添加dll引用,导致register32注册报错,结果导致关于dll错误处理一顿操作猛如虎,回头一看二百五。
3、问题2、问题3报错的原因以及如何彻底解决,我没有弄明白。
解决这个问题花了一天的时间,网上dll引用报错相关的帖子很多,大多管中窥豹。我的这个demo项目并非真正的dll问题,如果遇到真正的dll问题,需要排查的方面比较多。问题解决后在网上翻到一篇比较靠谱的,推荐给大家,作为本文结束。文章来源:https://www.toymoban.com/news/detail-440540.html
无法加载 DLL“xxxx.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。_汪锦鹏的博客-CSDN博客_dll找不到指定的模块
文章来源地址https://www.toymoban.com/news/detail-440540.html
到了这里,关于解决WinlicenseSDK二次开发Visual Studio项目DLL引用问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!