E语言中如何释放DLL
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了E语言中如何释放DLL相关的知识,希望对你有一定的参考价值。
用易言语 怎么让我自己做的EXE运行后释放出一个能隐藏在指定位置的DLL,
一直在想就是想不出应该怎么弄这个,
就是运行EXE后自动生成一个能隐藏在指定目录下的DLL文件(这个DLL必需是自己的DLL)
请高手指点一下
.版本 2
.局部变量 文件号, 整数型
.如果真 (文件是否存在 (“C:\AA.DLL”) = 假)
文件号 = 打开文件 (“AA.DLL”, 4, 1)
写出字节集 (文件号, #aa)
关闭文件 (文件号)
然后用一下置文件属性即可 参考技术A 用心释放DLL 参考技术B 调用格式: 〈逻辑型〉 写到文件 (文本型 文件名,字节集 欲写入文件的数据,... ) - 系统核心支持库->磁盘操作
英文名称:WriteFile
本命令用作将一个或数个字节集顺序写到指定文件中,文件原有内容被覆盖。成功返回真,失败返回假。本命令为初级命令。命令参数表中最后一个参数可以被重复添加。
参数<1>的名称为“文件名”,类型为“文本型(text)”。
参数<2>的名称为“欲写入文件的数据”,类型为“字节集(bin)”。
调用格式: 〈逻辑型〉 置文件属性 (文本型 欲设置其属性的文件名称,整数型 欲设置为的属性值) - 系统核心支持库->磁盘操作
英文名称:SetAttr
为一个文件设置属性信息。成功返回真,失败返回假。本命令为初级命令。
参数<1>的名称为“欲设置其属性的文件名称”,类型为“文本型(text)”。
参数<2>的名称为“欲设置为的属性值”,类型为“整数型(int)”。参数值可以为以下常量值或其和: 1、#只读文件; 2、#隐藏文件; 4、#系统文件; 32、#存档文件 。通过将这些常量值加起来可以一次设置多个文件属性。
如何从 Excel VBA 释放进程内 COM 服务器对象
【中文标题】如何从 Excel VBA 释放进程内 COM 服务器对象【英文标题】:How to release inprocess COM Server object from Excel VBA 【发布时间】:2011-11-12 02:03:11 【问题描述】:如何强制 Excel (2007) VBA 释放对 COM 服务器对象的引用?
我在 Visual Foxpro 9 SP2 中编写了一个进程内(单实例 DLL)COM 服务器,它是从我的开发机器上的 Excel 2007 VBA 代码实例化的。 Excel 似乎持有对 COM 对象/dll 的引用,即使我将它设置为 = 无。这会阻止我重建 DLL,因为“文件访问被拒绝 TestCOM.dll”消息,直到我退出 Excel,每次我想要进行更改并测试它时都很痛苦。
我将代码简化为一个非常简单的测试设置: VFP9 项目(TestCOM)只有一个 .prg 文件,内容如下
DEFINE CLASS TestClass As Session OLEPUBLIC
ENDDEFINE
VBA代码如下:
Sub Test()
Set objTest = CreateObject("TestCOM.TestClass")
Set objTest = Nothing
End Sub
我尝试在 VBA 项目中删除对 COM 服务器库的引用,但这没有任何区别。 我尝试过使用和不使用 DIMing 对象变量,这没有区别。 我已尝试创建一个新的 VFP DLL 项目,但问题仍然存在。
如果我将 VFP 应用程序/dll 构建为 INPROCESS/DLL 并运行 VBA 代码,我会遇到此问题,但如果我将其构建为 OUTOFPROCESS/EXE 并运行 VBA 代码,我不会遇到此问题。
我在COM Object Cleanup 中发现了一个非常相似的问题,除了我的 COM 服务器是用 Visual Foxpro 9 SP2 编写的,而这与 C# 相关,并且 OP 没有详细解释他们如何解决问题,所以我不知道如何绕过它;如果这是可能的话。
【问题讨论】:
对于阅读此线程的任何其他人,我随后意识到,如果项目是作为进程外 (EXE) COM 服务器构建的,那么如果您没有引用 VBA/Excel 中的类型库。 【参考方案1】:用于从 DLL 中的代码实例化 COM 类的过程是 Excel 调用 COM 库层以使用 ProgID 或 ClassID 查找您的实现。当您有一个 inproc 服务器时,这意味着它会找到您的 DLL 的路径并使用 LoadLibrary 将其加载到您的客户端进程中,然后创建类工厂并调用 DLL 中的方法。所以最终结果是 Excel 在您的 DLL 上调用 LoadLibrary,这会锁定文件,直到 Excel 在句柄上调用 FreeLibrary。
使用 COM 接口您无法控制这一点。您调用 CoCreateInstance() (或从 VBA 中使用 New 或 CreateObject 创建对象,它在下面调用此 Win32 API)。这个实现会处理 LoadLibrary 和其他所有东西,直到你得到一个接口指针来处理。一些应用程序会定期调用 CoFreeUnusedLibraries() 以尝试释放当前未使用的已加载 COM dll。默认类工厂实现维护一个创建的对象计数器,可用于确定 DLL 是否在使用中 - 但这并不总是可靠的,因为 COM 类编写者可能不遵守规则。退出 Excel 显然会释放对文件的锁定。
当您将 COM 类创建为进程外服务器时 - 它存在于单独的可执行文件或 DLL 中,其生命周期的管理方式不同。 Excel 不再锁定 DLL,释放 COM 实例可能会允许宿主进程退出。
您可以将 DLL 转换为用作本地服务器(进程外),方法是安排它由 DllHost 托管。如果您使用 OleView 实用程序并找到您的类 ProgId,那么您可以在代理进程 (dllhost) 中启用托管。自从我这样做以来已经有一段时间了,但是网络上应该有关于使用代理托管的信息。显然,在进程外托管 COM 对象会使一切变慢,并引入各种编组问题的可能性。如果你保持 oleautomation 兼容的接口应该没问题。
【讨论】:
感谢您出色的详细技术回复。所以简而言之,你基本上是在说 COM 接口我受客户端的支配,在这种情况下是 Excel,我没有办法强制释放 DLL?我应该在我的问题中提到,当从 VFP 的另一个副本调用 COM 服务器时不会发生此问题,因此故障似乎与客户端而不是服务器有关。我认为作为一种解决方法,我将在开发期间将此项目构建为进程外服务器 (EXE),然后将其切换到进程内 (DLL) 以进行最终测试和发布。 需要一种额外的成分。 COM 服务器必须从其 DllCanUnloadNow() 入口点返回 S_OK。在 VBA + Foxpro 环境中测试并不简单。【参考方案2】:添加更短的答案 ....
发布DLL
是一个棘手的问题,对于在COM
中使用的Excel
组件的开发人员来说是一个熟悉的问题。
需要满足两个条件
1) 不要使用早期绑定库引用 (Tools->Reference) ,而是使用后期绑定。早期绑定工具参考将持有锁。
2) 调用CoFreeUnusedLibraries
卸载不再有客户端的COM
服务器。
根据您的示例代码,您已经是后期绑定,但请检查您的参考资料。虽然payyhoyts answer 中提到了第 2) 点,但没有给出代码。
这是一个可复制和可粘贴的声明
Private Declare Sub CoFreeUnusedLibraries Lib "ole32.dll" ()
【讨论】:
以上是关于E语言中如何释放DLL的主要内容,如果未能解决你的问题,请参考以下文章
2022-10-29:go语言中的defer能非常方便地处理资源释放问题,rust语言里如何实现defer功能呢?