programming:cs:cs_tips

文書の過去の版を表示しています。


C# Tips

NDesk.Optionsが超便利。MIT/X11ライセンスなのも素敵。

Microsoft.Office.Interop.Excel.Applicationでエクセルのシートを操作中に、例外などで異常終了するとexcel.exeがゾンビプロセス化し残り続ける事がある。更に悪い事にExcel.Applicationのプロセスはタスクバーには表れないので、気づいた時には大量のゾンビexcel.exeが存在し、1つずつタスクマネージャで殺していく簡単なお仕事に追われることになる。

この問題は中々根が深くて──というか原因はCOMの解放漏れなんだけど、解放漏れがCでいう所のfreeし忘れなんて明白なものではなく“コードの書き方”ひとつで出来てしまうのが困り物。というわけで、少々行儀は悪いが強制的にガベコレを走らせ、それでもプロセスが残っていたらkillする方向で対策する。

class KillExcelApp
{
    using Excel = Microsoft.Office.Interop.Excel;
    void ProcExcel()
    {
        Excel.Application excelApp = null;
        System.Diagnostics.Process excelProcess = null;
        try
        {
            excelApp = new Excel.Application();
            excelProcess = GetExcelProcess(excelApp);
 
            // Excel.Applicationを使った処理
            ...
 
            // Excel.Applicationを閉じる
            excelApp.Quit();
            excelApp = null;
            // 念のため待ってみる
            System.Threading.Thread.Sleep(2000);
            GC.Collect();
            System.Threading.Thread.Sleep(2000);
        }
        finally
        {
            GC.Collect();
            // Excelが残ってたら強制終了
            if (excelProcess.HasExited == false)
            {
                excelProcess.Kill();
            }
        }
    }
 
    [DllImport("user32.dll")]
    static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
    System.Diagnostics.Process GetExcelProcess(Excel.Application excelApp)
    {
        int id;
        GetWindowThreadProcessId(excelApp.Hwnd, out id);
        return System.Diagnostics.Process.GetProcessById(id);
    }
}

他にいい方法があったら教えてください。

参考サイト:

パーミッション的には全く問題ない場所で、System.IO.File.Copyで新たにファイルをコピーしたあと、同じファイルに上書きコピーしようとするとSystem.UnauthorizedAccessException例外が発生する事がある。 そんな時はCopyで作成したファイルに対してFile.SetAttributes(file, FileAttributes.Normal)してやる。

  • programming/cs/cs_tips.1424936093.txt.gz
  • 最終更新: 2015-02-26 16:34
  • by Decomo