Как закрыть работающий экземпляр документа Word? (С #)

Я мог видеть много очень похожих тем вокруг, но ничто, кажется, не дает мне решение, которое должно быть очень простым.

Из моего приложения winforms мне нужно закрыть работающий экземпляр текстового документа (открытый из самого приложения). Когда я открываю документ Word из приложения, я отслеживаю его в списке. Теперь, как я могу закрыть тот же документ?

Вот что я попробовал:

private bool CloseWord(string osPath) //here I pass the fully qualified path of the file
{
    try
    {
        Word.Application app = (Word.Application)Marshal.GetActiveObject("Word.Application");
        if (app == null)
            return true;

        foreach (Word.Document d in app.Documents)
        {
            if (d.FullName.ToLower() == osPath.ToLower())
            {
               d.What? //How to close here?
               return true;
            }
        }
        return true;
    }
    catch
    {
        return true;
    }
}

Я получаю много методов для объекта документа, но только .Close() закрыть который имеет такие аргументы: ref object SaveChanges, ref object OriginalFormat, ref object RouteDocument что я не понимаю.

Какой идеальный способ? Спасибо..

Редактировать:

  1. Я не могу закрыть все приложение Word (WinWord), так как у пользователей могут быть открыты другие файлы Word.

  2. Мне нужно просто прекратить слово экземпляр (что-то вроде Process.Kill()) без каких-либо подсказок пользователю сохранить или нет и т. д.

4 ответа

Решение

Полученное отсюда решение решает.

Word.Application app = (Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
if (app == null)
    return true;

foreach (Word.Document d in app.Documents)
{
    if (d.FullName.ToLower() == osPath.ToLower())
    {
        object saveOption = Word.WdSaveOptions.wdDoNotSaveChanges;
        object originalFormat = Word.WdOriginalFormat.wdOriginalDocumentFormat;
        object routeDocument = false;
        d.Close(ref saveOption, ref originalFormat, ref routeDocument);
        return true;
    }
}
return true;

Как насчет использования что-то вроде:

Изменено с: http://www.dreamincode.net/code/snippet1541.htm

public static bool KillProcess(string name)
{
    //here we're going to get a list of all running processes on
    //the computer
    foreach (Process clsProcess in Process.GetProcesses())
    {
        if (Process.GetCurrentProcess().Id == clsProcess.Id)
            continue;
        //now we're going to see if any of the running processes
        //match the currently running processes. 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.
        //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
        if (clsProcess.ProcessName.Contains(name))
        {
            clsProcess.Kill();
            return true;
        }
    }
    //otherwise we return a false
    return false;
}

Если вы хотите закрыть целое текстовое приложение, вы можете просто позвонить:

Word.Application app = (Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
if (app == null)
    return true;
app.Quit(false);

Я знаю, что уже слишком поздно, но я нашел эту тему, потому что у меня была та же проблема.

И мое решение может помочь другим людям.

Приведенное выше решение не сработало, поскольку оно убивало все запущенные экземпляры Word, хотя оно не было открыто программой C#, а пользователем.

Так что это было не так удобно для пользователя.

Мой код проверяет процессы до / после создания Word.Application Объект в C# и записывает идентификаторы WINWORD Процессы в List<int> Затем он сравнивает значения в обоих List<int>, Когда processID не найден в обоих List<int> это убивает процесс с этим идентификатором.

public List<int> getRunningProcesses()
{
    List<int> ProcessIDs = new List<int>();
    //here we're going to get a list of all running processes on
    //the computer
    foreach (Process clsProcess in Process.GetProcesses())
    {
        if (Process.GetCurrentProcess().Id == clsProcess.Id)
            continue;             
        if (clsProcess.ProcessName.Contains("WINWORD"))
        {
            ProcessIDs.Add(clsProcess.Id);
        }
    }
    return ProcessIDs;
}

Выполните это дважды (один раз до создания приложения Word.Application и один раз после).

 List<int> processesbeforegen = getRunningProcesses();
 // APP CREATION/ DOCUMENT CREATION HERE...
 List<int> processesaftergen = getRunningProcesses();

Тогда беги killProcesses(processesbeforegen, processesaftergen);

 private void killProcesses(List<int> processesbeforegen, List<int> processesaftergen)
 {
    foreach (int pidafter in processesaftergen)
    {
        bool processfound = false;
        foreach (int pidbefore in processesbeforegen)
        {
            if (pidafter == pidbefore)
            {
                processfound = true;
            }
        }

        if (processfound == false)
        {
            Process clsProcess = Process.GetProcessById(pidafter);
            clsProcess.Kill();
        }
    }
 }
Другие вопросы по тегам