Как убить процесс с помощью Vb.NET или C #?

У меня есть сценарий, в котором я должен проверить, открыл ли пользователь Microsoft Word. Если да, то я должен убить процесс winword.exe и продолжить выполнение своего кода.

Есть ли у кого-нибудь простой код для убийства процесса с помощью vb.net или С #?


person bugBurger    schedule 22.09.2008    source источник


Ответы (9)


Вы захотите использовать System.Diagnostics.Process. Убить. Вы можете получить нужный процесс с помощью 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, что говорит о том, что процесс является удаленным.

person Blair Conrad    schedule 22.09.2008
comment
он также не будет работать во многих других случаях (если процесс, например, экранировал себя ACL) - на самом деле уничтожение процесса - ужасная идея и будет только генерировать проблемы в долгосрочной перспективе. Процессы всегда должны быть закрыты, а не остановлены, чтобы они могли завершиться должным образом. Этот ответ - типичная ошибка новичков. - person specializt; 07.12.2018

Полное уничтожение процесса Word возможно (см. Некоторые другие ответы), но совершенно грубо и опасно: что, если у пользователя есть важные несохраненные изменения в открытом документе? Не говоря уже об устаревших временных файлах, которые останутся после ...

Это, вероятно, все, что вы можете сделать в этом отношении (VB.NET):

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

Это закроет все открытые окна Word упорядоченным образом (предлагая пользователю сохранить свою работу, если применимо). Конечно, в этом сценарии пользователь всегда может щелкнуть «Отмена», так что вы сможете справиться и с этим случаем (желательно, открыв диалоговое окно «Пожалуйста, закройте все экземпляры Word, иначе мы не сможем продолжить» ... )

person mdb    schedule 22.09.2008
comment
Я согласен с таким подходом. Завершение процесса должно быть крайней мерой. Могут быть непредвиденные последствия. - person Nathan; 12.03.2020

Вот простой пример того, как убить все процессы Word.

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

foreach (Process proc in procs)
    proc.Kill();
person Nick Berardi    schedule 22.09.2008
comment
Один комментарий - используйте winword вместо winword.exe - person Rami; 22.09.2008

Вы можете обойти проблемы безопасности и создать более вежливое приложение, просто проверив, запущен ли процесс Word, попросив пользователя закрыть его, а затем щелкнув кнопку «Продолжить» в своем приложении. Такой подход используют многие установщики.

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

Конечно, вы можете сделать это только в том случае, если ваше приложение имеет графический интерфейс.

person Chris Lawlor    schedule 25.09.2008

В моем приложении на панели задач мне нужно было очистить Excel и Word Interops. Итак, этот простой метод в целом убивает процессы.

Здесь используется общий обработчик исключений, но его можно легко разделить на несколько исключений, как указано в других ответах. Я могу сделать это, если мой журнал дает много ложных срабатываний (т.е. не могу убить уже убитых). Но пока что руководство (шутка о работе).

/// <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" }));
person tyler_mitchell    schedule 08.12.2016
comment
что clean Excel and Word Interops вообще должно означать? - person specializt; 07.12.2018
comment
как и в случае с очисткой, если бы я не использовал этот процесс, у меня были бы сотни экземпляров word и excel, которые в конечном итоге повесили бы мою машину. - person tyler_mitchell; 10.12.2018
comment
завершение работы живых процессов также может привести к зависанию вашего компьютера - и вы можете потерять важные данные и вы можете полностью испортить установку, вынудив пользователя восстановить или переустановить. Итак, подведем итог: ваш чистый алгоритм на самом деле в один прекрасный день в значительной степени разрушит систему; нужно быть очень осторожным в управлении процессами, особенно, если речь идет о процессах Microsoft, потому что они тесно связаны с ОС и вызывают массу проблем, если с ними не обращаться осторожно. Но в настоящее время Microsoft извлекла уроки из их ошибок и защищает их от саботажа. - person specializt; 10.12.2018
comment
так что ... на этот раз тебе повезло. Но, пожалуйста, извлеките урок из своей ошибки и прекратите убивать процессы. Взгляните на CloseMainWindow. Я просто надеюсь, что они когда-нибудь начнут отказываться от вредоносного API, подобного этому, это явно на уровне ядра и не должно быть возможным для любого приложения в пользовательском пространстве. - person specializt; 10.12.2018
comment
вы используете очень маленький фрагмент кода без контекста того, как он используется ... - person tyler_mitchell; 11.12.2018
comment
это ... наглая ложь - person specializt; 23.12.2018

Примерно так будет работать:

foreach ( Process process in Process.GetProcessesByName( "winword" ) )
{
    process.Kill();
    process.WaitForExit();
}
person Tomer Gabel    schedule 22.09.2008
comment
Я не нахожу процессы, когда для GetProcessesByName передан .exe, хотя winword работает нормально. - person Blair Conrad; 22.09.2008

Лучше, безопаснее и вежливее определить, запущен ли процесс, и попросить пользователя закрыть его вручную. Конечно, вы также можете добавить тайм-аут и убить процесс, если они ушли ...

person MrVB.NET    schedule 21.11.2013

Я открыл один файл Word, 2. Теперь я программно открываю другой файл Word через среду выполнения vb.net. 3. Я хочу убить второй процесс в одиночку программно. 4. Не убивайте первый процесс

person ha a    schedule 17.06.2020

См. Пример ниже

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;
    }
person Ashok    schedule 25.03.2015