Context:
Microsoft Visual Studio 2005 Version 8.0.50727.42
Microsoft .NET Framework Version 2.0.50727
Word 2003 Interop
Problem:
I am trying to recreate the "AmbiguousMember" example from p. 31 of Whitechapel's "MS .NET Development for MS Office" using VB instead of VC#.
This involves implementing an event handler for the Word Quit event. In the event handler, I need to toggle the Enabled state of two buttons. This causes the following error:
A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
The code behind the Form1 form is shown below. Form1 has two buttons: Button1 "Run Word"; Button2 "Quit Word". The event handler is intended to clean up if the user quits the Word application, and reset the buttons.
A net search indicates a known source of this error involves use of "MTA" apartment threading model instead of "STA". I can't figure out how the threading model is set in my VB project.
I dunno why this post is doublespaced.
Imports
Word = Microsoft.Office.Interop.WordPublic
Class Form1Private wd As Word.Application Public wdEvents4 As Word.ApplicationEvents4_Event Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
wd =
New Word.Applicationwd.Visible =
TruewdEvents4 =
CType(wd, Word.ApplicationEvents4_Event) AddHandler wdEvents4.Quit, AddressOf Me.quitHandlerButton2.Enabled =
TrueButton1.Enabled =
False End Sub Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.ClickRemoveHandler wdEvents4.Quit, AddressOf Me.quitHandler
wd.Quit()
wd =
NothingButton1.Enabled =
TrueButton2.Enabled =
FalseGC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
End Sub Private Sub quitHandler()"In wdEvents4_Quit")Debug.Print(
wd =
NothingButton1.Enabled =
TrueButton2.Enabled =
False End SubEnd
Class

Word Interop - System.InvalidOperationException in System.Windows.Forms.dll
RostaB
Update
OK, here is a solution. As described in this article , if I use the "Invoke" method on the Button1 and Button2 calls in the quitHandler, it works.
In quitHandler, replace
with
Button1.Invoke(CType(AddressOf Button1Enable, MethodInvoker))where Button1Enable is just
Private Sub Button1Enable()End Sub
Likewise for Button2.
ntsoo
Here is some additional information. When I catch the exception that occurs in the quitHandler, the message text says
So this does appear to be related to a threading model issue. I tried to fix it by
1) Adding a sub main with <STAThread()> attribute in my Form1 class as follows
Public Shared Sub Main() New Form1()) End Sub2) In the Application Properties (Application tab), I unchecked the "Enable application framework" button so that I could change the Startup object to "Sub Main".
I still get the same error.
mshvw
Update
1) I looked at properties of the CurrentThread inside the Button1_Click and quitHandler methods. The thread executing Button1_Click is already set to ApartmentState.STA. There was no need for me to add the Sub Main and STAThread attribute. This puzzles me because I have seen in a half dozen places that managed threads are started MTA. There are, however, some hits on STA being required for System.Windows.Forms apps, so something is happening behind the scenes to make it STA.
2) The caller of quitHandler, who I assume is the Runtime Callable Wrapper (RCW) around my wdEvents4 ref, is running MTA. I guess this means it thinks it can execute anything it finds in there without marshaling, and when it tries to I get the exception.
3) Setting the MTAThread attribute on Sub Main does not help. I think I'm hitting the System.Windows.Forms STA issue there.
Perhaps if I had some way of starting the RCW as STA, then when it calls the quitHandler the runtime will handle the marshaling
This is obviously just a learning exercise for me, but would appreciate any ideas.