C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 20 を表示中)
■8685 / )  Excelのプロセスが一つだけ残ってしまいます
□投稿者/ 大阪人 (1回)-(2007/10/06(Sat) 21:09:44)

分類:[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はあまり使用したくないのですが、この記述を外した場合、同画面で同操作を行った場合にプロセスがどんどん増えていってしまいます。
ここ数日、色々なサイトを調べているのですが、どうしても解決できません。

お手数ですが、ご教授お願い致します。
返信 編集キー/


管理者用

- Child Tree -