当我交互式closuresExcel时,Lisp OLE Excel进程不会被终止

我正在编写一个用Lisp编写的应用程序。 我正在使用Franz OLE开始这个过程。 它打开excel罚款,但是当我交互closuresexcel,过程还在那里。 我不知道如何在交互式closuresexcel窗口时终止进程。 任何build议?

谢谢

当您通过自动化启动Excel时,只要它被引用为1 ,就会保持活动状态。 以交互方式closures它不一定会退出应用程序,在这种情况下,因为您的ole:remote-autotool for Excel尚未发布。

让Excel退出的一种方法是摆脱autotool包装,例如,如果你有一个存储在一个variables或对象的插槽中,将其值设置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接口中 ,创build一个IUnknown客户端封装程序会注册一个终止 ,当它被垃圾收集时释放底层的接口指针。

一个自动工具是另一个包装器,它包含一个IDispatch客户端包装器(它inheritance自IUnknown ,就像所有的COM接口一样),就像在脚本自动化中被称为后期绑定的脚本语言一样,简化了它的使用。 当你停止引用自动工具时,潜在的IDispatch / IUnknown客户端包装可能被垃圾回收,从而被释放。

但是,Excel可能不会以这种方式立即退出,除非您期待或迫使垃圾收集发生2 。 如果您希望Excel无需交互就立即Quit ,则应Quit DisplayAlerts设置为false的Excel,然后ole:release您的自动工具对象(注意:我没有对其进行彻底testing):

 (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 ,因为它被logging在ole:release (ole:IUnknown-Client)

还有一个使用ole:release-process-client-interfaces的暴力方式,但是你应该确保你不会访问到目前为止在当前lisp进程(线程)中创build的任何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.只要对任何已注册的工厂执行了locking或者保存了由excel.exe创build的任何对象的引用,它就应该继续运行。 这对于进程外服务器来说是正常的。

2.如果您的自动工具实例已经终结,那么它的生成需要被垃圾收集,通常可以通过全局GC实现,最终完成并释放。

3.在Common Lisp中,你可以改变一个对象的类 。