【问题标题】:How do I kill a process using Vb.NET or C#?如何使用 Vb.NET 或 C# 终止进程?
【发布时间】:2010-09-12 01:54:27
【问题描述】:

我有一个场景,我必须检查用户是否已经打开了 Microsoft Word。如果他有,那么我必须杀死 winword.exe 进程并继续执行我的代码。

有没有人有任何使用 vb.net 或 c# 杀死进程的直接代码?

【问题讨论】:

    标签: c# vb.net process kill


    【解决方案1】:

    您需要使用System.Diagnostics.Process.Kill 方法。您可以获得您想要使用的过程 System.Diagnostics.Proccess.GetProcessesByName.

    这里已经发布了示例,但我发现非 .exe 版本效果更好,所以类似:

    foreach ( Process p in System.Diagnostics.Process.GetProcessesByName("winword") )
    {
        try
        {
            p.Kill();
            p.WaitForExit(); // possibly with a timeout
        }
        catch ( Win32Exception winException )
        {
            // process was terminating or can't be terminated - deal with it
        }
        catch ( InvalidOperationException invalidException )
        {
            // process has already exited - might be able to let this one go
         }
    }
    

    您可能不必处理NotSupportedException,这表明该进程是远程的。

    【讨论】:

    • 它在许多其他情况下也不起作用(例如,如果进程已使用 ACL 保护自己) - 实际上是 杀死 一个进程这是一个可怕的想法,从长远来看只会产生问题。进程应始终关闭而不是终止,以便它们可以正常关闭。这个答案是典型的初学者错误。
    【解决方案2】:

    彻底终止 Word 进程是可能的(请参阅其他一些回复),但完全粗鲁和危险:如果用户在打开的文档中有重要的未保存更改怎么办?更不用说这会留下陈旧的临时文件......

    这可能是您在这方面所能做到的(VB.NET):

        Dim proc = Process.GetProcessesByName("winword")
        For i As Integer = 0 To proc.Count - 1
            proc(i).CloseMainWindow()
        Next i
    

    这将有序地关闭所有打开的 Word 窗口(如果适用,提示用户保存他/她的工作)。当然,在这种情况下,用户始终可以单击“取消”,因此您也应该能够处理这种情况(最好是通过设置“请关闭所有 Word 实例,否则我们无法继续”对话框... )

    【讨论】:

    • 我同意这种做法。杀死一个进程应该是最后可能的手段。可能会产生意想不到的后果。
    【解决方案3】:

    这是一个简单的示例,说明如何杀死所有文字进程。

    Process[] procs = Process.GetProcessesByName("winword");
    
    foreach (Process proc in procs)
        proc.Kill();
    

    【讨论】:

    • 一条评论 - 使用“winword”而不是“winword.exe”
    【解决方案4】:

    您可以绕过安全问题,创建一个更礼貌的应用程序,只需检查 Word 进程是否正在运行,并要求用户关闭它,然后单击应用程序中的“继续”按钮。这是许多安装人员采用的方法。

    private bool isWordRunning() 
    {
        return System.Diagnostics.Process.GetProcessesByName("winword").Length > 0;
    }
    

    当然,只有当您的应用具有 GUI 时,您才能这样做

    【讨论】:

      【解决方案5】:
          public bool FindAndKillProcess(string name)
          {
              //here we're going to get a list of all running processes on
              //the computer
              foreach (Process clsProcess in Process.GetProcesses()) {
                  //now we're going to see if any of the running processes
                  //match the currently running processes by using the StartsWith Method,
                  //this prevents us from incluing the .EXE for the process we're looking for.
                  //. Be sure to not
                  //add the .exe to the name you provide, i.e: NOTEPAD,
                  //not NOTEPAD.EXE or false is always returned even if
                  //notepad is running
                  if (clsProcess.ProcessName.StartsWith(name))
                  {
                      //since we found the proccess we now need to use the
                      //Kill Method to kill the process. Remember, if you have
                      //the process running more than once, say IE open 4
                      //times the loop thr way it is now will close all 4,
                      //if you want it to just close the first one it finds
                      //then add a return; after the Kill
                      try 
                      {
                          clsProcess.Kill();
                      }
                      catch
                      {
                          return false;
                      }
                      //process killed, return true
                      return true;
                  }
              }
              //process not found, return false
              return false;
          }
      

      【讨论】:

        【解决方案6】:

        在我的托盘应用程序中,我需要清理 Excel 和 Word 互操作。所以这个简单的方法一般会杀死进程。

        这使用通用异常处理程序,但可以轻松拆分为多个异常,如其他答案中所述。如果我的日志记录产生很多误报(即不能杀死已经杀死的),我可能会这样做。但到目前为止,指导(工作笑话)。

        /// <summary>
        /// Kills Processes By Name
        /// </summary>
        /// <param name="names">List of Process Names</param>
        private void killProcesses(List<string> names)
        {
            var processes = new List<Process>();
            foreach (var name in names)
                processes.AddRange(Process.GetProcessesByName(name).ToList());
            foreach (Process p in processes)
            {
                try
                {
                    p.Kill();
                    p.WaitForExit();
                }
                catch (Exception ex)
                {
                    // Logging
                    RunProcess.insertFeedback("Clean Processes Failed", ex);
                }
            }
        }
        

        这就是我当时的称呼:

        killProcesses((new List<string>() { "winword", "excel" }));
        

        【讨论】:

        • clean Excel and Word Interops 是什么意思?
        • 在清理过程中,如果我不使用这个过程,我会有数百个 word 和 excel 实例,最终会挂掉我的机器。
        • 杀死实时进程也可能使您的机器挂起 - 并且您可能会丢失重要数据并且您可能会完全破坏安装,迫使用户装修或重新安装。所以,总结一下:你的 clean 算法实际上会在一个闪亮的日子里摧毁系统;人们应该非常小心进程控制,尤其是如果涉及到 microsoft 进程,因为这些进程紧密地编织到操作系统中,如果不小心处理会导致一大堆问题。但如今,微软已经从他们的错误中吸取了教训,并保护他们免受破坏。
        • 所以……这次你走运了。但是请从你的错误中吸取教训并停止杀死进程。看看CloseMainWindow。我只是希望他们有一天会开始弃用像这样的有害 API,这显然是内核级别的,任何用户空间应用程序都不应该这样做
        • 您使用非常小的 sn-p 代码,没有关于其使用方式的上下文......
        【解决方案7】:

        这样的事情会起作用:

        foreach ( Process process in Process.GetProcessesByName( "winword" ) )
        {
            process.Kill();
            process.WaitForExit();
        }
        

        【讨论】:

        • 当有一个 .exe 给 GetProcessesByName 时,我找不到进程,尽管 winword 工作正常。
        【解决方案8】:

        检测进程是否正在运行并告诉用户手动关闭它会更好,更安全,更礼貌。当然,如果它们消失了,您也可以添加超时并终止进程...

        【讨论】:

          【解决方案9】:

          我打开了一个Word文件, 2. 现在我以编程方式通过 vb.net 运行时打开另一个 word 文件。 3.我想通过编程方式单独杀死第二个进程。 4. 不要杀死第一个进程

          【讨论】:

            【解决方案10】:

            请看下面的例子

            public partial class Form1 : Form
            {
                [ThreadStatic()]
                static Microsoft.Office.Interop.Word.Application wordObj = null;
            
                public Form1()
                {
                    InitializeComponent();
                }
            
                public bool OpenDoc(string documentName)
                {
                    bool bSuccss = false;
                    System.Threading.Thread newThread;
                    int iRetryCount;
                    int iWait;
                    int pid = 0;
                    int iMaxRetry = 3;
            
                    try
                    {
                        iRetryCount = 1;
            
                    TRY_OPEN_DOCUMENT:
                        iWait = 0;
                        newThread = new Thread(() => OpenDocument(documentName, pid));
                        newThread.Start();
            
                    WAIT_FOR_WORD:
                        Thread.Sleep(1000);
                        iWait = iWait + 1;
            
                        if (iWait < 60) //1 minute wait
                            goto WAIT_FOR_WORD;
                        else
                        {
                            iRetryCount = iRetryCount + 1;
                            newThread.Abort();
            
                            //'-----------------------------------------
                            //'killing unresponsive word instance
                            if ((wordObj != null))
                            {
                                try
                                {
                                    Process.GetProcessById(pid).Kill();
                                    Marshal.ReleaseComObject(wordObj);
                                    wordObj = null;
                                }
                                catch (Exception ex)
                                {
                                }
                            }
            
                            //'----------------------------------------
                            if (iMaxRetry >= iRetryCount)
                                goto TRY_OPEN_DOCUMENT;
                            else
                                goto WORD_SUCCESS;
                        }
                    }
                    catch (Exception ex)
                    {
                        bSuccss = false;
                    }
                WORD_SUCCESS:
            
                    return bSuccss;
                }
            
                private bool OpenDocument(string docName, int pid)
                {
                    bool bSuccess = false;
                    Microsoft.Office.Interop.Word.Application tWord;
                    DateTime sTime;
                    DateTime eTime;
            
                    try
                    {
                        tWord = new Microsoft.Office.Interop.Word.Application();
                        sTime = DateTime.Now;
                        wordObj = new Microsoft.Office.Interop.Word.Application();
                        eTime = DateTime.Now;
                        tWord.Quit(false);
                        Marshal.ReleaseComObject(tWord);
                        tWord = null;
                        wordObj.Visible = false;
                        pid = GETPID(sTime, eTime);
            
                        //now do stuff
                        wordObj.Documents.OpenNoRepairDialog(docName);
                        //other code
            
                        if (wordObj != null)
                        {
                            wordObj.Quit(false);
                            Marshal.ReleaseComObject(wordObj);
                            wordObj = null;
                        }
                        bSuccess = true;
                    }
                    catch
                    { }
            
                    return bSuccess;
                }
            
                private int GETPID(System.DateTime startTime, System.DateTime endTime)
                {
                    int pid = 0;
            
                    try
                    {
                        foreach (Process p in Process.GetProcessesByName("WINWORD"))
                        {
                            if (string.IsNullOrEmpty(string.Empty + p.MainWindowTitle) & p.HasExited == false && (p.StartTime.Ticks >= startTime.Ticks & p.StartTime.Ticks <= endTime.Ticks))
                            {
                                pid = p.Id;
                                break;
                            }
                        }
                    }
                    catch
                    {
                    }
                    return pid;
                }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-01-15
              • 2010-10-27
              • 1970-01-01
              • 2016-09-16
              • 1970-01-01
              • 2012-04-06
              • 1970-01-01
              相关资源
              最近更新 更多