Closing Excel Application Process in C# after Data

2019-01-04 00:40发布

I'm writing an application in C# that opens an Excel template file for read/write operations. I want to when user closes the application, excel application process has been closed, without saving excel file. See my Task Manager after multiple runs of the app.

enter image description here

I use this code to open the excel file :

public Excel.Application excelApp = new Excel.Application();
public Excel.Workbook excelBook;
excelBook = excelApp.Workbooks.Add(@"C:/pape.xltx");

and for data access I use this code :

Excel.Worksheet excelSheet = (Worksheet)(excelBook.Worksheets[1]);
excelSheet.DisplayRightToLeft = true;
Range rng;
rng = excelSheet.get_Range("C2");
rng.Value2 = txtName.Text;

I see similar questions in stackoverflow such as this question and this, and test answers, but it doesn't works.

15条回答
Explosion°爆炸
2楼-- · 2019-01-04 01:04

The right way to close all excel process

var _excel = new Application();
foreach (Workbook _workbook in _excel.Workbooks) {
    _workbook.Close(0);
}

_excel.Quit();
_excel = null;
var process = System.Diagnostics.Process.GetProcessesByName("Excel");
foreach (var p in process) {
    if (!string.IsNullOrEmpty(p.ProcessName)) {
        try {
            p.Kill();
        } catch { }
    }
}
查看更多
一夜七次
3楼-- · 2019-01-04 01:08

excelBook.Close(); excelApp.Quit(); add end of the code, it could be enough. it is working on my code

查看更多
放荡不羁爱自由
4楼-- · 2019-01-04 01:10

Killing Excel is not always easy; see this article: 50 Ways to Kill Excel

This article takes the best advice from Microsoft (MS Knowlege Base Article) on how to get Excel to quit nicely, but then also makes sure about it by killing the process if necessary. I like having a second parachute.

Make sure to Close any open workbooks, Quit the application and Release the xlApp object. Finally check to see if the process is still alive and if so then kill it.

This article also makes sure that we don't kill all Excel processes but only kills the exact process that was started.

See also Get Process from Window Handle

Here is the code I use: (works every time)

Sub UsingExcel()

    'declare process; will be used later to attach the Excel process
    Dim XLProc As Process

    'call the sub that will do some work with Excel
    'calling Excel in a separate routine will ensure that it is 
    'out of scope when calling GC.Collect
    'this works better especially in debug mode
    DoOfficeWork(XLProc)

    'Do garbage collection to release the COM pointers
    'http://support.microsoft.com/kb/317109
    GC.Collect()
    GC.WaitForPendingFinalizers()

    'I prefer to have two parachutes when dealing with the Excel process
    'this is the last answer if garbage collection were to fail
    If Not XLProc Is Nothing AndAlso Not XLProc.HasExited Then
        XLProc.Kill()
    End If

End Sub

'http://msdn.microsoft.com/en-us/library/ms633522%28v=vs.85%29.aspx
<System.Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, _
    ByRef lpdwProcessId As Integer) As Integer
End Function

Private Sub ExcelWork(ByRef XLProc As Process)

    'start the application using late binding
    Dim xlApp As Object = CreateObject("Excel.Application")

    'or use early binding
    'Dim xlApp As Microsoft.Office.Interop.Excel

    'get the window handle
    Dim xlHWND As Integer = xlApp.hwnd

    'this will have the process ID after call to GetWindowThreadProcessId
    Dim ProcIdXL As Integer = 0

    'get the process ID
    GetWindowThreadProcessId(xlHWND, ProcIdXL)

    'get the process
    XLProc = Process.GetProcessById(ProcIdXL)


    'do some work with Excel here using xlApp

    'be sure to save and close all workbooks when done

    'release all objects used (except xlApp) using NAR(x)


    'Quit Excel 
    xlApp.quit()

    'Release
    NAR(xlApp)

End Sub

Private Sub NAR(ByVal o As Object)
    'http://support.microsoft.com/kb/317109
    Try
        While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0)
        End While
    Catch
    Finally
        o = Nothing
    End Try
End Sub
查看更多
登录 后发表回答