2

I need to kill all Microsoft Word processes on a specific file

I have an overnight job that opens files and edits them then closes them again.

private void killprocess(string p)
{
    foreach (Process proc in Process.GetProcessesByName(p).OrderBy(x=>x.Id))
    {               
        proc.Kill();
    }
}

This method kills all processes with specific name, in this case p="winword" BUT... I would like to kill all processes where p="winword" and FilePath = "C:\Temp\Test.docx". Any ideas?

Christos
  • 53,228
  • 8
  • 76
  • 108

2 Answers2

1

If the user double clicked the file and opened WinWord then it will be passed as the commandline.

You can try the following:

private static void Killprocess(string processName, string expectedCommandLine)
{
    foreach (Process proc in Process.GetProcessesByName(processName).OrderBy(x => x.Id))
    {
        var commandLine = GetCommandLine(proc);
        if (commandLine.Contains(expectedCommandLine))
        {
            proc.Kill();
        }
    }
}

private static string GetCommandLine(Process process)
{
    string wmiQuery = string.Format("select CommandLine from Win32_Process where ProcessId={0}", process.Id);
    ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery);
    ManagementObjectCollection result = searcher.Get();
    return result.Cast<ManagementObject>()
        .Select(x => x["CommandLine"].ToString())
        .FirstOrDefault();
}

private static void Main()
{
    Killprocess("winword", yourfullFilePath);
}

Note: It needs more work if user opened the file through menu. You need to find whether a process(Winword) has open file handle to the file you're concerned about. Once you found that you can kill it.

Community
  • 1
  • 1
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • Could you please take a look at my code and tell me where I am wrong, since I got a downvote and I can't get it. Unfortunately the downvoter didn't give me a reasoning. Thank you very much in advance ! – Christos Aug 12 '14 at 13:51
  • That assumes the document name is on the command line, which might be, but not really necessarily. – GSerg Aug 12 '14 at 13:59
  • @GSerg Could you point an instance of which that would fail? Commandline with the file passed is for that purpose only. I have no idea about when it could fail. If you need it more reliable way go through the link I suggested in note section. That should do the trick. – Sriram Sakthivel Aug 12 '14 at 14:00
  • @SriramSakthivel Whenever the file is opened not via command line - which includes user interface and automation. – GSerg Aug 12 '14 at 14:17
  • @GSerg That's what I already mentioned in my answer(Note: It needs more work if user opened the file through menu). Read my answer fully please. – Sriram Sakthivel Aug 12 '14 at 14:18
  • hmmm so there wouldn't be a way to close the file of the word file opened programatically? I am using automation to open the files – Wisani Manganye Aug 13 '14 at 08:39
  • @WisaniManganye There is no easy way AFAIK, did you checked the link I provided in note section? That should help you. – Sriram Sakthivel Aug 13 '14 at 08:42
  • @SriramSakthivel I checked it but isn't very helpful as the Project mentioned in that link is written in a language I don't understand so I cant even replicate code – Wisani Manganye Aug 13 '14 at 10:09
0
private void KillWordByDocumentName(string FullPath)
{
    object document = null;
    object word = null;

    try
    {
        document = Microsoft.VisualBasic.Interaction.GetObject(FullPath, null);

        word = document.GetType().InvokeMember("Parent", BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public, null, document, null);
        word.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public | BindingFlags.OptionalParamBinding, null, word, new object[] { true });
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        // No words are running
    }
    finally
    {
        if (document != null) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(document);
        if (word != null) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(word);
    }
}

More work is needed if Word resists to killing (e.g. getting a process ID out of the object and killing that).
Excel is much better than Word in this regard, it directly exposes a hWnd.

GSerg
  • 76,472
  • 17
  • 159
  • 346