GetObject or GetActiveObject cannot find a running Office application

Article translations Article translations
Article ID: 238610 - View products that this article applies to.
This article was previously published under Q238610
Expand all | Collapse all

On This Page

SYMPTOMS

When you try to use GetObject (Microsoft Visual Basic) or GetActiveObject (Microsoft Visual C++) to automate a Microsoft Office application, you get one of the following error messages, even though the Office application is running:
Error message 1
Run-time error '429':
ActiveX component can't create object
Error message 2
Error: 0x800401e3 "Operation unavailable"

CAUSE

Although the Office application is running, it might not be registered in the Running Object Table (ROT). A running instance of an Office application must be registered in the ROT before it can be attached to using GetObject (Visual Basic) or GetActiveObject (Visual C++).

When an Office application starts, it does not immediately register its running objects. This optimizes the application's startup process. Instead of registering at startup, an Office application registers its running objects in the ROT once it loses focus. Therefore, if you attempt to use GetObject or GetActiveObject to attach to a running instance of an Office application before the application has lost focus, you might receive one of the errors above.

RESOLUTION

Using code, you can change focus from the Office application to your own application (or to some other application) to allow it to register itself in the ROT. Additionally, if your code is launching the Office application's exe file, you might need to wait for the Office application to finish loading before attempting to attach to the running instance. A code sample is provided as a workaround in the "More Information" section.

STATUS

This behavior is by design.

MORE INFORMATION

In most situations, developers who want to automate an Office application need to use CreateObject (Visual Basic) or CoCreateInstance (Visual C++) to launch a new instance of the Office application.

However, there are cases where you might prefer to automate an Office application that is already running: for example, if the user previously started the Office application. Or, if you launched the Office application's executable using code so that you could specify command-line switches for the application. In order to automate the running Office application, you must use GetObject or GetActiveObject.

Steps to reproduce the behavior

  1. Start Microsoft Visual Basic and create a new Standard EXE project. Form1 is created by default.
  2. Add a CommandButton control to Form1.
  3. Add the following code to the form's code module.
    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. Make sure the location of the Excel.exe is correct in the code sample.
  5. Quit Microsoft Excel if it is already running.
  6. Press F5 to run the project, and click Command1.

Workaround

To work around the problem, you can:
  • Give focus to the Office application by changing the second argument of the Shell function to either vbMinimizedFocus, vbMaximizedFocus, or vbNormalFocus.
  • Give your Visual Basic form the focus.
  • Attempt GetObject while accounting for the Office application's load time.
The following revised code illustrates this workaround.
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
				

Workaround for C++

If you are programming in C++, the following code sample demonstrates a similar workaround to that shown in the above Visual Basic sample. Notice that SetForegroundWindow is used to move focus away from Excel, allowing it to register its running objects.
//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();
				

REFERENCES

For more information, click the following article numbers to view the articles in the Microsoft Knowledge Base:
192919 How to automate a secured Access database using Visual Basic
237338 Error message using WordMail: "This method or property is not available"
240794 How to determine the path for an Office application

Properties

Article ID: 238610 - Last Review: May 11, 2007 - Revision: 6.3
APPLIES TO
  • 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
  • Microsoft Word 2000
  • Microsoft Word 97 Standard Edition
Keywords: 
kbautomation kbprb KB238610

Give Feedback

 

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