C# 获取数据后关闭EXCEL应用程序进程

C# 获取数据后关闭EXCEL应用程序进程,c#,excel,process,C#,Excel,Process,我试图通过以下方式从列表中的Excel文件中获取列数据: private void Form1_Load(object sender, EventArgs e) { Excel.Application xlApp = new Excel.Application(); Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"D:/test.xlsx"); Excel

我试图通过以下方式从列表中的Excel文件中获取列数据:

private void Form1_Load(object sender, EventArgs e)
        {
            Excel.Application xlApp = new Excel.Application();
            Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"D:/test.xlsx");
            Excel.Worksheet xlWorksheet = xlWorkbook.Sheets[1];
            Excel.Range xlRange = xlWorksheet.UsedRange;

            int rowCount = xlRange.Rows.Count;
            int colCount = xlRange.Columns.Count;

            List<string> FirstColumnValues = new List<string>();
            List<string> SecondColumnValues = new List<string>();

            for (int row=1; row <= rowCount; row++)
            {
                for (int col = 1; col <= colCount; col++)
                {
                    switch (col)
                    {
                        case 1:
                            FirstColumnValues.Add(xlRange.Cells[row, col].Value2.ToString());
                            break;
                        case 2:
                            SecondColumnValues.Add(xlRange.Cells[row, col].Value2.ToString());
                            break;
                    }
                }
            }

            if (FirstColumnValues.Count != 0 && SecondColumnValues.Count != 0)
            {
                xlWorkbook.Close();
                xlApp.Quit();
                MessageBox.Show("Completed");
                Marshal.ReleaseComObject(xlRange);
                Marshal.ReleaseComObject(xlWorksheet);
                Marshal.ReleaseComObject(xlWorkbook);
                Marshal.ReleaseComObject(xlApp);
                xlApp = null;
            }
        }
private void Form1\u加载(对象发送方,事件参数e)
{
Excel.Application xlApp=新的Excel.Application();
Excel.Workbook xlWorkbook=xlApp.Workbooks.Open(@“D:/test.xlsx”);
Excel.Worksheet xlWorksheet=xlWorkbook.Sheets[1];
Excel.Range xlRange=xlWorksheet.UsedRange;
int rowCount=xlRange.Rows.Count;
int colCount=xlRange.Columns.Count;
List FirstColumnValues=新列表();
List SecondColumnValues=新列表();

对于(int row=1;row我以前去过那里。这里有一篇文章真正帮助我解决了这个问题:


Excel似乎非常顽固地终止进程。您很可能最终会使用Stase.MydioStudio.Primult.< /P> < P>杀死进程,也许,您可以考虑使用<代码> Test{{} catch {},最后{}} /代码>,并尝试。


不确定您是否看过,它可能也会给您一些见解。

我知道这个问题已经得到了回答,但我想我会分享我在解决相同问题时发现的东西。希望有人会发现这很有用。这在vb.net中,但我相信它可以翻译

Dim proc As System.Diagnostics.Process
        For Each proc In System.Diagnostics.Process.GetProcessesByName("EXCEL")
            If proc.MainWindowTitle.ToString = "" Then
                proc.Kill()
            End If
        Next
我发现当我通过我的应用程序打开Excel文件时,窗口标题为空,所以我没有关闭每个正在运行的Excel进程,而是关闭了没有标题的进程

编辑:

如果由于找不到(基本上是使用两点设置的任何变量)而要终止该过程,则至少要杀死正确的Excel实例:

[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowThreadProcessId(IntPtr hwnd, ref int lpdwProcessId);

...

if (xlApp != null)
{
  GetWindowThreadProcessId(new IntPtr(xlApp.Hwnd), ref excelProcessId);

  Process ExcelProc = Process.GetProcessById(excelProcessId);
  if (ExcelProc != null)
  {
    ExcelProc.Kill();
  }
我不主张终止进程,您应该使用VSTO Contrib进行适当清理,例如:

using (var xlApp = new Microsoft.Office.Interop.Excel.Application().WithComCleanup())

确保正在运行的Excel实例最终终止(即应用程序退出时)的最简单方法是将顶级对象包装在try/finally块中

Excel.Application xlApp;  
try{  
   xlApp = new Excel.Application();  
   ...do some work...  
}  
finally{  
   xlApp.DisableAlerts=True;  
   xlApp.Quit();  
   xlApp.DisableAlerts=False;  
   Marshal.ReleaseComObject(xlApp);  
}  

//If you don't mind having the Excel process kept alive for a while,  
//you don't even have to call ReleaseComObject() on the intermediate objects.  
//The runtime will eventually free the underlying COM objects.  

//If you want to clean up right away, your bookkeeping needs to be more thorough.  
//Every time you access a method or property that returns a runtime callable wrapper  
//(System.__ComObject), you'll need to assign them to a variable  
//and make sure Marshal.ReleaseComObject() is called.  

// More thorough bookkeeping...    
Excel.Application xlApp;  
try{  
   xlApp = new Excel.Application();  

   Excel.Workbooks xlWorkbooks = xlApp.Workbooks;  
   Excel.Workbook xlWorkbook = xlWorkbooks.Open(@"D:/test.xlsx");  
   Excel.Sheets xlSheets = xlWorkbook.Sheets;  
   Excel.Worksheet xlWorksheet = xlSheets[1];  
   Excel.Range xlRange = xlWorksheet.UsedRange;  

   ...inside the loop...  
   Excel.Range xlCell = xlRange.Cells[row, col];  
   FirstColumnValues.Add(xlCell.Value2.ToString());  
   Marshal.ReleaseComObject(xlCell);  

   ...inside the loop...  
   Excel.Range xlCell = xlRange.Cells[row, col];  
   SecondColumnValues.Add(xlCell.Value2.ToString());  
   Marshal.ReleaseComObject(xlCell);  

   ...do more work...  

   ...clean up...  
   Marshal.ReleaseComObject(xlRange);  
   Marshal.ReleaseComObject(xlWorksheet);  
   Marshal.ReleaseComObject(xlSheets);  
   Marshal.ReleaseComObject(xlWorkbook);  
   Marshal.ReleaseComObject(xlWorkbooks);  
}  
finally{  
   xlApp.DisableAlerts=True;  
   xlApp.Quit();  
   xlApp.DisableAlerts=False;  
   Marshal.ReleaseComObject(xlApp);  
}  

感谢您的回复,是的,我使用了
System.Diagnostics.Process
方法来关闭正在运行的进程。但它将关闭进程列表中的所有excel进程。是否有方法关闭由
new excel.Application()启动的唯一进程
?如果您不介意跟踪正在运行的进程,您可以在开始运行COM之前以及之后获得excel进程列表。这样,您就可以在不太混乱的情况下获得与COM对象关联的进程。您只需确保不在单独的线程上启动两个或多个COM实例,或者在其他线程上启动明智的是,这种方法行不通。哦,听起来不错。如果我没有任何直接或简短的方法,我一定会尝试。谢谢!:)为什么?这似乎是结束这个过程的唯一方法