由于现在在做维护发现以前有段关于杀死EXCEL进程的代码是这样写的:  finally
                {
                    // 删除进程中 Excel.exe
                    foreach (System.Diagnostics.Process theProc in System.Diagnostics.Process.GetProcessesByName("EXCEL"))
                    {
                        if (theProc.CloseMainWindow() == false)
                        {
                            theProc.Kill();
                        }
                    }
                }
这样其实很有问题,如果客户开了多个EXCEL会被一起KILL掉.有什么办法只把读进去的
那个EXCEL给KILL掉.

解决方案 »

  1.   

    本帖最后由 net_lover 于 2012-09-18 09:45:06 编辑
      

  2.   

       /// <summary>
            /// 导出Excel后,杀死Excel进程
            /// </summary>
            /// <param name="app"></param>
            private static void KillProcess(_Excel.Application app)
            {
                IntPtr t = new IntPtr(app.Hwnd);
                int k = 0;
                GetWindowThreadProcessId(t, out k);
                System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k);
                p.Kill();
            }        [DllImport("User32.dll", CharSet = CharSet.Auto)]
            public static extern int GetWindowThreadProcessId(IntPtr hwnd, out   int ID);
      

  3.   

    想请问下如果我开了多个EXCEL 
    其实进程里显示的都是EXCEL.EXE
    这段代码是根据什么去判断我只要删除指定导入的那个EXCEL
    其他的不去动它.
      

  4.   


    startTime=Now.AddSeconds(-1)
    new excel
    endTime=Now.AddSeconds(1)
    //--------------------------
    foreach (System.Diagnostics.Process theProc in System.Diagnostics.Process.GetProcessesByName("EXCEL"))
      {
      if (theProc.StartTime.CompareTo(startTime) > 0 && theProc.StartTime.CompareTo(endTime) < 0)
      {
      theProc.Kill();
      break;
      }
      }
      

  5.   


    应该是这个问题,需要调用FinalReleaseComObject
    Mixing deterministic and non-deterministic cleanup
    http://blogs.msdn.com/b/vcblog/archive/2006/09/20/762884.aspxProper Way of Releasing COM Objects in .NET
    http://www.codeproject.com/Tips/162691/Proper-Way-of-Releasing-COM-Objects-in-NET
      

  6.   

      finally
                    {
                        //删除进程中 Excel.exe
                        //foreach (System.Diagnostics.Process theProc in System.Diagnostics.Process.GetProcessesByName("EXCEL"))
                        //{
                        //    if (theProc.CloseMainWindow() == false)
                        //    {
                        //        theProc.Kill();
                        //    }
                        //}
                        Con.Close();
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                        ThisWorkBook.Close(false, missing, missing);
                        Marshal.FinalReleaseComObject(ThisWorkBook);
                        Marshal.FinalReleaseComObject(ThisApplication);                  
                    }这样子的话会打开导入进来的EXCEL文件,能不能不让他打开?
      

  7.   


    当然只关掉使用的那个进程,,不是有个_Excel.Application参数么?
      

  8.   


    打开跟这里没关系。是你前面代码的功能的问题
    不知道你是要excel做的是什么,如果只是导入导出数据,没有必要使用COM调用Excel
      

  9.   

            /// <summary>
            /// 将文件中的数据读入到Table中
            /// </summary>
            /// <returns></returns>
            private bool ReadFileToTable(ref DataTable Table)
            {
                bool ReturnValue = true;
                string strPath;            OpenFileDialog fd = new OpenFileDialog();//首先根据打开文件对话框,选择excel表格
                fd.Filter = "表格|*.xls|(*.xlsx)|*.xlsx";//打开文件对话框筛选器            if (fd.ShowDialog() == DialogResult.OK)
                {
                    this.Cursor = Cursors.WaitCursor;
                    strPath = fd.FileName;
                    TxtPath.Text = strPath;
                    Microsoft.Office.Interop.Excel.Application ThisApplication = new Microsoft.Office.Interop.Excel.Application();
                    Microsoft.Office.Interop.Excel.Workbook ThisWorkBook;
                    object missing = System.Reflection.Missing.Value;
                    ThisWorkBook = ThisApplication.Workbooks.Open(strPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                    string strCon = @"provider=microsoft.jet.oledb.4.0;data source=" + TxtPath.Text + ";extended properties='Excel 8.0;HDR=YES;IMEX=1'";//关键是红色区域
                    OleDbConnection Con = new OleDbConnection(strCon);//建立连接
                    try
                    {
                        //获得excel第一个单元格的sheet名
                        Con.Open();
                        System.Data.DataTable dtSheet = Con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                        string tableName = dtSheet.Rows[0][2].ToString().Trim();                    string strSql = "select * from [" + tableName + "]";//表名的写法也应注意不同,对应的excel表为sheet1,在这里要在其后加美元符号$,并用中括号
                        OleDbCommand Cmd = new OleDbCommand(strSql, Con);//建立要执行的命令
                        OleDbDataAdapter da = new OleDbDataAdapter(Cmd);//建立数据适配器                    DataSet ds = new DataSet();//新建数据集ITPUB个人空间
                        da.Fill(ds, "shyman");//把数据适配器中的数据读到数据集中的一个表中(此处表名为shyman,可以任取表名)
                        //指定datagridview1的数据源为数据集ds的第一张表(也就是shyman表),也可以写ds.Table["shyman"]
                        Table = ds.Tables[0];
                        // 日产格式
                        if (TxtOrderType.Text.Trim() == "01")
                        {
                            Table = NissanToFormat(Table);
                        }                }
                    catch (Exception ex)
                    {
                        ReturnValue = false;
                        this.BtnSave.Enabled = false;
                        this.DgvMain.Rows.Clear();
                        //MessageBox.Show(ex.Message, "订单读入", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        // 捕捉异常
                        MessageBox.Show("请确认导入文件的正确性以及只读属性!", "订单读入", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    finally
                    {
                        //删除进程中 Excel.exe
                        //foreach (System.Diagnostics.Process theProc in System.Diagnostics.Process.GetProcessesByName("EXCEL"))
                        //{
                        //    if (theProc.CloseMainWindow() == false)
                        //    {
                        //        theProc.Kill();
                        //    }
                        //}
                        Con.Close();
                        ThisWorkBook.Close(false, missing, missing);
                        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ThisWorkBook);
                        ThisApplication.Quit();
                        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ThisApplication);
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                        //KillProcess(ThisApplication);
                    }
                }
                else
                {
                    return false;
                }
                return ReturnValue;
            }
            //private static void KillProcess(Microsoft.Office.Interop.Excel.Application app)
            //{
            //    IntPtr t = new IntPtr(app.Hwnd);
            //    int k = 0;
            //    GetWindowThreadProcessId(t, out k);
            //    System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k);
            //    p.Kill();
            //}        //[DllImport("User32.dll", CharSet = CharSet.Auto)]
            //public static extern int GetWindowThreadProcessId(IntPtr hwnd, out   int ID);
    这个是就是原来的订单导入方法,我其实只需要将EXCEL文件后
    在进程里再把这个EXCEL文件关掉,但是不能影响其他打开的EXCEL.
      

  10.   

    原来是用这个方法的
    //删除进程中 Excel.exe
      //foreach (System.Diagnostics.Process theProc in System.Diagnostics.Process.GetProcessesByName("EXCEL"))
      //{
      // if (theProc.CloseMainWindow() == false)
      // {
      // theProc.Kill();
      // }
      //}
    这样会把所有的EXCEL进程都关掉了,想请教下有其他办法不.
      

  11.   

    不是告诉你使用完FinalReleaseComObject了吗?怎么还System.Diagnostics.Process.GetProcessesByName("EXCEL")啊
    System.Diagnostics.Process.GetProcessesByName("EXCEL")是关闭全部的
      

  12.   


    这个我已经注掉了啊
    现在是
       finally
                    {
                        Con.Close();
                        //删除进程中 Excel.exe
                        
                        //foreach (System.Diagnostics.Process theProc in System.Diagnostics.Process.GetProcessesByName("EXCEL"))
                        //{
                        //    if (theProc.CloseMainWindow() == false)
                        //    {
                        //        theProc.Kill();
                        //    }
                        //}                 
                        //Microsoft.Office.Interop.Excel.ApplicationClass m_objExcel = new Microsoft.Office.Interop.Excel.ApplicationClass();
                        //m_objExcel.Visible = false;
                        //KillProcess(m_objExcel);
                        ThisWorkBook.Close(false, missing, missing);
                        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ThisWorkBook);
                        ThisApplication.Quit();
                        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ThisApplication);
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                       
                    }
    但是EXCEL还会把文件打开显示出来,有什么办法不打开或者打开后关掉吗?
      

  13.   

    跟你说了文件打开跟这没关系ThisApplication.Visible=false才是决定是否显示的地方