请教如何根据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,搜了很久,都没有一个能解决。
麻烦大家有试过可以成功的,再贴出来。
谢谢!
...全文
209 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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进程

111,098

社区成员

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

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

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