2012-06-25 65 views
2

我正在編寫用Lisp編寫的應用程序。我正在使用Franz OLE開始這個過程。它開放excel很好,但是當我交互地關閉excel時,過程仍然存在。我不確定如何在交互式關閉excel窗口時終止進程。任何建議?當我交互式關閉Excel時,Lisp OLE Excel進程不會被終止

感謝

+0

我從來沒有寫過真正的Lisp應用程序,而是一個自動化的Excel實例,不會關閉熟悉的聲音。在.NET中,通常會有一個自動創建的對象不會釋放其COM引用。也許這個問題的一些想法會幫助你:http://stackoverflow.com/questions/1041266/c-sharp-and-excel-automation-ending-the-running-instance? –

回答

1

當您通過自動化啓動Excel,它是維持生命,只要它被引用。以交互方式關閉它並不一定會退出應用程序,在這種情況下,因爲Excel的ole:remote-autotool尚未發佈。

讓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是另一種包裝,其containts的IDispatch客戶包裝(從IUnknown繼承,因爲所有的COM接口),緩解其以同樣的方式作爲腳本語言與所謂的late binding in COM automation。當你停止引用自動工具時,底層的IDispatch/IUnknown客戶端包裝可能被垃圾回收,從而被釋放。

但是,Excel可能不會立即退出,除非您期待或迫使發生垃圾回收。如果您希望Excel立即退出而不相互影響,你應該Quit的Excel與DisplayAlerts設置爲false,然後ole:release您autotool對象(注:我沒有測試過這種徹底):

(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)) 

爲autotool的計劃敲定在我們手動發佈後不會失敗。它檢查底層接口指針包裝是否已被釋放,可能是通過檢查其類是否爲ole::released-IUnknown ,因爲它被記錄在ole:release (ole:IUnknown-Client)的描述中。

還有使用ole:release-process-client-interfaces蠻力方式,但你應該確保你不會訪問當前口齒不清進程迄今創建的任何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.如果您的自動工具實例已經被終結,那麼它的生成需要被垃圾收集,通常可以通過全局GC實現,最終完成並釋放。

3.在Common Lisp中,你可以用change the class的一個對象。