Excleプロセスを完全に閉じるいくつかの方法

6101 ワード

前に研究したことがある質問ですが、最近友達に聞かれたので、ここでまとめてメモを取ります.
アプリケーション内でExcleアプリケーションオブジェクトを作成してExcleを開く場合、いくつかの問題に注意しないと、Excleプロセスを完全に閉じることができない可能性があります.以下の状況を考察します.
        public static void startexcel()
        {
            var  excel = new Microsoft.Office.Interop.Excel.Application();
            excel.Visible = true;
            var book=  excel.Application.Workbooks.Open("D:\\Book1.xlsx");
        }

上のコードはワークブックを開き、Excelは独立したプロセスを開始し、ユーザーにインタフェースを表示し、メソッドが終了した後にExcelを閉じることはありません.この場合,ユーザにいつワークブックを閉じるかを決定させるためである.
その結果、ユーザーがワークブックを手動で閉じた後、Excleプロセスは閉じられませんでした.これは私たちのためです.NET管理コードが開いているExcleの非管理コード、.NET実行時に関連ハンドルが解放されていない場合は、次のコードを追加して解放する必要があります.
        public static void startexcel()
        {
            var  excel = new Microsoft.Office.Interop.Excel.Application();
            excel.Visible = true;
            var book=  excel.Application.Workbooks.Open("D:\\Book1.xlsx");

            System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
            excel = null;
            GC.Collect();
        }

上のコード、Marshal.ReleaseComObjectはCOMコンポーネントオブジェクトを解放します.ここではexcelです.その後、コードはexcel=nullを設定します.これにより、ゴミ回収を実行してから有効になります.そうしないと、excelハンドルを回収できません.
なお、上記のコードを実行すると、Excelプロセスは閉じられません.Excleプロセスハンドルと.NET実行時の関係.
ユーザーが外部でExcleフォームを手動で閉じると、Excleプロセスは本当にタスクマネージャから消えます.
3行のコードを付けなくてもExcleプロセスを閉じることができるという友人もいるかもしれません.
そうです.上のコードは、Excleという非管理リソースをすぐに解放したにすぎません.我々のexcleオブジェクトはローカルオブジェクトであることに気づき、メソッドが終了すると、excleオブジェクトはメソッドスタック上で空になり、外部で適切なときにゴミ回収を呼び出すだけで、Excleプロセスを完全に閉じる効果を実現できます.
startexcel();
GC.Collect();
Console.WriteLine("excel close ok.");

もし私たちのExcelプロセスがユーザーによって閉鎖されるのではなく、プログラムによって自動的に閉鎖されたらどうしますか?
このときは、Excleアプリケーションオブジェクトのクローズ方法を呼び出すだけです.
完全なコードは以下の通りです.次のコードは、Excleプロセスがマクロファイルを開き、ワークブックを開き、イベントを処理し、最後にExcleフォームを閉じ、プロセスクリーンアップリソースを閉じる機能を示しています.
Excleのワークブックの保存と閉じるイベントは、ワークブックを保存するときにサーバにワークブックのコピーをアップロードするなど、役に立つ場合があります.
 public static void startexcel()
        {
            var  excel = new Microsoft.Office.Interop.Excel.Application();
            excel.Visible = true;
            excel.Workbooks.Open("C:\\A1000.xla");
            var book=  excel.Application.Workbooks.Open("D:\\Book1.xlsx");
            excel.WorkbookBeforeSave += Excel_WorkbookBeforeSave;
            excel.WorkbookBeforeClose += Excel_WorkbookBeforeClose;
            book.Close();
            excel.Quit();
            System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
            excel = null;
            GC.Collect();
        }

        private static void Excel_WorkbookBeforeClose(Workbook Wb, ref bool Cancel)
        {
            Console.WriteLine("Excel  ,title:" + Wb.Title);
        }

        private static void Excel_WorkbookBeforeSave(Workbook Wb, bool SaveAsUI, ref bool Cancel)
        {
            Console.WriteLine("Excel ,title:"+Wb.Title);
        }

注意:
本文のやり方は、Wordなどの他のOfficeプログラムを閉じることにも適用されます.