Зависшие процессы Office interop

337
27 сентября 2017, 08:09

Предположим, в приложении необходимо использовать Office interop.(без вариантов) Всем известно, что он создает приложения office без интерфейса и через них выполняет работу.

Ну как быть, если пользователь некорректно завершил работу с программой? Например, убил через диспетчер задач. Получается, что в процессах остаются висеть приложения офиса.

Можно ли это предотвратить? Если нет, то можно ли понять при запуске(повторном) приложения, что в процессах висит мусор, который остался от прошлого запуска и грохнуть эти процессы, не затронув реальные приложения офиса(например, юзер запустил Excel.)

Answer 1

Я полагаю, суть вопроса в методике отделения "мусора" от нормальных процессов Excel. Умея это, уже можно что-то смастерить: удалять мусорные процессы при запуске основной программы, или периодически - фоновым сервисом, когда основная программа закрыта.

Наиболее правильное решение: добавлять Id всех создаваемых Interop-процессов в БД, при корректном их завершении - удалять. Соответственно, при некорректном завершении приложения в БД останутся Id мертвых процессов, которые можно на следующем запуске прибить (предварительно убедившись, что это все еще существующие процессы Excel, так как они могли быть прибиты чем-то другим и те же Id уже переиспользованы системой для другой программы).

Но, если хочется метод попроще, можно считать "мусором" любой процесс Excel, не имеющий видимого главного окна:

using System.Diagnostics;
using System.Runtime.InteropServices;
static class Program 
{
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool IsWindowVisible(IntPtr hWnd);
    public static bool IsProcessDead(Process pr)
    {
            IntPtr hwnd = pr.MainWindowHandle;
            if (hwnd == IntPtr.Zero) return true;
            return !IsWindowVisible(hwnd);            
    }

    void ClearProcesses()
    {                
            Process[] prs=Process.GetProcessesByName("excel");
            foreach (Process proc in prs)
            {
                if(IsProcessDead(proc))proc.Kill();
            }
     }
}

Если на целевой машине нет других программ, использующих невидимые эксели для своих целей, это можно считать нормальным допущением.

READ ALSO
Как добавить еще один Resources.resx?

Как добавить еще один Resources.resx?

Всем приветДелаю программу мультиязычной

277
MessageBox из пользовательского Window [дубликат]

MessageBox из пользовательского Window [дубликат]

На данный вопрос уже ответили:

278
Путь к файлу/ресурсу в библиотеке

Путь к файлу/ресурсу в библиотеке

Есть своя библиотека классов, в которой есть файл (например, xsd)Как получить доступ к этому файлу из консольного и ASP MVC проекта?

225
C# работа с подстрокой

C# работа с подстрокой

Как сделать такое задание используя классы (Word, Sentence)?

299