我看了很多帖,可还是解决不了。下面是我的一段代码,是比较流行的,可还是杀不掉。我的环境是Window2003,vs 2002,Excel2000.我把几乎所有的EXCEL用户都设了权限,这个问题烦死我了。哪位大哥帮帮忙吧,我觉得是权限设置有问题,该如何设。跪谢了大哥们,解决加前一帖共200分!!!
Excel.Application  oExcel;  
Excel.Workbooks  oBooks;  
Object  oMissing  =  System.Reflection.Missing.Value; 

oExcel  =  new  Excel.ApplicationClass();  
oBooks=oExcel.Workbooks;
Excel.Workbook oBook=oBooks.Add(oMissing);
Excel.Worksheet oSheet = (Excel.Worksheet)oBook.ActiveSheet;
//----------------------------------------------------------
oSheet.Cells[1,1]="111";
oSheet.Cells[2,1]="222";
//--------------------------------------------------------
oBook.Saved  =  true;  
oExcel.UserControl  =  false;  
string filename = DateTime.Now.Ticks.ToString();
string  mm=Server.MapPath(  ".")+ "\\" + filename + ".xls";//服务器保存地址  
oExcel.ActiveWorkbook.SaveCopyAs  (mm);
//--------------------------------------------
System.Runtime.InteropServices.Marshal.ReleaseComObject (oSheet);
oSheet = null;oBook.Close(false,Type.Missing,Type.Missing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook);
oBook = null;oBooks.Close();
System.Runtime.InteropServices.Marshal.ReleaseComObject (oBooks);
oBooks = null;oExcel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel);
oExcel= null;
//---------------------------------------------------------------
GC.Collect();
GC.WaitForPendingFinalizers();
//------------------------------------------------------------
//-----------------------------------------------------------

解决方案 »

  1.   

    后来我又用了Kill的方法,代码如下。反应是“远程服务调用被拒绝”
    private void KillProcess(string processName)
    {
      System.Diagnostics.Process myproc= new System.Diagnostics.Process();
      foreach (Process thisproc in Process.GetProcessesByName(processName)) 
       {
          if(!thisproc.CloseMainWindow())
           {
    thisproc.Kill();
           }
        }
    }
      

  2.   

    你是在哪个页面打开的?   输出的那个页面也要加上 GC.Collect()
      

  3.   

    to shenkedong9(I LOVE INTER)
    不明白立的意思,我是在 Page_Load中,如下,有什么不对么?
    private void Page_Load(object sender, System.EventArgs e)
    {
    Excel.Application  oExcel;  
    Excel.Workbooks  oBooks;  
    Object  oMissing  =  System.Reflection.Missing.Value; 

    oExcel  =  new  Excel.ApplicationClass();  
    oBooks=oExcel.Workbooks;
    Excel.Workbook oBook=oBooks.Add(oMissing);
    Excel.Worksheet oSheet = (Excel.Worksheet)oBook.ActiveSheet;
    //----------------------------------------------------------
    oSheet.Cells[1,1]="111";
    oSheet.Cells[2,1]="222";
    //--------------------------------------------------------
    oBook.Saved  =  true;  
    oExcel.UserControl  =  false;  
    string filename = DateTime.Now.Ticks.ToString();
    string  mm=Server.MapPath(  ".")+ "\\" + filename + ".xls";//服务器保存地址  
    oExcel.ActiveWorkbook.SaveCopyAs  (mm);
    //--------------------------------------------
    System.Runtime.InteropServices.Marshal.ReleaseComObject (oSheet);
    oSheet = null;oBook.Close(false,Type.Missing,Type.Missing);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook);
    oBook = null;oBooks.Close();
    System.Runtime.InteropServices.Marshal.ReleaseComObject (oBooks);
    oBooks = null;oExcel.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel);
    oExcel= null;
    //---------------------------------------------------------------
    GC.Collect();
    GC.WaitForPendingFinalizers();}
      

  4.   

    加on error resume next
      

  5.   

    http://goody9807.611.cn/Announce/Announce.asp?BoardID=2&ID=581
      

  6.   

    to  lang11zi(micro奔):
    不明白你的意思。to goody9807() :
    我进不去,你给的帖子要20分才能进。
      

  7.   

    如果一次运行出错,需要手工把Excel进程终止,然后再使用网上的那些方法,应该没有问题。
      

  8.   

    to fengfangfang() :
    这样处理时不是和你说的一个意思,我试了不行。
    try
    {
      .
      .
      .
    }
    finally
    {
      GC.Collect();
    }
      

  9.   

    把这句去掉试试 GC.WaitForPendingFinalizers();
      

  10.   

    to shenkedong9(I LOVE INTER):
    试过了,没用。
      

  11.   

    我也前也是的,你是不是引用了Excel.exe呀?
    看一下它的版本。
    ----------------------------------------
    有一次不上心装了office 2003 ,又一不小心引用了 excel.exe (11.0版的)
    结果一不小心发现 可以用来操作excel文件。楼主实在没有办法试试装上2003呀!
      

  12.   

    我在做REPOTTING SERVICES 报表导出到EXCEL时,也有个进程到现在就一直存在!
    手动杀也杀不掉,占内存也不多,但耗CUP时间太多了80%左右,我也快急死了,现在机子给这个进程搞的好慢!我的机子配置是P4 3GHZ 512M内存!三线程联想品牌机!
    我也没有办法解决
      

  13.   

    to powerllr(笨笨的招财鸡);
    我装的是Office2000,引用得是Excel 9.0,这样有问题么?
      

  14.   

    to jakexue31(anni)
    我不是一个进程,我是运行一次,多一个进程。如果只是一个进程杀不掉,也就能对付着用了。
      

  15.   

    你看看这个贴!
    我也是看人的
    推荐]如何杀掉EXCEL进程Excel.Application  oExcel;  
    Excel.Workbooks  oBooks;  
    Object  oMissing  =  System.Reflection.Missing.value; 
               
    oExcel  =  new  Excel.ApplicationClass();  
    oBooks=oExcel.Workbooks;
    Excel.Workbook oBook=oBooks.Add(oMissing);
    Excel.Worksheet oSheet = (Excel.Worksheet)oBook.ActiveSheet;
    //----------------------------------------------------------
    oSheet.Cells[1,1]="111";
    oSheet.Cells[2,1]="222";
    //--------------------------------------------------------            
    oBook.Saved  =  true;  
    oExcel.UserControl  =  false;  
    string filename = DateTime.Now.Ticks.ToString();
    string  mm=Server.MapPath(  ".")+ "\\" + filename + ".xls";//服务器保存地址  
    oExcel.ActiveWorkbook.SaveCopyAs  (mm);
    //--------------------------------------------
    System.Runtime.InteropServices.Marshal.ReleaseComObject (oSheet);
    oSheet = null;oBook.Close(false,Type.Missing,Type.Missing);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook);
    oBook = null;oBooks.Close();                  
    System.Runtime.InteropServices.Marshal.ReleaseComObject (oBooks);
    oBooks = null;oExcel.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel);
    oExcel= null;
    //---------------------------------------------------------------
    GC.Collect();
    GC.WaitForPendingFinalizers();
    //------------------------------------------------------------
    //-----------------------------------------------------------
    后来我又用了Kill的方法,代码如下。反应是“远程服务调用被拒绝”
    private void KillProcess(string processName)
    {
      System.Diagnostics.Process myproc= new System.Diagnostics.Process();
      foreach (Process thisproc in Process.GetProcessesByName(processName)) 
       {
          if(!thisproc.CloseMainWindow())
           {
         thisproc.Kill();
           }
        }
    }
    Private Sub killEXCEL() '为进程避免冲突,在调用EXCEL前先杀死现有EXCEL进程.  Dim pProcess() As Process  pProcess = Process.GetProcesses()  Dim i As Integer  For i = 0 To pProcess.Length() - 1    If (pProcess(i).ProcessName = "EXCEL") Then    pProcess(i).Kill() '关闭进程    End If  NextEnd Sub 
    ArrayList arr = new ArrayList();
    Process[] procs = Process.GetProcessesByName("Excel");
    arr.AddRange(procs);try
    {
    Application.Run(new MainForm());
    }
    catch (Exception e)
    {
    ExceptionForm.Show(e);
    }// 杀掉死掉的 Excel 进程
    procs = Process.GetProcessesByName("Excel");
    foreach (Process proc in procs)
    {
    if (arr.IndexOf(proc) < 0)
    {
    proc.Kill();
    }
    }Process.GetCurrentProcess().Kill();
    Kill 强制终止进程,而 CloseMainWindow 只是请求终止。有图形界面的进程在执行时,其消息循环处于等待状态。每当操作系统向该进程发送 Windows 消息时,该消息循环执行。调用 CloseMainWindow 会向主窗口发送关闭请求,在一个设计规范的应用程序中,该请求会关闭子窗口并撤消此应用程序所有正在运行的消息循环。通过调用 CloseMainWindow 发出的退出进程的请求不强制应用程序退出。应用程序可以在退出前请求用户验证,也可以拒绝退出。若要强制应用程序退出,请使用 Kill 方法。CloseMainWindow 的行为与用户使用系统菜单关闭应用程序主窗口的行为一样。因此,通过关闭主窗口发出的退出进程的请求不强制应用程序立即退出。如果调用 Kill,则可能丢失进程编辑的数据或分配给进程的资源。Kill 导致进程不正常终止,因而只应在必要时使用。CloseMainWindow 使进程能够有序终止并关闭所有窗口,所以对于有界面的应用程序,使用它更好。如果 CloseMainWindow 失败,则可以使用 Kill 终止进程。Kill 是终止没有图形化界面的进程的唯一方法。只能对在本地计算机上运行的进程调用 Kill 和 CloseMainWindow。无法使远程计算机上的进程退出。仅可查看在远程计算机上运行的进程的信息。private void KillProcess(string processName)
    {
    System.Diagnostics.Process myproc= new System.Diagnostics.Process();
    //得到所有打开的进程
        try{
        foreach (Process thisproc in Process.GetProcessesByName(processName)) {
           if(!thisproc.CloseMainWindow()){
    thisproc.Kill();
    }
            }
          }
        catch(Exception Exc)
        {
            msg.Text+= "杀死" + processName + "失败!";
        }
    }http://dotnet.aspx.cc/ShowDetail.aspx?id=299D1529-59A3-42F9-77A7-7BF353754FEA
    老孟高手的做法
    private void KillProcess(string processName)
    {
    System.Diagnostics.Process myproc= new System.Diagnostics.Process();
    //得到所有打开的进程
    try
    {
    foreach (Process thisproc in Process.GetProcessesByName(processName)) 
    {
    if(!thisproc.CloseMainWindow())
    {
    thisproc.Kill();
    }
    MessageBox.Show("杀死" + processName + "成功!");
    }}
    catch(Exception Ex)
    {
    MessageBox.Show("杀死" + processName + "失败!");
    }
    }
    在调用Excel的方法之外调用GC.Collect() 就好了,进程列表中Excel的进程在GC.Collect() 后就消失了。
    void DoSomething(){      ...      HandleExcel();      GC.Collect() ;}void HandleExcel(){Excel.Application myExcel = new Excel.Application() ;...myExcel.Quit();}
    保证GC.Collect() 收集垃圾前释放EXCEL对象极其引用,确保垃圾回收器可以回收这些资源。直接杀Excel进程,但是这样有很大的问题(有可能杀掉用户自己打开的Excel)。后来用上面的方式后就好了。本方法在WinForm下的正常,asp.net中在服务器端执行Excel好像不是很好。
    Excel是一个COM 对象,COM对象有一个引用计数的概念,只要计数不为0,Excel这个进程外COM对象就不会释放。
    前几天做了一个程序,打开EXCEL并保存数据库中,发现Excel进程关不了,后来采取了下面的方法,希望对大家有用:
    using System.Runtime.InteropServices;
    namespace ProduceDayReport
    {
    public class ExceptionReport : System.Windows.Forms.Form
    {
    ..................
    private const int  WM_CLOSE=0x0010;
    private const int  WM_QUIT=0x0012;
    private const int  WM_DESTROY=0x0002;
    .....................................
                      ..............
    delegate DataTable AsynchronousManipulateDelegage();
    private AsynchronousManipulateDelegage amd;[DllImport("user32.dll",CharSet=CharSet.Unicode)] 
    public static extern IntPtr PostMessage(IntPtr hwnd,int wMsg,IntPtr wParam,IntPtr lParam);
    [DllImport("user32.dll")]
    public static extern bool MessageBeep(BeepType beepType); 
    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);.....................//关键是下面的话excel.DisplayAlerts =false;
    PostMessage(excel.HWND,WM_CLOSE,new IntPtr(0),new IntPtr(0));
    PostMessage(excel.HWND,WM_DESTROY,new IntPtr(0),new IntPtr(0));///////////
    以上是我从程序内拷贝的一部分,希望大家知道该么做!
    如果你用的不是officeXP,则在打开EXCEL后,做这样的工作:
    excel.Workbooks.Open (.......);
    String WndClassCaption="Microsoft Excel - "+xlsName.Substring(xlsName.LastIndexOf (@"\")+1);
    IntPtr hwnd_win = FindWindow("XLMAIN", WndClassCaption);
    if(hwnd_win==IntPtr.Zero)
    {
    hwnd_win = FindWindow("MS-SDIa",xlsName.Substring(xlsName.LastIndexOf (@"\")+1));
    if(hwnd_win==IntPtr.Zero)
    {MessageBox.Show ("没找到窗口类   "+xlsName.Substring(xlsName.LastIndexOf (@"\")+1));
    return null;
    }
    }
    ...................
    并作如下更改:
    excel.DisplayAlerts =false;
    PostMessage((IntPtr)hwnd_win,WM_CLOSE,new IntPtr(0),new IntPtr(0));
    PostMessage((IntPtr)hwnd_win,WM_DESTROY,new IntPtr(0),new IntPtr(0));
    void DoSomething(){      ...      HandleExcel();      GC.Collect() ;}void HandleExcel(){Excel.Application myExcel = new Excel.Application() ;...myExcel.Quit();}
      

  16.   

    有Excel 9.0 好像有权限问题。居体是怎么回事俺也不太清楚。不过自从来用了2003以后就没有出来要杀进程的事了。
    以前也是用了那些高手说的方法,还是解决不了。
    你可以试一下。我现在用的是Excel11.0 ,现在创建文件,对文件进行操作都可以。至少我们公司内部还是可以的。
      

  17.   

    to powerllr(笨笨的招财鸡):
    可我的用户大多用的是office2000,还有客户端如果版本低于office2003会不会有问题,
    希望指点。
      

  18.   

    用户是什么不要紧。只要服务器是2003就没有问题了。Excel9.0和Excel11.0的方法参数有些不同。这是我创建excel文件的代码:
    System.Reflection.Missing ObjMissing = System.Reflection.Missing.Value;
    Excel.Application ObjApplication = new Excel.Application();
    ObjApplication.Visible = false;
    Excel.Workbooks ObjWorkbooks = (Excel.Workbooks)ObjApplication.Workbooks;
    Excel.Workbook ObjWorkbook = (Excel.Workbook)ObjWorkbooks.Add(ObjMissing);
    ObjWorkbook.SaveAs( FilePath ,ObjMissing,ObjMissing,ObjMissing,ObjMissing,ObjMissing,Excel.XlSaveAsAccessMode.xlNoChange,ObjMissing,ObjMissing,ObjMissing,ObjMissing,ObjMissing );
    ObjWorkbook.Close(false,ObjMissing,ObjMissing);
    ObjApplication.Quit();
    blFile = true;
      

  19.   

    我用的是正版的OFFICE2000,不会有这样的问题吧!
    是公司花钱买的,公司的SQL也是从微软买的
    郁闷!正版也有问题
      

  20.   

    操作EXCEL的语句要单独写成一个函数,GC.Collect()必须在此函数之外。
      

  21.   

    to powerllr(笨笨的招财鸡) 
    谢谢,我的程序是要给别人安装的,就是说服务器不在我这,如果用户的服务器用的是
    office2000,我打得包中的3个office2003的DLL是否会与之冲突。是否需要求用户从装office2003,
    再次感谢指导。
      

  22.   

    to  xlfrd(黑旋风) 
    网上看过,我也试过,可没用。
    我就是奇怪,为什么别人说可以的我确试不通,该考虑的好像都考虑了,
    现在都不知还有什么还能改的了。
      

  23.   

    1. Marshal.ReleaseComObject() 的返回值是 int
       这个函数一次只销毁一个 对 COM+ 对象的引用
       要写成这样 或是类似的
       while(Marshal.ReleaseComObject(comObject)>0)
       {}
    2. 垃圾收集要 调用两次,因为 ComObject 多半有默认的销毁函数
       GC.Collect();
       GC.WaitForPendingFinalizers();
       GC.Collect();
       GC.WaitForPendingFinalizers();
      

  24.   

    to  jessonyang() 
    你的方法试呢,还是不行。
    各位老大,我的问题还是解决不了,帮帮忙吧!!帖子还有效,我就不信没人碰到过。
      

  25.   

    我认为你写的代码都是可行的,尤其是第二种孟子的方法,我用了好用,而你现在进程杀不死的原因我觉得就是权限的问题。
    解决方法如下:
    1。把你的excel文件(就是那些你要启动,并且想要杀死进程的)放在一个文件夹里面,我认为最好放在你网站的虚拟目录下。。
    2。把刚才的文件夹设置为  web共享  ,并且赋予“写入”,“执行脚本”等等你认为有用的权限。
    这样在 iis里面,你就能看到你刚才设置的虚拟目录。以后程序也能杀死这个文件夹的进程了。注:
    如果你在服务器端杀死进程,没有问题;但是放在客户端杀死服务器上的进程就有一些说道了:
    根据我的经验,服务器是xp pro那么在客户端杀没问题,如果服务器是2003 那么就会出现“无法获得远程计算机进程”的错误。我认为这还是权限的问题,可惜2003我不太会配置。
    所以当你在客户端成功杀死2003的进程,还望分享经验。
    [email protected]
      

  26.   

    实在不行就用我的吧,也凑合着能用了http://www.cnblogs.com/lingyun_k/archive/2005/07/12/191740.html
      

  27.   

    在管理工具->组件服务->DCOM->MICROSOFT EXCEL->属性->安全->访问权限里要加上everyone
      

  28.   

    to xlfrd(黑旋风) 
    终于找到正解了,你是对的,太感谢了。
      

  29.   

    to xlfrd(黑旋风) :
    兄弟,前面还有一个同名的帖,你可以到那报个名,那还有100分给你,快去,等你去我结帖。
      

  30.   

    感谢 xlfrd  和 turner,找了 2天 终于找到 你这里 得 终极 解答了,再次感谢