在应用程序崩溃时释放Excel.Applicationcom对象

时间:2014-05-19 09:54:43

标签: c# excel com

在创建一个简单的winform(将excel值提取到标签和文本框中)时,我遇到了这个错误:进程无法访问文件' C:\ Locations.xlsx'因为它正被另一个进程使用。

我刚调试以检查我的Excel文件的连接性...... :(

Excel.Application excelApp = new Excel.Application();
excelApp.Visible = false;
string workbookPath = tpath;
try
{
     Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(workbookPath,
                    0, true, 5, "", "", false, Excel.XlPlatform.xlWindows, "",
                    true, true, 0, true, false, false);
     Excel.Sheets excelSheets = excelWorkbook.Worksheets;
     Excel.Worksheet excelWorksheet = (Excel.Worksheet)excelSheets.get_Item("Check");
     Excel.Range excelCell = (Excel.Range)excelWorksheet.get_Range("A1", "I11");

然后我意识到com对象一定不会被释放bcoz我刚刚测试了代码的连接性。如果应用程序崩溃,这让我觉得需要释放com对象...这个文件在应用程序启动时被复制到硬盘上,并在应用程序关闭时被删除。因此,即使加载文件,也需要检查是否释放对象bcoz文件将被删除。

BTW Marshal.ReleaseComObject("Check");也没有帮助。

任何帮助。

修改 这个getdb代码进入主窗体加载的第一行。

         private void getdb()
    {
        try
        {
            if (File.Exists(tpath))
            {
                File.Delete(tpath);
            }
            else
            {
                string spath = textBox1.Text.ToString() + "\\Locations.xlsx";
                File.Copy(spath, tpath, true);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message + "\nSource: " + ex.Source + "\n" + ex.ToString(), "Database File Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

1 个答案:

答案 0 :(得分:0)

以下是我在申请中关闭它的方法:

[DllImport("user32.dll")]
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out IntPtr ProcessId);

//close excel by the interface functions
excelWorkbook.Close(true, filepath, Missing.Value);
excelApp.Quit()

// kill the curent excel instance due to the fact that not always the curent object gets released
IntPtr hwnd = new IntPtr(excelApp.Hwnd); 
IntPtr processId; 
IntPtr foo = GetWindowThreadProcessId(hwnd, out processId); 
Process proc = Process.GetProcessById(processId.ToInt32()); 
proc.Kill();