我正在使用Lisp编写的应用程序。我正在使用Franz OLE来启动该过程。它开得很好,但当我以交互方式关闭excel时,过程仍然存在。当我以交互方式关闭excel窗口时,我不确定如何终止进程。有什么建议吗?
由于
答案 0 :(得分:1)
当您通过自动化启动Excel时,只要引用 1 ,它就会保持活动状态。以交互方式关闭它并不一定会退出应用程序,在这种情况下,因为您的ole:remote-autotool
for Excel尚未发布。
让Excel退出的一种方法是摆脱autotool包装器,例如如果您有一个存储在变量或对象的插槽中,请将其值设置为nil
:
(let ((excel-app (ole:ask-for-autotool "Excel.Application"
ole:CLSCTX_LOCAL_SERVER)))
;; ...
;; Break the reference to all autotool wrappers you no longer need
(setf excel-app nil))
在Allegro CL的OLE Interface中,IUnknown
客户端包装器的创建注册了一个finalization,它在垃圾收集时释放了底层接口指针。
一个autotool是另一个包装器,它包含一个IDispatch
客户端包装器(它继承自IUnknown
,作为所有COM接口),以与脚本语言相同的方式简化其使用为late binding in COM automation。当您停止引用自动工具时,基础IDispatch
/ IUnknown
客户端包装器可能被垃圾收集,因此被释放。
但是,Excel可能不会以这种方式立即退出,除非您期望或强制垃圾收集发生 2 。如果您希望Excel在没有交互的情况下立即退出,则应Quit
Excel将DisplayAlerts
设置为false,然后ole:release
设置自动工具对象(注意:我没有对此进行彻底测试):< / p>
(let ((excel-app (ole:ask-for-autotool "Excel.Application"
ole:CLSCTX_LOCAL_SERVER)))
;; ...
;; Disable prompts asking to save unsaved workbooks
;; They will not be saved
(setf (ole:auto-getf excel-app "DisplayAlerts") nil)
(ole:auto-method excel-app "Quit")
;; Manually release all autotool wrappers you no longer need
(ole:release excel-app))
我们手动释放后,自动工具的计划完成不会失败。它检查底层接口指针包装器是否已被释放,可能是通过检查它的类现在是否为ole::released-IUnknown
3 ,因为它记录在ole:release (ole:IUnknown-Client)
的描述中。
还有一种使用ole:release-process-client-interfaces
的暴力方法,但是你应该确保你不会访问当前在当前lisp进程(线程)中创建的任何OLE对象:
(mp:process-run-function
"Excel worker"
#'(lambda ()
(ole:start-ole)
(unwind-protect
(let ((excel-app (ole:ask-for-autotool "Excel.Application"
ole:CLSCTX_LOCAL_SERVER)))
;; ...
;; Disable prompts asking to save unsaved workbooks
;; They will not be saved
(setf (ole:auto-getf excel-app "DisplayAlerts") nil)
(ole:auto-method excel-app "Quit")
;; Make sure this is the last thing you do, the wrappers
;; created in the current process will become invalid
(ole:release-process-client-interfaces))
;; Given this call, the brute force doesn't make much sense anyway
(ole:stop-ole))))
1。只要保留对任何已注册工厂的锁定或保留对excel.exe创建的任何对象的引用,它就应该继续运行。这对out-of-process servers来说是正常的。
2. 如果您的autotool实例已经使用,那么它的生成需要进行垃圾收集,通常可以通过全局GC实现,最终确定并发布。
3. 在Common Lisp中,你可以change the class一个对象。