GetObject o GetActiveObject Impossibile trovare un'applicazione di Office in esecuzione

Traduzione articoli Traduzione articoli
Identificativo articolo: 238610 - Visualizza i prodotti a cui si riferisce l?articolo.
Espandi tutto | Chiudi tutto

In questa pagina

Sintomi

Quando si tenta di utilizzare GetObject (Microsoft Visual Basic) o GetActiveObject (Microsoft Visual c ++) per automatizzare un'applicazione Microsoft Office, viene visualizzato uno dei seguenti messaggi di errore, anche se l'applicazione di Office è in esecuzione:
Messaggio di errore 1
Errore di run-time "429":
ActiveX il componente non è in grado di creare l'oggetto
Messaggio di errore 2
Errore: 0x800401e3 "Operazione non disponibile"

Cause

Anche se l'applicazione di Office è in esecuzione, è possibile che non sia registrata nella tabella degli oggetti in esecuzione (ROT, Running Object Table). Un'istanza in esecuzione di un'applicazione deve essere registrata nella ROT prima di Office può essere collegata all'utilizzo di GetObject (Visual Basic) o GetActiveObject (Visual c ++).

Quando un'applicazione di Office viene avviata, i relativi oggetti in esecuzione non vengono registrati immediatamente. In tal modo si ottimizza il processo di avvio dell'applicazione. Invece di effettuare la registrazione all'avvio, gli oggetti in esecuzione di un'applicazione di Office vengono registrati nella ROT quando l'applicazione ha perso lo stato attivo. Di conseguenza, se si tenta di utilizzare GetObject o GetActiveObject per associare a un'istanza di un'applicazione di Office in esecuzione prima che l'applicazione abbia perso lo stato attivo, si potrebbe essere visualizzato uno degli errori precedenti.

Risoluzione

Utilizza del codice, lo stato attivo puoi modificare da Office applicazione a un'applicazione personalizzata (oppure a un'altra applicazione) per consentire la registrazione nella ROT. Inoltre, se il codice avvia l'eseguibile dell'applicazione di Office, può essere necessario attendere che questa abbia completato il caricamento prima che sia possibile tentare di collegarsi all'istanza in esecuzione. Come soluzione per questo problema nella sezione "Ulteriori informazioni" viene fornito un esempio di codice.

Status

Questo comportamento legato alla progettazione.

Informazioni

Nella maggior parte dei casi, gli sviluppatori che desiderano automatizzare un'applicazione di Office necessario utilizzare CreateObject (Visual Basic) o CoCreateInstance (Visual c ++) per avviare una nuova istanza di Office dell'applicazione.

Tuttavia, esistono casi in cui potrebbe essere preferibile automatizzare un'applicazione di Office è già in esecuzione: ad esempio, se l'utente ha avviato l'applicazione. oppure se l'eseguibile dell'applicazione di Office è stato avviato tramite codice per poter specificare opzioni da riga di comando per l'applicazione. Per automatizzare Office in esecuzione dell'applicazione, è necessario utilizzare GetObject o GetActiveObject .

Procedura per riprodurre il problema.

  1. Avviare Microsoft Visual Basic e creare un nuovo progetto EXE standard. In base all'impostazione predefinita, viene creato il progetto Form1.
  2. Aggiungere un controllo CommandButton al Form1.
  3. Aggiungere al modulo del codice il seguente codice.
    Private Sub Command1_Click()
        Dim oExcel As Object
        ' Launch a new instance of Microsoft Excel:
        Shell "C:\Program Files\Microsoft Office\Office\Excel.EXE", _
           vbMinimizedNoFocus
        ' An error 429 occurs on the following line:
        Set oExcel = GetObject(, "Excel.Application")
        MsgBox oExcel.Name
        Set oExcel = Nothing
    End Sub
    					
  4. Assicurarsi che il percorso del Excel.exe sia corretto nell'esempio di codice.
  5. Uscire da Microsoft Excel se è già in esecuzione.
  6. Premere F5 per eseguire il progetto e fare clic su Command1 .

Per risolvere il problema

Per aggirare il problema, è possibile procedere come segue:
  • Assegnare lo stato attivo per l'applicazione Office modificando il secondo argomento della funzione Shell in vbMinimizedFocus , vbMaximizedFocus o l'utilizzo delle costanti vbNormalFocus .
  • Assegnare lo stato attivo al form Visual Basic.
  • Tentativo di GetObject tenendo conto di tempo di caricamento dell'applicazione Office.
Il seguente codice modificato illustra la soluzione.
Private Declare Sub Sleep Lib "kernel32" _
    (ByVal dwMilliseconds As Long)

Private Sub Command1_Click()
    Dim intSection As Integer
    Dim intTries As Integer
    Dim oExcel As Object
    
    ' Enable error handler for this procedure:
    On Error GoTo ErrorHandler
    
    ' Launch Microsoft Excel, giving it focus:
    Shell "C:\Program Files\Microsoft Office\Office\Excel.EXE", _
        vbMinimizedFocus 'other options for starting with
        'focus: vbMaximizedFocus and vbNormalFocus
    
    ' Move focus back to this form. (This ensures the Office
    '  application registers itself in the ROT, allowing
    '  GetObject to find it.)
    Me.SetFocus
    
    ' Attempt to use GetObject to reference the running
    '  Office application:
    intSection = 1 'attempting GetObject...
    Set oExcel = GetObject(, "Excel.Application")
    intSection = 0 'resume normal error handling
    
    ' Now you can automate Microsoft Excel:
    MsgBox oExcel.Name & ": able to GetObject after " & _
        intTries + 1 & " tries.", vbMsgBoxSetForeground
    
    ' Finished with automation so release your reference:
    Set oExcel = Nothing
    
    ' Exit procedure:
    Exit Sub
    
ErrorHandler:
    If intSection = 1 Then 'GetObject may have failed because the
    'Shell function is asynchronous; enough time has not elapsed
    'for GetObject to find the running Office application. Wait
    'wait 1/2 seconds and retry the GetObject. If you try 20 times
    'and GetObject still fails, assume some other reason
    'for GetObject failing and exit the procedure.
        intTries = intTries + 1
        If intTries < 20 Then
            Sleep 500 ' wait 1/2 seconds
            Resume 'resume code at the GetObject line
        Else
            MsgBox "GetObject still failing. Process ended.", _
                vbMsgBoxSetForeground
        End If
    Else 'intSection = 0 so use normal error handling:
        MsgBox Error$
    End If
End Sub
				

Soluzione per C++

Per la programmazione in c ++, l'esempio di codice seguente viene illustrato una soluzione simile a quello illustrato nell'esempio precedente di Visual Basic. Si noti che SetForegroundWindow viene utilizzata per spostare lo stato attivo esce da Excel, che consentono di registrare gli oggetti in esecuzione.
//Store the handle of the currently active window...
HWND hwndCurrent = ::GetForegroundWindow();

//Launch Excel and wait until it is waiting for
//user input...
STARTUPINFO Start;
PROCESS_INFORMATION ProcInfo;
ZeroMemory(&Start,sizeof(STARTUPINFO));
Start.cb=sizeof(Start);
Start.dwFlags = STARTF_USESHOWWINDOW;
Start.wShowWindow = SW_SHOWMINIMIZED;

//Change the path to Excel as needed...
LPSTR pszExcelPath = 
      "c:\\program files\\microsoft office\\office\\excel.exe";

::CreateProcess(NULL, pszExcelPath, 0, 0, 1,
       NORMAL_PRIORITY_CLASS, 0, NULL, &Start, &ProcInfo);


if((::WaitForInputIdle(ProcInfo.hProcess, 10000))==WAIT_TIMEOUT)
{
    ::MessageBox(NULL, "Timed out waiting for Excel.", NULL,  
                 MB_OK);
}

//Restore the active window to the foreground...
//  NOTE: If you comment out this line, the code will fail!
::SetForegroundWindow(hwndCurrent);

//Initialize COM library...
::CoInitialize(NULL);

//Attach to the running instance...
CLSID clsid;
CLSIDFromProgID(L"Excel.Application", &clsid);  
IUnknown *pUnk = NULL;
IDispatch *pDisp = NULL;

for(int i=1;i<=5;i++) //try attaching for up to 5 attempts
{
   HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);
   if(SUCCEEDED(hr)) 
   {
       hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pDisp);
       break;
   }
   ::Sleep(1000);
}
        
if (!pDisp) {
    ::MessageBox(NULL, "Failed to find instance!!", "Error", 
                 MB_ICONHAND);
}
else {
    ::MessageBox(NULL, "Got instance of Excel!", "Success", MB_OK);
}

//Release the no-longer-needed IUnknown...
if (pUnk) 
    pUnk->Release();

//... Add your automation code for Excel here ...

//Release pDisp when no longer needed...
if (pDisp)
    pDisp->Release();

//Cleanup COM...
CoUninitialize();
				

Riferimenti

Per ulteriori informazioni, fare clic sui numeri degli articoli della Microsoft Knowledge Base riportato di seguito:
192919Come automatizzare un database protetto utilizzando Visual Basic
237338Messaggio di errore utilizzando WordMail: "il metodo o proprietà non disponibile"
240794Come determinare il percorso per un'applicazione di Office

Proprietà

Identificativo articolo: 238610 - Ultima modifica: venerdì 11 maggio 2007 - Revisione: 6.3
Le informazioni in questo articolo si applicano a:
  • Microsoft Office Excel 2007
  • Microsoft Office Excel 2003
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Visual Basic for Applications 5.0
  • Microsoft Visual Basic for Applications 6.0
  • Microsoft Visual C++ 5.0 Professional Edition
  • Microsoft Visual C++ 6.0 Professional Edition
  • Microsoft Office Access 2007
  • Microsoft Office Access 2003
  • Microsoft Access 2002 Standard Edition
  • Microsoft Access 2000 Standard Edition
  • Microsoft Access 97 Standard Edition
  • Microsoft Office PowerPoint 2007
  • Microsoft Office PowerPoint 2003
  • Microsoft PowerPoint 2002 Standard Edition
  • Microsoft PowerPoint 2000 Standard Edition
  • Microsoft PowerPoint 97 Standard Edition
  • Microsoft Office Word 2007
  • Microsoft Office Word 2003
  • Microsoft Word 2002 Standard Edition
  • Microsoft Word 2000 Standard Edition
  • Microsoft Word 97 Standard Edition
Chiavi: 
kbmt kbautomation kbprb KB238610 KbMtit
Traduzione automatica articoli
Il presente articolo è stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell?utente. Tuttavia, un articolo tradotto in modo automatico non è sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, più o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non è la sua. Microsoft non è responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell?utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.
Clicca qui per visualizzare la versione originale in inglese dell?articolo: 238610
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.

Invia suggerimenti

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com