2009-04-20 17 views
11

Estoy trabajando con C#, necesito obtener una instancia específica de Excel por su ID de proceso; Obtengo el ID de proceso de la instancia que necesito de otra aplicación, pero no sé qué más hacer, no sé cómo puedo obtener una instancia en ejecución de Excel dado su ID de proceso.¿Cómo obtener una instancia de Excel o un CLSID de instancia de Excel utilizando la ID del proceso?

He investigado mucho en la web, pero solo he visto ejemplos del uso de Marshal.GetActiveObject (...) o Marshal.BindToMoniker (...), que no puedo usar desde que devuelve el primero la primera instancia de Excel registrada en el ROT y no precisamente la que necesito, y la segunda requiere que guarde el archivo de Excel antes de intentar obtener la instancia.

Además, si cuando sea capaz de obtener el CLSID de la instancia de Excel que necesito, utilizando el ID de proceso, entonces puede ser capaz de llamar

GetActiveObject(ref _guid, _ptr, out objApp);

que en última instancia va a devolver la instancia de Excel que yo necesitar.

+0

me puede publicar una muestra cómo utilizar el método GetActiveObject – Higune

Respuesta

12

Una vez que identifica el proceso a través de la identificación del proceso, puede obtener el Process.MainWindowHandle y luego usarlo junto con el AccessibleObjectFromWindow API para obtener acceso al modelo de objetos de Excel para ese proceso.

El artículo Getting the Application Object in a Shimmed Automation Add-in de Andrew Whitechapel describe esta técnica en detalle, junto con el código de muestra.

El código clave en ese artículo para que comienza en la línea:

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

que en su caso puede tener un aspecto más parecido a:

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

donde el 'excelId' es el número identificador de proceso que estás buscando De lo contrario, el código debería ser esencialmente el mismo que figura en el artículo. (Ignore el hecho de que su código está escrito para un complemento, ese aspecto no afectará sus necesidades aquí, así que simplemente ignórelo.)

Si no tiene la identificación del proceso, entonces usted querría use Process.GetProcessesByName, con lo cual podría enumerar cada una de ellas y tomar el control de cada instancia de Excel con acceso al modelo de objetos, según sea necesario.

Espero que esto ayude,

Mike

+0

gracias, era exactamente lo que estaba buscando. – Vic

+0

No hay problema, Vic, me alegra que te sirva. Este no es un tema fácil y no es bien conocido, pero el artículo de Andrew Whitechapel lo cubre muy bien. ¡Buena suerte! –

+1

El artículo está caído, pero aquí hay una copia del código que he encontrado http://pastebin.com/F7gkrAST –

-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(); 

Esto obtiene todos los procesos denominados "EXCEL" donde la Id del proceso es igual a un valor específico.

+1

Gracias por su respuesta rápida, el problema aquí es que no estoy buscando para matar el proceso , Necesito obtener la instancia de Excel para trabajar con ella, para ser más específico, necesito pegar algo de información sobre ella. – Vic

2

Las entradas ROT no están etiquetadas con un CLSID. El ROT devuelve un DWORD de Register, que se usa como un identificador para Anular registro. Me he encontrado con este problema antes y la única forma en que lo he resuelto es tener algún tipo de complemento cargado en cada Excel con el que pueda comunicarse directamente.

Cuestiones relacionadas