yatasoft一‘叶’

做一粒微尘,聚满水气,滋润大地
随笔 - 29, 文章 - 0, 评论 - 121, 引用 - 0
数据加载中……

C#关闭excel进程方法

一直被一个问题困扰就是导出excel时如何关闭excel进程,我使用过oExcelApp.Quit(); 也用过GC回收,结果都不理想,后来发现可以kill进程,但是问题是kill进程 时不好解决多人并发的使用,比如一个人在导表然后kill所以的excel但是如果同时又有人在导表那么这就把另外一个excel结束了,现在我们要办的 是如何kill当前这个进程,这里我们先看一下代码:

oExcelApp.Quit();
    oExcelApp = null;
    PublicMethod.Kill(oExcelApp);//调用kill当前excel进程

PublicMethod.Kill()内容是:

using System.Runtime.InteropServices;
 public class PublicMethod
 {
  public PublicMethod()
  {
   //
   // TODO: 在此处添加构造函数逻辑
   //
  }
  [DllImport("User32.dll",   CharSet   =   CharSet.Auto)]  
  public static extern int GetWindowThreadProcessId(IntPtr hwnd,out int ID);
  public static void Kill(Excel.Application excel)
  {  
   IntPtr t=new IntPtr(excel.Hwnd);   //得到这个句柄,具体作用是得到这块内存入口 

  int k= 0;  
   GetWindowThreadProcessId(t,out k);   //得到本进程唯一标志k
   System.Diagnostics.Process p=System.Diagnostics.Process.GetProcessById(k);   //得到对进程k的引用
   p.Kill();     //关闭进程k
  }

}

 

这样我们就可以关闭当前进程excel而不是杀掉所有的类型为excel进程了,

 

另外一个新发现的方法:

如果你某刻发现一个excel做模板然后载入excel应用对象,导出数据如果excel进程自己会退出,那么复制这个模板,然后清空内容,重新在这个摸板设计你x想要的模板内容,载入这个模板excel应用对象,导出数据,那么这个excel进程自己会很听话的退掉,
我曾经测试过,再系统非常多用户时同时点击导出excel报表也仅仅是2-3个进程,正常使用仅仅一个!前提是你要发现一个听话的excel模板。

posted on 2008-08-06 13:43 yatasoft 阅读(3032) 评论(24)  编辑 收藏 网摘 所属分类: 实习计划

评论

#1楼   回复  引用  查看    

很好
2008-08-06 13:52 | sskset      

#2楼   回复  引用  查看    

good!
2008-08-06 13:54 | Tony Zhou      

#3楼   回复  引用    

服务端excel文件生成,调用excel固然省事,但我不太喜欢这个办法.
2008-08-06 13:55 | allenpan[未注册用户]

#4楼   回复  引用  查看    

当 Visual Studio .NET 从托管代码调用 COM 对象时,它自动创建 Runtime Callable Wrapper (RCW)。RCW 封送 .NET 应用程序和 COM 对象之间的调用。RCW 保留着对 COM 对象的引用计数。因此,如果 RCW 上没有将所有引用全部释放,COM 对象就不会退出。

要确保退出 Office 应用程序,自动化代码一定要满足以下条件:
• 将每个对象声明为新变量。例如,将下面的代码行
oBook = oExcel.Workbooks.Add()
更改为以下内容:
dim oBooks as Excel.Workbooks
oBooks = oExcel.Workbooks
oBook = oBooks.Add()

• 停止使用某个对象时,应使用 System.Runtime.InteropServices.Marshal.ReleaseComObject。这样可以减少 RCW 的引用计数。
• 要释放对变量的引用,请将变量设置为等于 Nothing 或 Null。
• 使用 Office 应用程序对象的 Quit 方法通知服务器关闭。



请注意,如果您执行了“重现问题的步骤”部分描述的步骤,而服务器仍然不关闭,您可以在释放最后一个对象后使用 GC.Collect() 方法。因为运行库对 RCW 执行垃圾收集,所以 GC.Collect() 会强制垃圾回收器运行,并且会释放 RCW 仍然拥有的任何引用。GC.Collect() 会尝试最大限度地回收可用内存。注意,这不能保证所有内存都被回收。

2008-08-06 14:01 | 阿新      

#5楼   回复  引用  查看    

很好
2008-08-06 14:14 | 张波sun      

#6楼   回复  引用  查看    

這種是服務器資源的競爭,你的代碼可以寫的好,正常退出,使用了這種組件只有有一家程序寫的不好,無法退出,服務器就不行了.

我以前常受這種困擾,然後服務器管理人員就問,誰用了這個組件啊?我無語.

所以我們通常用"暴力"的方法,檢查創建時間,如果超出了10分鍾,全部殺掉,這種方法最簡單,哈哈.
2008-08-06 15:19 | 老头      

#7楼[楼主]   回复  引用  查看    

新发现,如果你某刻发现一个excel做模板然后载入excel应用对象,导出数据如果excel进程自己会退出,那么再复制这个模板,然后清空内容,重新在这个摸板设计内容,在载入excel应用对象,导出数据,那么这个excel进程自己会很听话的退掉,
我曾经测试过,再系统非常多用户时同时点击导出excel报表也仅仅是2-3个进程,正常使用仅仅一个!
2008-08-06 15:38 | yatasoft      

#8楼   回复  引用    

关闭Word的冗余进程有什么好的方法那???
2008-08-06 15:48 | ghtn_yu[未注册用户]

#9楼[楼主]   回复  引用  查看    

兄弟word出现垃圾进程。。。。。
反正我用的时候word都很老实的,基本按时下班。
2008-08-06 16:02 | yatasoft      

#10楼   回复  引用  查看    

资源释放问题,处理得好的话,就不需要这么暴力的方法
2008-08-06 16:11 | 可乐加冰      

#11楼   回复  引用  查看    

Mark.
2008-08-06 16:31 | 寒枫      

#12楼   回复  引用  查看    

我前上周帮老婆做了个处理excel的小程序,貌似没有遇到过Excel.exe进程不能正常退出的情况,关键还是调用Com组件时应注意使用一个对像声明一个变量,不用时让其为null.
2008-08-06 16:35 | Evilbaniry      

#13楼   回复  引用  查看    

@Evilbaniry
楼主说的是导出Excel的时候,这种情况确实存在,现在都没有消失。
2008-08-06 16:36 | 寒枫      

#14楼   回复  引用  查看    

你们应该换一个方法想!

启动一个或多个 Excel 进程后
不关闭进程

使用方法类似【连接池】那样;有就用没有就创建;

这样其实在内存润徐的情况下可以提高很高效能;

不过就是要写些代码来管理使用这个【池】
2008-08-06 16:53 | 曲滨*銘龘鶽      

#15楼[楼主]   回复  引用  查看    

谢谢大家请大家留意我近期的Netron应用实战系列

一次图形图像类库的开发!一次.net组件的开发!一次MVC的尝试!一次重构的旅途!

http://www.cnblogs.com/yatasoft/category/149035.html" target="_new">http://www.cnblogs.com/yatasoft/category/149035.html
2008-08-06 17:00 | yatasoft      

#16楼   回复  引用  查看    

以上都不是正解,正解是使用Static对象!已经稳定运行8个月了
2008-08-06 18:07 | 个人知识管理      

#17楼   回复  引用  查看    

其实这个问题用GC是可以解决的,你把GC放到你处理Excel函数的外面就可以了。杀进程我想应该没有必要的吧!
2008-08-06 19:24 | 金鱼      

#18楼   回复  引用  查看    

习惯用GC
2008-08-06 20:04 | BoyLee      

#19楼   回复  引用  查看    

个人知识管理 提出使用Static对象也许是一种不错的方法哦。反正我没有试过,我不用Office中的Excel库来做,我在项目中采用的是开源的Excel库NExcel,完全使用.net代码写的,根本不存在Kill进程的问题。
2008-08-07 01:43 | 深蓝      

#20楼   回复  引用    

使用VB.NET的里对象,
先看系统中有没有EXCEL对象,有的话直接使用,没有再createobject.
此种方法,我试过,可以正常退出
2008-08-07 10:01 | graystar[未注册用户]

#21楼   回复  引用    

很不错!我找了好久都没有找到!
2008-08-07 17:07 | csui2008[未注册用户]

#22楼   回复  引用    

谢谢提供以上资料,我使用时老是提示 p.Kill(); 访问拒绝,是没有权限还是怎么回事?
2008-09-26 12:47 | luzhuxi[未注册用户]

#23楼   回复  引用  查看    

"外一个新发现的方法……"不知道你用的是哪个模板,可否告知一下,多谢
Excel.Application xlApp = new.Excel.Application();

Workbooks workbooks = xlApp.Workbooks;
Workbook workbook =workbooks.Add(XlWBATemplate.xlWBATWorksheet);
Worksheet worksheet = (Worksheet)workbook.Worksheets[1];

我用的是这个模板,总是存在Excel.exe进程,我想实现的就是导出后,当用户关闭Excel的时候,Excel.exe进程然后再关闭,vb中用“createobject”可以实现,c#不知道用什么方法实习了,请教了!!高手!!
2009-03-11 10:34 | 燕山又飘雪      

#24楼   回复  引用  查看    

以上方法都试了一下,都不是很理想啊。kill有时候取不到进程id,所有的方法只要客户端非法操作(比如正在载入的时候关闭或者刷新),都会出问题。还有强行关闭进程有时候就无法再打开进程了...
2009-06-24 22:34 | 品茶      
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1261969 WN0OHKN0j6k=



相关文章:

相关链接: