Question

J'ai un scénario dans lequel je dois vérifier si l'utilisateur a déjà ouvert Microsoft Word. S'il l'a fait, je dois alors arrêter le processus winword.exe et continuer à exécuter mon code.

Quelqu'un a-t-il un code simple pour tuer un processus en utilisant vb.net ou c #?

Était-ce utile?

La solution

Vous voudrez utiliser le System.Diagnostics Méthode .Process.Kill . Vous pouvez obtenir le processus que vous voulez en utilisant System.Diagnostics.Proccess.GetProcessesByName . / p>

Des exemples ont déjà été postés ici, mais j’ai constaté que la version non-.exe fonctionnait mieux. Quelque chose comme:

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

Vous n'avez probablement pas à traiter avec NotSupportedException , ce qui suggère que le processus est distant.

Autres conseils

Tuer le processus Word est tout à fait possible (voir certaines des autres réponses), mais carrément grossier et dangereux: que se passera-t-il si l'utilisateur a d'importantes modifications non enregistrées dans un document ouvert? Sans parler des fichiers temporaires obsolètes que cela laissera derrière vous ...

C’est probablement aussi loin que vous pouvez aller à cet égard (VB.NET):

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

Ceci fermera toutes les fenêtres Word ouvertes de manière ordonnée (invitant l'utilisateur à enregistrer son travail le cas échéant). Bien entendu, l'utilisateur peut toujours cliquer sur "Annuler" dans ce scénario. Vous devriez donc pouvoir également gérer ce cas (de préférence en plaçant un dialogue "fermez toutes les instances de Word, sinon nous ne pourrons pas continuer"). .)

Voici un exemple simple sur la manière de tuer tous les processus de traitement de texte.

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

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

Vous pouvez contourner les problèmes de sécurité et créer une application beaucoup plus polie en vérifiant simplement si le processus Word est en cours d'exécution et en demandant à l'utilisateur de le fermer, puis cliquez sur un bouton "Continuer" dans votre application. C’est l’approche adoptée par de nombreux installateurs.

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

Bien sûr, vous ne pouvez le faire que si votre application dispose d'une interface graphique

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

Dans mon application Plateau, je devais nettoyer Excel et Word Interops. Donc, cette méthode simple tue les processus de manière générique.

Ceci utilise un gestionnaire d'exception général, mais peut être facilement fractionné pour plusieurs exceptions, comme indiqué dans d'autres réponses. Je peux le faire si mon enregistrement produit beaucoup de faux positifs (c’est-à-dire que je ne peux pas tuer déjà tué). Mais jusqu'ici, alors guid (blague de travail).

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

Voici comment je l'ai appelé alors:

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

Quelque chose comme ça va marcher:

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

Il est préférable, plus sûr et plus poli, de détecter si le processus est en cours d'exécution et d'indiquer à l'utilisateur de le fermer manuellement. Bien sûr, vous pouvez également ajouter un délai d’attente et mettre fin au processus s’ils sont partis ...

Veuillez voir l'exemple ci-dessous

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;
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top