72

I have a scenario where I have to check whether user has already opened Microsoft Word. If he has, then I have to kill the winword.exe process and continue to execute my code.

Does any one have any straight-forward code for killing a process using vb.net or c#?

Mark Biek
  • 146,731
  • 54
  • 156
  • 201
bugBurger
  • 6,950
  • 9
  • 32
  • 39

10 Answers10

98

You'll want to use the System.Diagnostics.Process.Kill method. You can obtain the process you want using System.Diagnostics.Proccess.GetProcessesByName.

Examples have already been posted here, but I found that the non-.exe version worked better, so something like:

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

You probably don't have to deal with NotSupportedException, which suggests that the process is remote.

Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
  • it also wont work in a lot of other cases *(if the process has shielded itself with ACLs, for instance)* - actually *killing* a process is a horrible idea and will only generate problems in the long run. Processes should always be **closed** instead of killed so that they can shutdown properly. This answer is a typical beginners' mistake. – specializt Dec 07 '18 at 11:45
31

Killing the Word process outright is possible (see some of the other replies), but outright rude and dangerous: what if the user has important unsaved changes in an open document? Not to mention the stale temporary files this will leave behind...

This is probably as far as you can go in this regard (VB.NET):

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

This will close all open Word windows in an orderly fashion (prompting the user to save his/her work if applicable). Of course, the user can always click 'Cancel' in this scenario, so you should be able to handle this case as well (preferably by putting up a "please close all Word instances, otherwise we can't continue" dialog...)

mdb
  • 52,000
  • 11
  • 64
  • 62
  • I agree with this approach. Killing a process should be the last possible resort. There could be unintended consequences. – Nathan Mar 12 '20 at 14:18
15

Here is an easy example of how to kill all Word Processes.

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

foreach (Process proc in procs)
    proc.Kill();
Nick Berardi
  • 54,393
  • 15
  • 113
  • 135
5

You can bypass the security concerns, and create a much politer application by simply checking if the Word process is running, and asking the user to close it, then click a 'Continue' button in your app. This is the approach taken by many installers.

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

Of course, you can only do this if your app has a GUI

Chris Lawlor
  • 47,306
  • 11
  • 48
  • 68
5
    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;
    }
Vova Popov
  • 1,053
  • 11
  • 11
2

In my tray app, I needed to clean Excel and Word Interops. So This simple method kills processes generically.

This uses a general exception handler, but could be easily split for multiple exceptions like stated in other answers. I may do this if my logging produces alot of false positives (ie can't kill already killed). But so far so guid (work joke).

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

This is how i called it then:

killProcesses((new List<string>() { "winword", "excel" }));
tyler_mitchell
  • 1,727
  • 1
  • 19
  • 27
  • what is `clean Excel and Word Interops` even supposed to mean? – specializt Dec 07 '18 at 11:53
  • as in clean up, if i didn't use this process i would have hundreds of instances of word and excel which would end up hanging my machine. – tyler_mitchell Dec 10 '18 at 11:04
  • killing live processes might also make your machine hang - **and** you might lose important data **and** you might corrupt the installation entirely, forcing the user to repair or reinstall. So, to summarize : your *clean* algorithm will actually will pretty much destroy the system one shiny day; one should be very careful about process control, **especially** if it comes to microsoft processes because these are tighly woven into the OS and cause a whole truckload of problems if not handled carefully. But nowadays, microsoft has learned from their mistakes and shields them against sabotage. – specializt Dec 10 '18 at 15:58
  • so ... you got lucky this time. But please learn from **your** mistake and stop killing processes. Have a look at `CloseMainWindow`. I just hope they start deprecating harmful API like this one someday, this is clearly kernel-level and should not be possible for any userspace app – specializt Dec 10 '18 at 16:01
  • your going off on a very small snippet of code, with no context of how its used... – tyler_mitchell Dec 11 '18 at 17:28
  • thats ... a blatant lie – specializt Dec 23 '18 at 07:33
1

Something like this will work:

foreach ( Process process in Process.GetProcessesByName( "winword" ) )
{
    process.Kill();
    process.WaitForExit();
}
Jimi
  • 29,621
  • 8
  • 43
  • 61
Tomer Gabel
  • 4,104
  • 1
  • 33
  • 37
0

It's better practise, safer and more polite to detect if the process is running and tell the user to close it manually. Of course you could also add a timeout and kill the process if they've gone away...

-1

I opened one Word file, 2. Now I open another word file through vb.net runtime programmatically. 3. I want to kill the second process alone through programmatically. 4. Do not kill first process

ha a
  • 63
  • 7
-2

Please see the example below

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;
    }
JNYRanger
  • 6,829
  • 12
  • 53
  • 81
Ashok
  • 1