program tip

Vb.NET 또는 C #을 사용하여 프로세스를 어떻게 종료합니까?

radiobox 2020. 11. 1. 17:31
반응형

Vb.NET 또는 C #을 사용하여 프로세스를 어떻게 종료합니까?


사용자가 이미 Microsoft Word를 열 었는지 확인해야하는 시나리오가 있습니다. 그가 있다면, 나는 winword.exe 프로세스를 죽이고 내 코드를 계속 실행해야한다.

누구든지 vb.net 또는 C #을 사용하여 프로세스를 종료하기위한 간단한 코드가 있습니까?


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프로세스가 원격임을 암시하는 을 처리 할 필요가 없을 것입니다 .


Word 프로세스를 완전히 죽이는 것도 가능하지만 (다른 응답 중 일부 참조) 완전히 무례하고 위험합니다. 사용자가 열려있는 문서에 저장되지 않은 중요한 변경 사항이 있으면 어떻게합니까? 이로 인해 남겨질 오래된 임시 파일은 말할 것도 없습니다.

이것은 아마도 이와 관련하여 (VB.NET) 갈 수있는 한 멀리 있습니다.

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

이렇게하면 열려있는 모든 Word 창이 질서 정연하게 닫힙니다 (해당되는 경우 사용자에게 작업 내용을 저장하라는 메시지가 표시됨). 물론이 시나리오에서는 사용자가 항상 '취소'를 클릭 할 수 있으므로이 경우도 처리 할 수 ​​있어야합니다 (바람직하게는 "모든 Word 인스턴스를 닫으십시오. 그렇지 않으면 계속할 수 없습니다"대화 상자를 표시하여 ... )


다음은 모든 워드 프로세스를 종료하는 방법에 대한 쉬운 예입니다.

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

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

보안 문제를 우회하고 Word 프로세스가 실행 중인지 확인하고 사용자에게 닫으라고 요청한 다음 앱에서 '계속'버튼을 클릭하여 많은 응용 프로그램을 만들 수 있습니다. 이것은 많은 설치자가 취하는 접근 방식입니다.

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

물론 앱에 GUI가있는 경우에만이 작업을 수행 할 수 있습니다.


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

트레이 앱에서 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" }));

다음과 같이 작동합니다.

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

프로세스가 실행 중인지 감지하고 사용자에게 수동으로 닫으라고 지시하는 것이 더 낫고, 더 안전하고, 정중합니다. 물론 시간 초과를 추가하고 프로세스가 사라지면 종료 할 수도 있습니다.


아래 예를 참조하십시오

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

참고 URL : https://stackoverflow.com/questions/116090/how-do-i-kill-a-process-using-vb-net-or-c

반응형