4

私はこの問題に数日間苦労してきました.researchを行い、さまざまなフォーラムで見つけたすべての提案を適用しましたが、まだ解決できません.

私の問題は、相互運用ライブラリを使用したExcelにあります。テンプレートとしてExcelファイルを使用しているため、それを開いて新しい名前で新しい場所に保存しています。ファイルが作成されて閉じられた後も Excel プロセスが実行され続けることを除いて、すべてがうまく機能します。

これは私のコードです

protected string CreateExcel(string strProjectID, string strFileMapPath)
{
    string strCurrentDir = HttpContext.Current.Server.MapPath("~/Reports/Templates/");
    string strFile = "Not_Created";

    Application oXL;
    Workbook oWB;        

    oXL = new Application();
    oXL.Visible = false;

    Workbooks wbks = oXL.Workbooks;
    //opening template file
    oWB = wbks.Open(strFileMapPath);        

    oXL.Visible = false;
    oXL.UserControl = false;
    strFile = strProjectID + "_" + DateTime.Now.Ticks.ToString() + ".xlsx";
    //Saving file with new name
   oWB.SaveAs(strCurrentDir + strFile, XlFileFormat.xlWorkbookDefault, null, null,    false, false, XlSaveAsAccessMode.xlExclusive, false, false, null, null);

    oWB.Close(false, strCurrentDir + strFile, Type.Missing);

    wbks.Close();

    oXL.Quit();


    System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(wbks);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oWB);


    oWB = null;
    oXL = null;
    wbks = null;
    GC.Collect();

    return strFile;
}

ご覧のとおり、すべてのオブジェクトを閉じて解放していますが、アプリケーションは終了しません。

私は、Windows Server 2008 (運用) と Windows 7 (開発) の両方で、IIS7 を使用して 32 ビットでテストしています。

4

8 に答える 8

6

試す

Process excelProcess = Process.GetProcessesByName("EXCEL")[0];
if (!excelProcess.CloseMainWindow())
{
 excelProcess.Kill();
}
于 2013-05-23T04:36:24.353 に答える
3

これが私がこの問題を回避した方法です:

// Store the Excel processes before opening.
Process[] processesBefore = Process.GetProcessesByName("excel");

// Open the file in Excel.
Application excelApplication = new Application();
Workbook excelWorkbook = excelApplication.Workbooks.Open(Filename);

// Get Excel processes after opening the file.
Process[] processesAfter = Process.GetProcessesByName("excel");

// Now find the process id that was created, and store it.
int processID = 0;
foreach (Process process in processesAfter)
{
    if (!processesBefore.Select(p => p.Id).Contains(process.Id))
    {
        processID = process.Id;
    }
}

// Do the Excel stuff

// Now close the file with the COM object.
excelWorkbook.Close();
excelApplication.Workbooks.Close();
excelApplication.Quit();

// And now kill the process.
if (processID != 0)
{
    Process process = Process.GetProcessById(processID);
    process.Kill();
}
于 2014-01-16T14:25:39.850 に答える
2

こちらをご覧ください:非表示の Excel アプリケーション インスタンスの ProcessID (PID) を取得する方法

API を介して ProcessID を追跡し、GetWindowThreadProcessIdExcel Application オブジェクトのインスタンスに特に一致するプロセスを強制終了できます。

[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);

Process GetExcelProcess(Microsoft.Office.Interop.Excel.Application excelApp)
{
     int id;
     GetWindowThreadProcessId(excelApp.Hwnd, out id);
     return Process.GetProcessById(id);
}

void TerminateExcelProcess(Microsoft.Office.Interop.Excel.Application excelApp)
{
     var process = GetExcelProcess(excelApp);
     if (process != null)
     {
          process.Kill();
     }
}
于 2016-06-06T16:47:58.753 に答える
1

このメソッドを作成しましたが、テストでは機能します。

private void ClearMemory(Application excelApp) {
    excelApp.DisplayAlerts = false;
    excelApp.ActiveWorkbook.Close(0);
    excelApp.Quit();
    Marshal.ReleaseComObject(excelApp);
}
于 2016-05-12T16:16:10.413 に答える
0

相互運用アセンブリを使用する代わりに、Open XML SDK 2.0 for Microsoft Office ライブラリを使用して Excel ドキュメントを作成してみてください。私の経験では、はるかに高速に実行され、使いやすくなっています。

于 2013-03-06T21:09:25.810 に答える
-2
oWB.Close(false, strCurrentDir + strFile, Type.Missing);
oWB.Dispose();
wbks.Close();
wbks.Dispose();
oXL.Quit();
oXL.Dispose();


System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wbks);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWB);
于 2013-03-06T18:53:50.853 に答える