Как получить экземпляр Excel или экземпляр Excel CLSID с помощью идентификатора процесса?

Я работаю с С#, мне нужно получить конкретный экземпляр excel с помощью идентификатора процесса; Я получаю идентификатор процесса экземпляра, который мне нужен из другого приложения, но я не знаю, что еще делать, я не знаю, как я могу получить исполняемый экземпляр excel с его идентификатором процесса.

Я много исследовал в Интернете, но я вижу только примеры использования Marshal.GetActiveObject(...) или Marshal.BindToMoniker(...), которые я не могу использовать, поскольку первый возвращает первый экземпляр Excel, зарегистрированный в ROT, а не тот, который мне нужен, а второй требует, чтобы вы сохранили файл excel, прежде чем пытаться получить экземпляр.

Кроме того, если я могу получить CLSID экземпляра excel, который мне нужен, используя идентификатор процесса, тогда я могу позвонить

GetActiveObject(ref _guid, _ptr, out objApp);

который в конечном итоге вернет экземпляр excel, который мне нужен.

Ответ 1

Как только вы идентифицируете процесс с помощью идентификатора процесса, вы можете получить Process.MainWindowHandle, а затем использовать его вместе с AccessibleObjectFromWindow API, чтобы получить доступ к объектной модели Excel для этого процесса.

В статье "Приобретение объекта приложения в надстроенной надстройке надстройки" Эндрю Уайтчепел подробно описывает эту технику вместе с образцом кода.

key code в этой статье для вас начинается с строки:

int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle

Что в вашем случае может выглядеть больше:

int excelId = 1234; // Change as appropriate!
int hwnd = (int)Process.GetProcessById(excelId).MainWindowHandle

где "excelId" - это номер идентификатора процесса, который вы ищете. В противном случае код должен быть по существу таким же, как в данной статье. (Игнорируйте тот факт, что его код написан для надстройки, этот аспект не повлияет на ваши потребности здесь, поэтому просто игнорируйте его.)

Если у вас нет идентификатора процесса, то вы хотите использовать Process.GetProcessesByName, посредством чего вы можете перечислить каждый из них и захватить управление каждым экземпляром Excel с доступом к объектной модели по мере необходимости.

Надеюсь, что это поможет,

Mike

Ответ 2

Записи ROT не помечены CLSID. ROT возвращает DWORD из Register, который используется как идентификатор для Unregister. Я столкнулся с этой проблемой раньше, и единственный способ, которым я решил, - это добавить какую-либо надстройку в каждый Excel, с которой вы можете напрямую общаться.

Ответ 3

using System.Diagnostics;

   var eProcess = from p in Process.GetProcessesByName("EXCEL")
                   where p.Id == 3700 //whatever Id you have...
                   select p;

    foreach (var process in eProcess)
        process.Kill();

Получает все процессы с именем "EXCEL", где Id процесса равен конкретному значению.