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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
69
0
164 271
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Ответ принят как подходящий

Вы захотите использовать метод 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) - на самом деле убийство процесс - ужасная идея и будет создавать проблемы только в долгосрочной перспективе. Процессы всегда должны быть закрыто, а не уничтожены, чтобы они могли завершиться должным образом. Этот ответ - типичная ошибка новичков.

specializt 07.12.2018 14:45

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

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

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

Один комментарий - используйте winword вместо winword.exe.

Rami 22.09.2008 21:04

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

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

Я не нахожу процессы, когда для GetProcessesByName задан .exe, хотя winword работает нормально.

Blair Conrad 22.09.2008 21:14

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

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

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

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

Я согласен с таким подходом. Завершение процесса должно быть крайней мерой. Могут быть непредвиденные последствия.

Nathan 12.03.2020 17:18

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

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

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

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

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

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

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

В моем приложении на панели задач мне нужно было очистить 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" }));

что вообще должно означать clean Excel and Word Interops?

specializt 07.12.2018 14:53

как и в случае с очисткой, если бы я не использовал этот процесс, у меня были бы сотни экземпляров word и excel, что в конечном итоге привело бы к зависанию моей машины.

tyler_mitchell 10.12.2018 14:04

убийство живых процессов также может привести к зависанию вашей машины - и вы можете потерять важные данные и вы можете полностью испортить установку, вынудив пользователя восстановить или переустановить. Итак, подведем итог: ваш алгоритм чистый фактически уничтожит систему в один прекрасный день; следует быть очень осторожным с управлением процессами, особенно, если речь идет о процессах Microsoft, потому что они тесно связаны с ОС и вызывают массу проблем, если с ними не обращаться осторожно. Но в настоящее время Microsoft извлекла уроки из их ошибок и защищает их от саботажа.

specializt 10.12.2018 18:58

так что ... на этот раз тебе повезло. Но, пожалуйста, извлеките урок из ошибки ваш и перестаньте убивать процессы. Взгляните на CloseMainWindow. Я просто надеюсь, что они когда-нибудь начнут отказываться от вредоносного API, подобного этому, это явно на уровне ядра и не должно быть возможным для любого приложения пользовательского пространства.

specializt 10.12.2018 19:01

вы используете очень маленький фрагмент кода без контекста того, как он используется ...

tyler_mitchell 11.12.2018 20:28

это ... наглая ложь

specializt 23.12.2018 10:33

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

Другие вопросы по теме