Как получить дескриптор окна или процесса определенного процесса Excel? - PullRequest
4 голосов
/ 20 января 2011

Как мы можем получить дескриптор окна приложения или дескриптор процесса Excel, который принадлежит созданному нами экземпляру приложения Excel? Мы используем Interop.Excel.dll версии 1.3.0.0. Класс приложения, похоже, не имеет свойства HWnd для вызова.

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

Excel.Application app = new Excel.Application();
// .. do something with excel here
app.Quit();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
// this is in some cases still not enough to get excel killed
uint processID;        
GetWindowThreadProcessId((IntPtr)hWnd, out processID); // how to get HWnd from this Excel application?
Process.GetProcessById((int)processID).Kill(); 

Ответы [ 3 ]

2 голосов
/ 26 января 2011

Класс приложения, похоже, не имеет свойства HWnd для вызова

Класс Excel.Application имеет свойство Hwnd.

В ответ на комментарий:

Мы не используем Microsoft.Office.Interop.Excel.dll, а вместо этого Interop.Excel.dll, у которого отсутствует это свойство

Я бы вообще рекомендовал использовать PIA (Microsoft.Office.Interop.Excel.dll). Если у вас есть веская причина не желать этого, а используемый вами RCW по какой-то причине не раскрывает свойство, альтернативой может быть использование позднего связывания, например ::11013*

typeof(Excel.Application).InvokeMember("Hwnd", BindingFlags.GetProperty, null, app, null);
1 голос
/ 26 января 2011

Хотя все ответы, которые я получил, не помогли, спасибо за ответы в любом случае. Теперь я нашел обходной путь сам:

Теперь я создал рабочий процесс , который периодически проверяет процессы Excel, которые старше одной минуты . Поскольку моя обработка Excel никогда не должна длиться дольше одной минуты, я могу быть уверен, что процессы Excel старше одной минуты выполнены, поэтому я могу убить этот процесс.

Другой способ, который приходит мне в голову, - это получить список всех процессов Excel до того, как вы создадите экземпляр своего процесса Excel. Затем после создания экземпляра вы проверяете снова . PID, который является новым, это новый процесс Excel. Не забудьте поставить оператор lock , чтобы избежать проблем с многопоточностью.

0 голосов
/ 26 января 2011

Вы можете использовать эту конструкцию для вызова функции Windows API

    [DllImport("user32.dll")]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    IntPtr hWnd = FindWindow("XLMAIN", null);

Но вы должны сделать это ДО любых операций с объектом Application - создайте его, установите Visible = true и со следующей строкой кода получите дескриптор

...