|
分類:[ASP.NET (C#)]
開発環境:ASP.net2005 Windows2003サーバ
現在、Webサービスで内部的にExcelテンプレートを読み込み、ExcelファイルをTempフォルダに作成し、作成したExcelをバイト配列としてクライアントに返すというアプリケーションを開発中なのですが、Excelのプロセスが一つだけ残ってしまい困っています。 クライアントからWebサービスを呼ぶとサーバにExcelのプロセスが残るのですが、プロセスが残った状態で再度、同じWebサービスを呼ぶと、もう一つプロセスが起動しますが、すぐに消えてくれます。 ソースは以下のように記述しています。
//MicroSoftExcelのCOMオブジェクト Excel.Application appExcel = null; Excel._Workbook excelBook = null; Excel._Worksheet excelSheet = null; //Excel.Sheets sheets = null; Excel.Range excelRange = null;
//一時ファイルの保存先パス string WorkFilePath = String.Copy(Path.GetTempPath() + "\\" + Guid.NewGuid() + ".xls"); //テンプレートパス string execDllPath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; //実行中DLL取得 Uri wkUri = new Uri(execDllPath); string execDirName = Path.GetDirectoryName(wkUri.LocalPath); //実行中DLLディレクトリ string TemplatePath = execDirName + "\\template.xlt";
try { appExcel = new Excel.Application(); appExcel.DisplayAlerts = false; appExcel.Visible = false; excelBook = appExcel.Workbooks.Add(Path.GetFullPath(TemplatePath)); int idx;
for (int i = 1; i <= excelBook.Sheets.Count; i++) { if (excelSheet != null) Marshal.ReleaseComObject(excelSheet); excelSheet = excelBook.Sheets[i] as Excel.Worksheet; if (excelRange != null) Marshal.ReleaseComObject(excelRange); excelRange = excelSheet.Cells; switch (i) { case 1: excelRange[2, 7] = DateTime.Today; excelRange[5, 2] = 12345; excelSheet.Protect(Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); break; case 2: break; case 3: excelSheet.Protect(Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); break; case 4: excelSheet.get_Range("B15", "B24").Validation.Delete(); excelSheet.get_Range("B15", "B24").Validation.Add(Excel.XlDVType.xlValidateList, Excel.XlDVAlertStyle.xlValidAlertStop, Excel.XlFormatConditionOperator.xlEqual, "=$AA$1:$AA$" + idx, Type.Missing); excelSheet.get_Range("B15", "B24").Validation.IgnoreBlank = false; //HIDDEN列を非表示化 excelSheet.get_Range("AA1", "AF1").EntireColumn.Hidden = true;
excelSheet.Protect(Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); break; } } Excel.Worksheet select_Sheet = excelBook.Sheets[1] as Excel.Worksheet; select_Sheet.Select(Type.Missing); Marshal.ReleaseComObject(select_Sheet); select_Sheet = null; //Bookの保護 excelBook.Protect(Type.Missing, Type.Missing, Type.Missing);
} finally { if (excelRange != null) Marshal.ReleaseComObject(excelRange); excelRange = null; if (excelSheet != null) Marshal.ReleaseComObject(excelSheet); excelSheet = null; if (excelBook != null) try { excelBook.Close(true, Path.GetFullPath(WorkFilePath), false); } finally { Marshal.ReleaseComObject(excelBook); excelBook = null; } if (appExcel != null) { try { appExcel.Quit(); } finally { Marshal.ReleaseComObject(appExcel); appExcel = null; } } System.GC.Collect(); }
finally内のGC.Collectはあまり使用したくないのですが、この記述を外した場合、同画面で同操作を行った場合にプロセスがどんどん増えていってしまいます。 ここ数日、色々なサイトを調べているのですが、どうしても解決できません。
お手数ですが、ご教授お願い致します。
|