[c#] 데이터 액세스 후 C #에서 Excel 응용 프로그램 프로세스 닫기

읽기 / 쓰기 작업을 위해 Excel 템플릿 파일을 여는 응용 프로그램을 C #으로 작성하고 있습니다. 사용자가 응용 프로그램을 닫을 때 Excel 파일을 저장하지 않고 Excel 응용 프로그램 프로세스를 닫고 싶습니다. 앱을 여러 번 실행 한 후 내 작업 관리자를 참조하십시오.

여기에 이미지 설명 입력

이 코드를 사용하여 Excel 파일을 엽니 다.

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

데이터 액세스를 위해 다음 코드를 사용합니다.

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

이 질문this 와 같은 스택 오버플로에서 유사한 질문을보고 답변을 테스트하지만 작동하지 않습니다.



답변

이 시도:

excelBook.Close(0);
excelApp.Quit();

통합 문서를 닫을 때 세 가지 선택적 매개 변수가 있습니다.

Workbook.close SaveChanges, filename, routeworkbook

Workbook.Close(false)또는 후기 바인딩을 수행하는 경우 0을 사용하는 것이 더 쉬울 때가
Workbook.Close(0)
있습니다. 통합 문서 닫기를 자동화 할 때 이렇게했습니다.

또한 문서를 찾아서 여기에서 찾았습니다.
Excel 통합 문서 닫기

감사,


답변

xlBook.Save();
xlBook.Close(true);
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);

이것을 시도하십시오 .. 그것은 나를 위해 일했습니다 … 프로세스를 중지하려면 해당 xl 응용 프로그램 개체를 해제해야합니다.


답변

참고 : https://stackoverflow.com/a/17367570/132599

다음과 같은 이중 점 호출 표현식을 사용하지 마십시오.

var workbook = excel.Workbooks.Open(/*params*/)

…이 방법으로 통합 문서뿐만 아니라 통합 문서에 대해서도 RCW 개체를 만들고이를 해제해야하기 때문입니다 (개체에 대한 참조가 유지되지 않는 경우 불가능).

이것은 나를 위해 문제를 해결했습니다. 코드는 다음과 같습니다.

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

...

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

그런 다음 모든 개체를 해제합니다.

System.Runtime.InteropServices.Marshal.ReleaseComObject(rng);
System.Runtime.InteropServices.Marshal.ReleaseComObject(excelSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets);
excelBook .Save();
excelBook .Close(true);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks);
excelApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);

나는 try {} finally {}무언가가 잘못 되더라도 모든 것이 해제되도록하기 위해 이것을 a 로 감싼다 (무엇이 잘못 될 수 있는가?).

public Excel.Application excelApp = null;
public Excel.Workbooks workbooks = null;
...
try
{
    excelApp = new Excel.Application();
    workbooks = excelApp.Workbooks;
    ...
}
finally
{
    ...
    if (workbooks != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks);
    excelApp.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
}


답변

이것을 생각하면 프로세스가 종료됩니다.

System.Diagnostics.Process[] process=System.Diagnostics.Process.GetProcessesByName("Excel");
foreach (System.Diagnostics.Process p in process)
{
    if (!string.IsNullOrEmpty(p.ProcessName))
    {
        try
        {
            p.Kill();
        }
        catch { }
    }
}

또한 정상적으로 닫으려고 했습니까?

myWorkbook.SaveAs(@"C:/pape.xltx", missing, missing, missing, missing, missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, missing, missing, missing, missing, missing);
excelBook.Close(null, null, null);                 // close your workbook
excelApp.Quit();                                   // exit excel application
excel = null;                                      // set to NULL


답변

Excel을 죽이는 것이 항상 쉬운 것은 아닙니다. 이 기사를 참조하십시오 : Excel을 죽이는 50 가지 방법

이 기사는 Excel을 멋지게 종료하는 방법에 대한 Microsoft ( MS Knowlege Base Article ) 의 최고의 조언을 취하지 만 필요한 경우 프로세스를 종료하여 확인합니다. 두 번째 낙하산을 좋아합니다.

열려있는 통합 문서를 모두 닫고 응용 프로그램을 종료 한 다음 xlApp 개체를 해제해야합니다. 마지막으로 프로세스가 아직 살아 있는지 확인하고 그렇다면 종료하십시오.

이 기사는 또한 모든 Excel 프로세스를 종료하지 않고 시작된 정확한 프로세스 만 종료하도록합니다.

창 핸들에서 프로세스 가져 오기를 참조하십시오.

내가 사용하는 코드는 다음과 같습니다. (매번 작동)

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


답변

나는 같은 문제를 만났고 그것을 해결하기 위해 많은 방법을 시도했지만 작동하지 않습니다. 마침내, 나는 내 방식으로 발견했습니다. 일부 참조는 여기에 링크 설명을 입력

내 코드가 누군가의 미래를 도울 수 있기를 바랍니다. 나는 그것을 해결하기 위해 이틀 이상을 보냈다. 아래는 내 코드입니다.

//get current in useing excel
            Process[] excelProcsOld = Process.GetProcessesByName("EXCEL");
            Excel.Application myExcelApp = null;
            Excel.Workbooks excelWorkbookTemplate = null;
            Excel.Workbook excelWorkbook = null;
try{
    //DO sth using myExcelApp , excelWorkbookTemplate, excelWorkbook
}
catch (Exception ex ){
}
finally
            {
                //Compare the EXCEL ID and Kill it 
                Process[] excelProcsNew = Process.GetProcessesByName("EXCEL");
                foreach (Process procNew in excelProcsNew)
                {
                    int exist = 0;
                    foreach (Process procOld in excelProcsOld)
                    {
                        if (procNew.Id == procOld.Id)
                        {
                            exist++;
                        }
                    }
                    if (exist == 0)
                    {
                        procNew.Kill();
                    }
                }
            }


답변

excelBook.Close (); excelApp.Quit (); 코드의 끝을 추가하면 충분할 수 있습니다. 내 코드에서 작동 중입니다.