Frage

Ich habe ein Szenario, in dem ich habe zu prüfen, ob Benutzer Microsoft Word bereits geöffnet haben. Wenn er hat, dann muß ich den winword.exe Prozess töten und weiterhin meinen Code auszuführen.

Hat jemand irgendeine Straight-Forward-Code für das Töten eines Prozesses vb.net oder c #?

War es hilfreich?

Lösung

Sie wollen die System.Diagnostics .Process.Kill Methode. Sie können den Vorgang erhalten Sie wollen mit System.Diagnostics.Proccess.GetProcessesByName .

Beispiele werden bereits hier gepostet, aber ich fand, dass die Nicht-Exe-Version besser gearbeitet, so etwas wie:

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

Sie wahrscheinlich müssen nicht mit NotSupportedException befassen, was darauf hindeutet, dass der Prozess entfernt ist.

Andere Tipps

das Wort Prozess Töten geradezu möglich ist (einige der anderen Antworten sehen), aber geradezu unhöflich und gefährlich: Was, wenn der Benutzer wichtige gespeicherte Änderungen in einem geöffneten Dokument hat? Nicht zu vergessen die veraltete temporäre Dateien dies hinter sich lassen ...

Dies ist wahrscheinlich so weit wie Sie in dieser Hinsicht (VB.NET) gehen können:

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

Damit werden alle geöffneten Word-Fenster in einer geordneten Art und Weise (den Benutzer auffordert, seine / ihre Arbeit ggf. speichern) schließen. Natürlich kann der Benutzer immer in diesem Szenario klicken Sie auf ‚Abbrechen‘, so sollten Sie einen „Bitte schließen Sie alle Word-Instanzen, sonst können wir nicht weiter“, indem sie auf diesen Fall als gut (vorzugsweise zu handhaben können, Dialog ... )

Hier ist ein einfaches Beispiel dafür, wie alle Word-Prozesse zu töten.

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

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

Sie können die Sicherheitsbedenken umgehen, und erstellen Sie eine viel höflicher Anwendung durch einfaches Prüfen, ob die Word-Prozess ausgeführt wird, und bittet den Benutzer um es zu schließen, und klicken Sie auf eine Schaltfläche ‚Weiter‘ in Ihrer Anwendung. Dies ist der Ansatz von vielen Installateuren gemacht.

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

Natürlich können Sie dies nur tun, wenn Ihre Anwendung hat eine grafische Benutzeroberfläche

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

In meinem Fach app, brauchte ich Excel und Word Interops zu reinigen. So Diese einfache Methode tötet allgemein Prozesse.

Dieser verwendet einen allgemeinen Exception-Handler, aber leicht für mehrere Ausnahmen wie in anderen Antworten erwähnt geteilt werden könnte. Ich kann dies tun, wenn die Protokollierung einer Menge Fehlalarme produziert (dh nicht töten kann bereits getötet). Aber so weit, so guid (Arbeitswitz).

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

Das ist, wie ich nannte es dann:

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

So etwas wie dies funktioniert:

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

Es ist besser, Praxis, sicherer und höflich zu erkennen, ob der Prozess ausgeführt wird und sagen Sie dem Benutzer manuell zu schließen. Natürlich können Sie auch einen Timeout hinzufügen und den Prozess töten, wenn sie weg gegangen sind ...

Bitte beachten Sie das folgende Beispiel

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;
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top