如何使用 Vb.NET 或 C# 终止进程?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/116090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 14:27:47  来源:igfitidea点击:

How do I kill a process using Vb.NET or C#?

提问by bugBurger

I have a scenario where I have to check whether user has already opened Microsoft Word. If he has, then I have to kill the winword.exe process and continue to execute my code.

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

Does any one have any straight-forward code for killing a process using vb.net or c#?

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

采纳答案by Blair Conrad

You'll want to use the System.Diagnostics.Process.Killmethod. You can obtain the process you want using System.Diagnostics.Proccess.GetProcessesByName.

您需要使用System.Diagnostics.Process.Kill方法。您可以使用System.Diagnostics.Proccess.GetProcessesByName获取所需的进程 。

Examples have already been posted here, but I found that the non-.exe version worked better, so something like:

示例已经在此处发布,但我发现非 .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
     }
}

You probably don't have to deal with NotSupportedException, which suggests that the process is remote.

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

回答by Nick Berardi

Here is an easy example of how to kill all Word Processes.

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

Process[] procs = Process.GetProcessesByName("winword");

foreach (Process proc in procs)
    proc.Kill();

回答by Tomer Gabel

Something like this will work:

像这样的事情会起作用:

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

回答by mdb

Killing the Word process outright is possible (see some of the other replies), but outright rude and dangerous: what if the user has important unsaved changes in an open document? Not to mention the stale temporary files this will leave behind...

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

This is probably as far as you can go in this regard (VB.NET):

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

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

This will close all open Word windows in an orderly fashion (prompting the user to save his/her work if applicable). Of course, the user can always click 'Cancel' in this scenario, so you should be able to handle this case as well (preferably by putting up a "please close all Word instances, otherwise we can't continue" dialog...)

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

回答by Chris Lawlor

You can bypass the security concerns, and create a much politer application by simply checking if the Word process is running, and asking the user to close it, then click a 'Continue' button in your app. This is the approach taken by many installers.

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

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

Of course, you can only do this if your app has a GUI

当然,只有在您的应用程序具有 GUI 时才能执行此操作

回答by Vova Popov

    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;
    }

回答by MrVB.NET

It's better practise, safer and more polite to detect if the process is running and tell the user to close it manually. Of course you could also add a timeout and kill the process if they've gone away...

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

回答by Ashok

Please see the example below

请看下面的例子

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;
    }

回答by tyler_mitchell

In my tray app, I needed to clean Excel and Word Interops. So This simple method kills processes generically.

在我的托盘应用程序中,我需要清理 Excel 和 Word Interops。所以这个简单的方法通常会杀死进程。

This uses a general exception handler, but could be easily split for multiple exceptions like stated in other answers. I may do this if my logging produces alot of false positives (ie can't kill already killed). But so far so guid (work joke).

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

/// <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);
        }
    }
}

This is how i called it then:

我当时是这样称呼它的:

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