PRB: Visual C# .NET Error Attaching to Running Instance of Office Application (316125)
The information in this article applies to:
- Microsoft Visual C# .NET (2003)
- Microsoft Visual C# .NET (2002)
- Microsoft Office Access 2003
- Microsoft Access 2002
- Microsoft Office Excel 2003
- Microsoft Excel 2002
- Microsoft Office PowerPoint 2003
- Microsoft PowerPoint 2002
- Microsoft Office Word 2003
- Microsoft Word 2002
This article was previously published under Q316125
For a Microsoft Visual Basic .NET version of this article, see 308409.
For a Microsoft Visual Basic 6.0 and
Visual C++ 6.0 version of this article, see 238610.
SYMPTOMS When you try to use System.Runtime.InteropServices.Marshal.GetActiveObject from Microsoft Visual C# .NET to automate a Microsoft Office application,
you may receive the following error message, even though the Office application
is running: An unhandled exception of type
'System.Runtime.InteropServices.COMException' occurred in
mscorlib.dll
Additional information: Operation unavailable
CAUSE Although the Office application is running, it may not be
registered in the Running Object Table (ROT). A running instance of an Office
application must be registered in the ROT before GetActiveObject can be used to attach to it.
When an Office application
starts, it does not immediately register its running objects. This optimizes
the application startup process. Instead of registering at startup, an Office
application registers its running objects in the ROT after it loses focus.
Therefore, if you attempt to use GetActiveObject to attach to a running instance of an Office application before
the application has lost focus, you may receive an error message.
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 starting the
executable (.exe) file for the Office application, you may need to wait for the
Office application to finish loading before you attempt to attach to the
running instance. A code sample is provided as a workaround in the "More
Information" section.
STATUSThis
behavior is by design.WORKAROUND To work around the problem, follow these steps:
- Create an instance of the application by using the System.Diagnostics.Process.Start method.
- Give the focus to your Visual C# form.
- Try to use GetActiveObject while accounting for the load time of the Office
application.
The following revised code illustrates this workaround:
private void button1_Click(object sender, System.EventArgs e)
{
int iSection = 0, iTries = 0;
Word.Application oWord;
// Start Word, giving it focus.
System.Diagnostics.Process.Start("C:\\Program Files\\Microsoft Office\\Office10\\winword.exe");
// Move focus back to this form. (This ensures the Office
// application registers itself in the ROT, allowing
// GetObject to find it.)
this.Activate();
tryAgain:
try
{
// Attempt to use GetObject to reference the running
// Office application.
iSection = 1; // Attempting GetObject.
oWord = (Word.Application) System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
iSection = 0; // Resume normal error handling.
// Automate Word.
MessageBox.Show(oWord.Name + ": able to GetObject after " +
(iTries + 1) + " tries.");
oWord.ActiveDocument.Content.Text = "Hello!";
// You are finished with Automation, so release your reference.
oWord = null;
// Exit procedure.
return;
}
catch (Exception err)
{
if (iSection == 1)
{
//GetObject may have failed because the
//Shell function is asynchronous; enough time has not elapsed
//for GetObject to find the running Office application. 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.
iTries++;
if (iTries < 20)
{
System.Threading.Thread.Sleep(500); // Wait 1/2 seconds.
this.Activate();
goto tryAgain; //resume code at the GetObject line
}
else
MessageBox.Show("GetObject still failing. Process ended.");
}
else
{
//iSection = 0 so use normal error handling:
MessageBox.Show(err.Message);
}
}
}
REFERENCES For more information, visit the following Microsoft Developer
Network (MSDN) Web site:
Modification Type: | Major | Last Reviewed: | 1/19/2006 |
---|
Keywords: | kbPIA kbAutomation kbprb KB316125 kbAudDeveloper |
---|
|