2009-04-20 4 views
11

Sto lavorando con C#, ho bisogno di ottenere un'istanza specifica di Excel dal suo ID di processo; Ricevo l'ID di processo dell'istanza di cui ho bisogno da un'altra applicazione, ma non so cos'altro fare, non so come posso ottenere un'istanza in esecuzione di Excel, dato il suo ID di processo.Come ottenere l'istanza di Excel o il CLSID di un'istanza di Excel utilizzando l'ID di processo?

Ho cercato molto sul web, ma ho visto solo esempi di utilizzo di Marshal.GetActiveObject (...) o Marshal.BindToMoniker (...), che non posso utilizzare dal momento che il primo restituisce la prima istanza di Excel registrata nel ROT e non esattamente quella di cui ho bisogno, e la seconda richiede il salvataggio del file excel prima di provare a ottenere l'istanza.

Inoltre, se io dove in grado di ottenere il CLSID dell'istanza excel che ho bisogno, utilizzando l'ID di processo, allora io possa essere in grado di chiamare

GetActiveObject(ref _guid, _ptr, out objApp);

che alla fine restituirà l'istanza di Excel che ho bisogno.

+0

mi può inviare un campione come utilizzare il metodo GetActiveObject – Higune

risposta

12

Una volta identificato il processo tramite l'id di processo, è possibile ottenere il Process.MainWindowHandle e quindi utilizzarlo insieme allo AccessibleObjectFromWindow API per ottenere l'accesso al modello a oggetti di Excel per tale processo.

L'articolo Getting the Application Object in a Shimmed Automation Add-in di Andrew Whitechapel descrive questa tecnica in dettaglio, insieme al codice di esempio.

Il codice chiave in tale articolo per voi inizia alla linea:

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

che nel tuo caso potrebbe apparire più simile a:

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

dove il 'excelId' è il numero di processo id che stai cercando. Altrimenti, il codice dovrebbe essere essenzialmente uguale a quello indicato nell'articolo. (Ignorare il fatto che il suo codice è stato scritto per un componente aggiuntivo, questo aspetto non influirà sulle tue esigenze qui, quindi ignoralo.)

Se non hai l'id di processo, allora vorresti utilizzare Process.GetProcessesByName, in base al quale è possibile enumerarne uno e acquisire il controllo di ogni istanza di Excel con accesso al modello di oggetto, in base alle esigenze.

Spero che questo aiuti,

Mike

+0

grazie, era esattamente quello che stavo cercando. – Vic

+0

Nessun problema, Vic, felice che funzioni per voi. Questo non è un problema facile e non è noto, ma l'articolo di Andrew Whitechapel lo descrive molto bene. In bocca al lupo! –

+1

L'articolo non è disponibile, ma ecco un pastebin del codice che ho trovato 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(); 

Questo ottiene tutti i processi denominati "EXCEL", dove il processo di identificazione è uguale a un valore specifico.

+1

Grazie per la risposta rapida, il problema qui è che non sto cercando di uccidere il processo , Ho bisogno di ottenere l'istanza di Excel per lavorare con esso, per essere più specifici ho bisogno di incollare alcune informazioni su di esso. – Vic

2

Le voci ROT non sono contrassegnate con un CLSID. Il ROT restituisce un DWORD dal registro, che viene utilizzato come identificativo per annullare la registrazione. Ho incontrato questo problema in passato e l'unico modo che ho risolto è di avere una sorta di componente aggiuntivo caricato in ogni Excel con cui è possibile comunicare direttamente.