当我以交互方式关闭Excel时,Lisp OLE Excel进程不会被杀死

时间:2012-06-25 17:57:14

标签: excel lisp

我正在使用Lisp编写的应用程序。我正在使用Franz OLE来启动该过程。它开得很好,但当我以交互方式关闭excel时,过程仍然存在。当我以交互方式关闭excel窗口时,我不确定如何终止进程。有什么建议吗?

由于

1 个答案:

答案 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一个对象。