Ted Palmer
asked on
Microsoft Automation of MS-Word 2007 using VB.NET 2008 programming COMException
Hello EE Experts,
I am very suprised to see so few answered questions on the topic of Microsoft Automation of MS-Word using Visual Basic .NET (2008 in this case) programming there are on EE. The word "Automation" has a very special meaning in this context. So much benefit can be had in businesses of all sizes for the production of documents that are specific to the recipient -- not just junk mail. That is what my VB.NET 2008 program does. Produce documents for attorneys that have data inserted in them by the MS-Word Mail Merge process, but I am having a problem. After the document is produced and saved, I display the file name in a DataGrid that the user can click on to select and click on a button to "open" the MS-Word document. This opens the document in MS-Word using MS-Word as what Microsoft calls an "Automation Server".
The problem that I am having is this. Early in the start up of the program I declare an object reference variable to point to an instance of MS-Word, and instantiate an instance of MS-Word using MS-Automation techniques. No big deal. Here is the code that works:
Public go_wrdApp As Microsoft.Office.Interop.W ord.Applic ation
go_wrdApp = CreateObject("Word.Applica tion")
So now go_wrdApp is an object reference variable that points to an instance of the MS-Word.program (an Automation Server)
Using Microsoft "Automation" technique -- Each of the Microsoft Office program components can be a Microsoft "Automation Server" -- I can run the mail merge process and save each MS-Word document generated into a file to be opened later as described above. The problem occurs when the user closes the MS-Word application frame after looking at a documet by clicking on the red 'X' in the upper right corner of the application frame. This closes the whole instance of MS-Word -- not just the document that was being viewed in the application program.
So now, at a later time, when the same user attempts to look at another MS-Word document using the technique described above with the DataGrid, instead of opening the document in MS-Word the VB.NET 2008 program throws a COMException with the message "RPC server is unavailable" because the object reference variable go_wrdApp was left pointing at a MS-Word program object (Automation Server) that no longer exists because the user clicked on the little red 'X' in the upper right corner of the application frame instead of just closing only the document.
Is there a way that I can test "go_wrdApp" object reference variable to be sure that it is pointing at an instance of MS-Word program object that is really there?
"If Not IsNothing(go_wrdApp) Then" doesn't work.
Oh! I believe the reference to RPC in the error message means "Remote Procedure Call".
Thanks,
Ted Palmer
I am very suprised to see so few answered questions on the topic of Microsoft Automation of MS-Word using Visual Basic .NET (2008 in this case) programming there are on EE. The word "Automation" has a very special meaning in this context. So much benefit can be had in businesses of all sizes for the production of documents that are specific to the recipient -- not just junk mail. That is what my VB.NET 2008 program does. Produce documents for attorneys that have data inserted in them by the MS-Word Mail Merge process, but I am having a problem. After the document is produced and saved, I display the file name in a DataGrid that the user can click on to select and click on a button to "open" the MS-Word document. This opens the document in MS-Word using MS-Word as what Microsoft calls an "Automation Server".
The problem that I am having is this. Early in the start up of the program I declare an object reference variable to point to an instance of MS-Word, and instantiate an instance of MS-Word using MS-Automation techniques. No big deal. Here is the code that works:
Public go_wrdApp As Microsoft.Office.Interop.W
go_wrdApp = CreateObject("Word.Applica
So now go_wrdApp is an object reference variable that points to an instance of the MS-Word.program (an Automation Server)
Using Microsoft "Automation" technique -- Each of the Microsoft Office program components can be a Microsoft "Automation Server" -- I can run the mail merge process and save each MS-Word document generated into a file to be opened later as described above. The problem occurs when the user closes the MS-Word application frame after looking at a documet by clicking on the red 'X' in the upper right corner of the application frame. This closes the whole instance of MS-Word -- not just the document that was being viewed in the application program.
So now, at a later time, when the same user attempts to look at another MS-Word document using the technique described above with the DataGrid, instead of opening the document in MS-Word the VB.NET 2008 program throws a COMException with the message "RPC server is unavailable" because the object reference variable go_wrdApp was left pointing at a MS-Word program object (Automation Server) that no longer exists because the user clicked on the little red 'X' in the upper right corner of the application frame instead of just closing only the document.
Is there a way that I can test "go_wrdApp" object reference variable to be sure that it is pointing at an instance of MS-Word program object that is really there?
"If Not IsNothing(go_wrdApp) Then" doesn't work.
Oh! I believe the reference to RPC in the error message means "Remote Procedure Call".
Thanks,
Ted Palmer
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
i know its not the best way of handling this issue but for me it saved alot of time and worked on the spot.
cheers
cheers
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
CodeCruiser:
This looks more like what I was looking for. I just finished an SEO webinar and I have to run for an appointment. So I may not get to experiment with this suggestion till tomorrow, but you can be sure that I am going to try this.
Thank you so much,
Ted Palmer
This looks more like what I was looking for. I just finished an SEO webinar and I have to run for an appointment. So I may not get to experiment with this suggestion till tomorrow, but you can be sure that I am going to try this.
Thank you so much,
Ted Palmer
ASKER
CodeCruiser:
I tried you suggestion and this is what I got. I'm adding a screen shot image of a stack trace and some code. The code first.
From the Logon_clicked event in the form Logon screen:
'2013-01-16 Ted Palmer
'Changed late binding to early binding per Experts-Exchange.
'go_wrdApp = CreateObject("Word.Applica tion")
go_wrdApp = New Microsoft.Office.Interop.W ord.Applic ation()
From the PrintWord_Clicked event in a different form (screen):
go_wrdApp = Marshal.GetActiveObject("W ord.Applic ation")
'***** Debug Code -- Save 2013-01-14 by Ted Palmer
If Not IsNothing(go_wrdApp) Then
'Debug Code -- Save 2013-01-14 by Ted Palmer
MessageBox.Show("go_wrdApp exists", _
"AutoSubrogate® Debug Message:", MessageBoxButtons.OK, MessageBoxIcon.Stop)
GoTo Exit_Point
Else
'Debug Code -- Save 2013-01-14 by Ted Palmer
MessageBox.Show("go_wrdApp does NOT exists", _
"AutoSubrogate® Debug Message:", MessageBoxButtons.OK, MessageBoxIcon.Stop)
GoTo Exit_Point
End If
MarshalDotGetActiveObject.JPG
I tried you suggestion and this is what I got. I'm adding a screen shot image of a stack trace and some code. The code first.
From the Logon_clicked event in the form Logon screen:
'2013-01-16 Ted Palmer
'Changed late binding to early binding per Experts-Exchange.
'go_wrdApp = CreateObject("Word.Applica
go_wrdApp = New Microsoft.Office.Interop.W
From the PrintWord_Clicked event in a different form (screen):
go_wrdApp = Marshal.GetActiveObject("W
'***** Debug Code -- Save 2013-01-14 by Ted Palmer
If Not IsNothing(go_wrdApp) Then
'Debug Code -- Save 2013-01-14 by Ted Palmer
MessageBox.Show("go_wrdApp
"AutoSubrogate® Debug Message:", MessageBoxButtons.OK, MessageBoxIcon.Stop)
GoTo Exit_Point
Else
'Debug Code -- Save 2013-01-14 by Ted Palmer
MessageBox.Show("go_wrdApp
"AutoSubrogate® Debug Message:", MessageBoxButtons.OK, MessageBoxIcon.Stop)
GoTo Exit_Point
End If
MarshalDotGetActiveObject.JPG
ASKER
CodeCruser:
I tried your suggestion and this is what I got. I attached a screen shot of an error message screen from the general exception handler at the end of the Try/Catch for this block of code.
You can see in the first line of the stack trace that it referes to the Marshal.GetActiveObject("W ord.Applic ation"). I have the "go_wrdApp = New Microsoft.Office.Interop.W ord.Applic ation()" statement in a different class. I didn't get an error message about putting this statement in a different class to create the MS-Word program object.
Do I need to import this "System.Runtime.InteropSer vices" in the class where I do the "New" statement? I already added the import where I do the Marshal statement because I got a fatal error message requiring it.
The CLR message was "Operation unavailable".
Thanks for your help,
Ted Palmer
MarshalDotGetActiveObject.JPG
I tried your suggestion and this is what I got. I attached a screen shot of an error message screen from the general exception handler at the end of the Try/Catch for this block of code.
You can see in the first line of the stack trace that it referes to the Marshal.GetActiveObject("W
Do I need to import this "System.Runtime.InteropSer
The CLR message was "Operation unavailable".
Thanks for your help,
Ted Palmer
MarshalDotGetActiveObject.JPG
I don't know why that error is generated.
>go_wrdApp = New Microsoft.Office.Interop.W ord.Applic ation()
This is creating a new word instance anyway. In the class, you just declare the object (I don't know it needs to be in a separate class), then use marshal to get an existing instance and only create new instance if there is no existing instance.
>go_wrdApp = New Microsoft.Office.Interop.W
This is creating a new word instance anyway. In the class, you just declare the object (I don't know it needs to be in a separate class), then use marshal to get an existing instance and only create new instance if there is no existing instance.
ASKER
CodeCruser:
OK! I'll try that. Just FYI -- I may have to change this concept but the 'go_' in go_wrdApp stands for Global Object. It was my intent that I instantiate this program object at logon and make it available throughout the whole application program. I thought it would save some time not having to new up a MS-Word object everytime it was needed, but I have learned since the amount of time saved is trivial. I can be flexible.
Thanks for your help.
Ted Palmer
OK! I'll try that. Just FYI -- I may have to change this concept but the 'go_' in go_wrdApp stands for Global Object. It was my intent that I instantiate this program object at logon and make it available throughout the whole application program. I thought it would save some time not having to new up a MS-Word object everytime it was needed, but I have learned since the amount of time saved is trivial. I can be flexible.
Thanks for your help.
Ted Palmer
ASKER
CodeCruser & sedgwick:
I was able to instantiate the MS-Word program object as described by CodeCruser both ways:
By moving the "go_wrdApp = New Microsoft.Office.Interop.W ord.Applic ation()" into the same class where I was testing the object reference variable with "If Not IsNothing(go_wrdApp) Then" and after adding the import statement to the place from where I was originally instantiating it. But now that I have it instantiated I am having trouble Disposing of it. I guess I'm just not as good of OOP programmer as I thought I am. Anyway trying to reconcile this better method with what I already have in place that basicly works is taking way too much of my time. So I am going to have to split the points, and use sedgwick's method for now as an expediency.
Maybe next time I can start off doing it the better way in the beginning and not have problems disposing of the object when I am finished with it.
Thank you both for your help.
Ted Palmer
I was able to instantiate the MS-Word program object as described by CodeCruser both ways:
By moving the "go_wrdApp = New Microsoft.Office.Interop.W
Maybe next time I can start off doing it the better way in the beginning and not have problems disposing of the object when I am finished with it.
Thank you both for your help.
Ted Palmer
ASKER
Thank you both. I appreciate your patience.
Ted Palmer
Ted Palmer
ASKER
Actually without intending to, I am already doing that twick. Except the Try/Catch block has a lot of source code in it and I didn't think of it as a twick at the time. But that doesn't mean that I can't create a small Try/Catch block just for that purpose. In another function I am already testing the error message returned for "RPC server is unavailable". If it tests true, I execute go_wrdApp = CreateObject("Word.Applica
Thank you for your help.
Ted Palmer