请教如何根据kill Excel Application 的进程。

ufo20020427 2014-07-24 05:01:42
用微软自带Interop.Excel的操作,大家都知道即使关闭了,仍存在着EXCEL进程。



[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern int GetWindowThreadProcessId(IntPtr hwnd, out uint ID);

IntPtr hwndExcel = new IntPtr(_excel.Hwnd);

GetWindowThreadProcessId(hwndExcel, out processId);

//根据获取到的processId,就可以 kill该进程。


//以上代码在vs.net运行(即F5),是正常的。
但是部署到iis中,则 GetWindowThreadProcessId里面返回的processId总是0
不管我在dcomcnfg的标识中,用哪种启动方式,都不可以(我都是用administrator)

于是我想着,既然上面方式行不通,换种方式


IntPtr hwndExcel = new IntPtr(_excel.Hwnd);

Process[] localByName = Process.GetProcessesByName("excel");
foreach (Process p in localByName)
{
//这里可以获取到进程名称为Excel的进程。
//但是我如何转换成Excel Application,
//也就是说我要如何才能知道该进程其实对应加载的是哪个.xls文件

}



baidu google,搜了很久,都没有一个能解决。
麻烦大家有试过可以成功的,再贴出来。
谢谢!
...全文
200 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
hou3125378 2016-01-21
  • 打赏
  • 举报
回复
现在我也用到这个问题,在IIS中调试的时候发现GetWindowThreadProcessId 捕获的进程id 始终是0,现在不知道怎么搞了
  • 打赏
  • 举报
回复
引用 楼主 ufo20020427 的回复:
用微软自带Interop.Excel的操作,大家都知道即使关闭了,.......
谁知道你是怎样关闭的?
ufo20020427 2014-07-24
  • 打赏
  • 举报
回复
@liuchaolin 不过,我试着把 GC.Collect();放在excel操作类的dispose()之外了,为何仍得开个Thread才能释放?
ufo20020427 2014-07-24
  • 打赏
  • 举报
回复
@liuchaolin 我明白了,之前我是放在Excel操作类中去调用GC,而Excel操作类还没null,所有没效。
ufo20020427 2014-07-24
  • 打赏
  • 举报
回复
@liuchaolin 用了Thread调用GC,测试,好像是可以,为什么不用Thread就没效?
md5e 2014-07-24
  • 打赏
  • 举报
回复
引用 6 楼 ufo20020427 的回复:
@liuchaolin 用gc等之前我有试过,有时成功,有时不成功 我还是倾向于使用杀进程的方式。
你是否是用线程来调用呢? GC需要另开线程来使用
ufo20020427 2014-07-24
  • 打赏
  • 举报
回复
@Z65443344 是的,服务器上运行的_excel = new Application();, 打印 需要调用到 public void Print(Worksheet sheet, int zoom, XlPaperSize paperSize) { sheet.PageSetup.Zoom = zoom; sheet.PageSetup.Orientation = XlPageOrientation.xlLandscape; sheet.PageSetup.PaperSize = paperSize; sheet.PrintOut(Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); }
於黾 2014-07-24
  • 打赏
  • 举报
回复
你的EXCEL还要自动打印? 不行自己做打印功能算了,依赖EXCEL的打印,问题还是挺多的.
於黾 2014-07-24
  • 打赏
  • 举报
回复
我明白你的意思了,服务器上不止一个程序在调用EXCEL是吧... 这就难办了. p.MainWindowTitle在用户打开的EXCEL里应该是文件名 不过服务器上运行,当然都是空
ufo20020427 2014-07-24
  • 打赏
  • 举报
回复
@Z65443344 由于 Process.GetProcessesByName("EXCEL") 获取到的不只一个excel(我不能都杀了,有些是别的程序用到的excel)。 另外,p.MainWindowTitle总是为empty
於黾 2014-07-24
  • 打赏
  • 举报
回复
如果你是在服务器上运行,正常是没有用户去操作EXCEL的, 你可以不管EXCEL到底谁打开的,见到了就杀死.
於黾 2014-07-24
  • 打赏
  • 举报
回复
如果就是想用kill,应该这样用: foreach(Process p in Process.GetProcessesByName("EXCEL")) { if(string.IsNullOrEmpty(p.MainWindowTitle)) { p.Kill(); } } 意思就是,判断一下打开的文件窗口名称是否为空,程序打开的只在进程中有,没有窗口,所以名称为空.
ufo20020427 2014-07-24
  • 打赏
  • 举报
回复
@liuchaolin 用gc等之前我有试过,有时成功,有时不成功 我还是倾向于使用杀进程的方式。
ufo20020427 2014-07-24
  • 打赏
  • 举报
回复
@yaotomo 我是怀疑iis运行时的权限问题,如果以上代码放在控制台(Console),而不是web,则能正常的获取到processId的。
md5e 2014-07-24
  • 打赏
  • 举报
回复
参考这个的用法,要在线程进使用

<%@ WebHandler Language="C#" Class="ajaxWordToHtml" %>

using System;
using System.Web;
using System.Threading;


public class ajaxWordToHtml : IHttpHandler
{

    private static object _lock = new object();
    string docPath = string.Empty;
    string htmlPath = string.Empty;
    bool Flang = false;
    string Message = string.Empty;

    [STAThread]
    private void _Import()
    {



        object o = Type.Missing;

        try
        {

            Word.Application app = new Word.Application();
            app.Visible = false;


            object docFile = docPath;
            object readOnly = true;
            object fileName = htmlPath;


            /*office 2003 begin
            Word.Document doc = app.Documents.Open(ref docFile, ref o, ref readOnly, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o);
            object format = Word.WdSaveFormat.wdFormatFilteredHTML;
            doc.SaveAs(ref fileName, ref format, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o);
            //office 2003 end*/

            //* offic 2000 begin


            Word.Document doc = app.Documents.Open(ref docFile, ref o, ref readOnly, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o);
            object format = Word.WdSaveFormat.wdFormatHTML;
            doc.SaveAs(ref fileName, ref format, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o);
            doc.Close(ref o, ref o, ref o);
            app.Quit(ref o, ref o, ref o);

            //*/

            //WordToHtml.ConvertToHtml(docPath, htmlPath);
            Flang = true;
            Message = "已成功生成!";
            return;
        }
        catch (Exception error)
        {
            Flang = false;
            Message = error.Message;
            return;
        }
        finally
        {
            GC.Collect();
        }
    }

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/html";
        docPath = HttpContext.Current.Request["docPath"];
        htmlPath = HttpContext.Current.Request["htmlPath"];
        if (!string.IsNullOrEmpty(docPath) && !string.IsNullOrEmpty(htmlPath))
        {
            lock (_lock)
            {


                docPath = HttpContext.Current.Server.MapPath("/docfile/" + docPath);
                htmlPath = HttpContext.Current.Server.MapPath("/htmlfile/" + htmlPath);
             Thread _thread = new Thread(new ThreadStart(_Import));
              _thread.Name = "ajaxWordToHtml";
              _thread.SetApartmentState(ApartmentState.STA);
              _thread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
              _thread.Start();
              TimeSpan ts = new TimeSpan(0, 0, 0, 30);
              _thread.Join();
              context.Response.Write(Flang);
              context.Response.Write(Message);
            }
        }
        else
        {
            Flang = false;
            Message = "提交的参数不正确";
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}
yaotomo 2014-07-24
  • 打赏
  • 举报
回复
mark一下,这个问题也困扰我好久了。每次服务器上的进程都关不干净。。 所以我一般都不使用微软自带的这个组件。
ufo20020427 2014-07-24
  • 打赏
  • 举报
回复
NPOI好像不能实现打印,我这里需要用到打印。 而且如何更改,需要涉及的地方太多。
於黾 2014-07-24
  • 打赏
  • 举报
回复
改用NPOI吧,前几天有吧友放出了源码,下载一个. 这样服务器上不用安装OFFICE,程序不依赖OFFICE版本,也不开启EXCEL进程
Re: 《Linux 进程管理命令》   ---------------------------------------内容提要: 01/15)命令 ps         :查看进程(快照)02/15)命令 pstree   :显示进程状态树03/15)命令 pgrep   :查找匹配条件的进程04/15)命令 kill        :终止进程号(1277)05/15)命令 killall    :通过进程名(nginx)终止进程(父/子进程)06/15)命令 pkill      :通过进程名终止进程(通杀)/终止客户端(pst/tty)07/15)命令 top       :实时显示系统中各个进程的资源占用状况(录像)08/15)命令 nice      :调整程序运行时的优先级09/15)命令 renice   :调整运行中的进程的优先级10/15)命令 nohup  :用户退出系统,进程继续工作11/15)命令 strace   :跟踪进程的系统调用12/15)命令 ltrace    :跟踪进程调用库函数13/15)命令 runlevel:输出当前运行级别14/15)命令 init        :初始化 Linux 进程15/15)命令 service  :管理系统服务  本人在教学和实战过程中发现,即便是有一定运维经验的人,可能已经能够搭建一定复杂度的Linux架构,但是在来来回回的具体操作中,还是体现出CLI(命令界面)功底不够扎实,甚至操作的非常‘拙’、处处露‘怯’。 对一个士兵来说,枪就是他的武器,对于一个程序员来说,各种library(工具库)就是他的武器;而对于Linux运维人员来说,无疑命令行工具CLI(命令界面)就是他们的武器;高手和小白之间的差距往往就体现在对于这些“武器”的掌握和熟练程度上。有时候一个参数就能够解决的事情,小白们可能要写一个复杂的Shell脚本才能搞定,这就是对CLI(命令界面)没有理解参悟透彻导致。 研磨每一个命令就是擦拭手中的作战武器,平时不保养不理解,等到作战的时候,一定不能够将手中的武器发挥到最好,所以我们要平心、静气和专注,甘坐冷板凳一段时间,才能练就一身非凡的内功! 本教程从实战出发,结合当下流行或最新的Linux(v6/7/8 版本)同时演示,将命令行结合到解决企业实战问题中来,体现出教学注重实战的务实精神,希望从事或未来从事运维的同学,能够认真仔细的学完Linux核心命令的整套课程。 本课程系列将逐步推出,看看我教学的进度和您学习的步伐,孰占鳌头! 注:关于教学环境搭建,可以参考本人其它课程系列,本教学中就不再赘述! 《参透 VMware 桌面级虚拟化》 《在虚拟机中安装模版机(包括应用软件等)》 《SecureCRT 连接 GNS3/Linux 的安全精密工具》

110,545

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧