VSTO – .Net code throws ‘System.AccessViolationException’ error when automating the ‘Find’ object in Word (KB 292744 BUG: Automation client receives an error message or crashes when the client calls the Find object in Word)


Sometimes users are running versions of Office which are not fully
up-to-date. This might be due to the fact that their local IT
department has not tested the new patches and did not approve their
company wide distribution, or because the machine is not connected to
the Internet and needs to be manually updated .. or some other reason. 
At the same time end-users are relying on COM add-ins and stand-alone COM automation programs to help with their daily work.

Later, the machine gets updated (let's suppose its user had Office 2007
SP2 and he installs SP3 and the latest Cumulative Updates). Suddenly he
notices that some of the programs automating Word will crash when performing certain tasks.

Let's assume the user is working with a WindowsForms application 
developed in a managed environment (VB.NET), which uses COM automation
to open a document and perform a Find and Replace action in Word 2007:

  -  everything worked as expected until he updated Office from SP2 to
     SP3;
 
-  after this change, the code started to trigger a 
     'System.AccessViolationException' error when running this code:

Private Sub Test()
   Dim wrd As Microsoft.Office.Interop.Word.Application
     
   wrd = CreateObject("Word.Application")
   wrd.Documents.Open(sFilename)
   wrd.ActiveDocument.Selection.Find.ClearFormatting()

   With wrd.ActiveDocument.Selection.Find
     .Text = "-"
     .Replacement.Text = "-test-"
     .Forward = True
     .Wrap = Microsoft.Office.Interop.Word.WdFindWrap.wdFindContinue
     .Format = True
     .MatchCase = False
     .MatchWholeWord = False
     .MatchWildcards = False
     .MatchSoundsLike = False
     .MatchAllWordForms = False
   End With
  wrd.ActiveDocument.Selection.Find.Execute
     (Replace:=Microsoft.Office.Interop.Word.WdReplace.wdReplaceAll)

End Sub


  - even if we try to comment the "Selection.Find.ClearFormatting()"
    line, any instruction which gets executes inside the WITH block 
    triggers a COM exception: 

Application: sampleApp.exe

Framework Version: v4.0.30319

Description:       The process was terminated due to an unhandled exception.
Exception Info:    System.AccessViolationException

Stack:
   at Microsoft.Office.Interop.Word.Find.set_Style(System.Object
    
 ByRef)
   at Word2WikiPlus.Form1.ConvertHeading(Int64, System.String, 
      System.String)

   at Word2WikiPlus.Form1.Transform(System.String ByRef, Int32)
   at Word2WikiPlus.Form1.Button_start_Click(System.Object,
      System.EventArgs)

   at System.Windows.Forms.Control.OnClick(System.EventArgs)
   at System.Windows.Forms.Button.OnClick(System.EventArgs)
   at System.Windows.Forms.Button.OnMouseUp
      (System.Windows.Forms.MouseEventArgs)

   at System.Windows.Forms.Control.WmMouseUp
      (System.Windows.Forms.Message ByRef,
      System.Windows.Forms.MouseButtons, Int32)

   at System.Windows.Forms.Control.WndProc(System.Windows.Forms.
      Message ByRef)

   at System.Windows.Forms.ButtonBase.WndProc
     (System.Windows.Forms.Message ByRef)

   at System.Windows.Forms.Button.WndProc(System.Windows.Forms.
      Message ByRef)

   at System.Windows.Forms.Control+ControlNativeWindow.OnMessage(
      System.Windows.Forms.Message ByRef)

   at System.Windows.Forms.Control+ControlNativeWindow.WndProc(
      System.Windows.Forms.Message ByRef)

   at System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32,
      IntPtr, IntPtr)

   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG
      ByRef)

   at System.Windows.Forms.Application+ComponentManager.System.
      Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.
      FPushMessageLoop(IntPtr,Int32,Int32)

   at System.Windows.Forms.Application+ThreadContext.RunMessageLoop
      Inner(Int32,System.Windows.Forms.ApplicationContext)

   at System.Windows.Forms.Application+ThreadContext.RunMessageLoop 
      (Int32,System.Windows.Forms.ApplicationContext)

   at Microsoft.VisualBasic.ApplicationServices.
      WindowsFormsApplicationBase.OnRun()

   at Microsoft.VisualBasic.ApplicationServices.
      WindowsFormsApplicationBase.DoApplicationModel()

   at Microsoft.VisualBasic.ApplicationServices.
      WindowsFormsApplicationBase.Run(System.String[])

   at Word2WikiPlus.My.MyApplication.Main(System.String[])

 

This entry appears in Computer Management
                       
> Event Viewer
                         
> Windows Logs 
                            > Application

The description for Event ID 1000 from source .NET Runtime 4.0 Error Reporting cannot be found. Either the component that raises this event is not    installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.

If the event originated on another computer, the display information had to be saved with the event.

The following information was included with the event:

   sampleApp.exe
   0.3.3.0
   4eca4fbc
   oleaut32.dll
   5.1.2600.5512
   4802bdb7
   0
   0007c86c


  -  however, another machine that has also been updated to SP3 can
     successfully run the code;

 

Troubleshooting steps performed

  1. tried to eliminate the .Net layer by writing a small VBscript:

Set objDOCXSourceApp = CreateObject("Word.Application")

objDOCXSourceApp.Visible       = false
objDOCXSourceApp.DisplayAlerts = false

wscript.echo " Open Input file..."

Set objDOCXSourceDoc = objDOCXSourceApp.Documents.Open(<inputPath>)

If Err.Number <> 0 Then
  
objDOCXSourceApp.Application.Quit
  
Set objDOCXSourceDoc = Nothing
  
Set objDOCXSourceApp = Nothing
   wscript.Quit
End If

wscript.echo " File opened OK."

Dim newDocWin
Set newDocWin = objDOCXSourceDoc.ActiveWindow

newDocWin.Selection.Find.ClearFormatting()newDocWin.Selection.Find.Replacement.ClearFormatting()

If Err.Number <> 0 Then
   wscript.Quit
End If

wscript.echo " ClearFormatting .. OK."

With newDocWin.Selection.Find
    
.Text = "-"
   
.Replacement.Text = "-test-"
   
.Forward = True
   
.Wrap = 1 'Microsoft.Office.Interop.Word.WdFindWrap.wdFindContinue
   
.Format = True
   
.MatchCase = False
   
.MatchWholeWord = False
   
.MatchWildcards = False
   
.MatchSoundsLike = False
   
.MatchAllWordForms = False
End With

'WdReplace.wdReplaceAll = 2

newDocWin.Selection.Find.Execute ,,,,,,,,,,2

wscript.echo " newDocWin.Selection.Find.Execute(Replace) .. OK."

objDOCXSourceDoc.Close (False)
objDOCXSourceApp.Application.Quit

Set objDOCXSourceDoc = Nothing
Set objDOCXSourceApp = Nothing

     RESULT: the late binding code works;

  2. Analyzed Fusion logs and ProcMon activity trace;
     RESULT: the correct type libraries seem to be loaded;
 

  3. Researched the Internet;
     RESULT: found t
his article: http://support.microsoft.com/kb/292744;
     The issues which are described are similar to what we experience when  
     working with the Find object, but the error we receive is not listed
     there.

 

BUG: Automation client receives an error message or crashes when the client calls the Find object in Word
http://support.microsoft.com/kb/292744
=======================================================================

...

Symptoms


When you us
e an out-of-process client application that uses early binding to Automate Microsoft Word 97 or later versions of Word, the application may crash with an access violation or you may receive one of the following error messages:

 

From Microsoft Visual Basic:

   > Run-time error '-2147023113 (800706f7)': The method '~' of object '~' failed
  > Run-time error '-2147023113 (800706f7)': 
Method 'Execute' of object 'Find' failed
  >
Run-time error 430: Class does not support automation or does not support expected interface.

From Microsoft Visual C++:

  > HRESULT = 0x800706F7
    RPC_X_BAD_STUB_DATA - The stub received bad data.

Note In debug builds, you receive a corrupt stack warning message from an Assert dialog box, and the value of EAX is that listed above. In release builds, the stack corruption likely crashes the application soon after this point. However, the HRESULT value is likely to be similar to the above.

 

The problem occurs consistently on some computers, but may never occur on others. Installing a new application or a Microsoft Excel service pack can cause a computer that was working previously to experience the problem.

Cause

Several globally unique identifiers (GUIDs) that are used by Word for its interface identifiers were used by Excel 5.0 for an older object model that is now obsolete.

When the Excel 5.0 type library is reregistered on a system, the interface GUIDs in the registry that should point to the Word type library point to the Excel 5.0 library, and COM can mistakenly construct the wrong proxy v-table for an out-of-process client using early binding to Word. Calls that are made to this proxy return errors or crash because the proxy is configured for a dispinterface for Excel instead of for a dispinterface for the expected Word interface.

The following GUIDs are duplicated in the Excel 5.0 type library and the Word 8.0, 8.1, 10.0 and 11.0 type libraries.

The following GUIDs are affected:

  > Word.Replacement interface {000209B1-0000-0000-C000-000000000046}
  > Word.Dictionary            {000209AD-0000-0000-C000-000000000046}
  > Word.ReadabilityStatistics {000209AE-0000-0000-C000-000000000046}
  > Word.ReadabilityStatistic  {000209AF-0000-0000-C000-000000000046}
  > Word.Find                  {000209B0-0000-0000-C000-000000000046}


Resolution


To resolve this problem, use one of the following methods.

• Modify your code to use late binding when you call methods or properties on any of the above listed Word interfaces.
• Reregister the Word type library on the system on which the problem occurs.

The recommended solution is to use late binding. Because both type libraries describe interfaces that implement the IDispatch interface, calls to any of the IDispatch methods work regardless of which library was last registered on the system. This is the only way to be sure that your code does not encounter this error on systems that you do not administer.

 

For customers who use client applications that cannot be recompiled to use late binding, you can reregister the Word type library to resolve the problem in most cases. Because the problem returns if the Excel 5.0 library is reregistered again, this method is not an ideal resolution. However, the chances of the Excel 5.0 library being reregistered are low. Therefore, this method should work for most users.

 

To reregister the Word type library, find the appropriate type library for the version of Word that is installed on the system.

 

Version     Library name
--------------------------------------
Word 97     Msword8.olb
Word 2000   Msword9.olb
Word 2002   Msword.olb
Word 2003   Msword.olb

 

Then, from the command line, use Regtlib.exe together with the full path to the type library to reregister the library for COM. Regtlib.exe calls the LoadTypeLib and RegisterTypeLib application program interfaces (APIs) on the type library (.tlb or .olb) file that is passed in. COM repairs the misconfigured registry keys. 

 

How to solve this issue?

Since the user cannot modify the design of the application, he has to
re-register the Word type library.

C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe "C:\Program Files\Microsoft Office\Office12\MSWORD.OLB"

Caution: 
------------------------------------------------------------------------------
*  If the library registration goes wrong, you might receive 
the
"SEHException was unhandled" message when automating the Find object.

*  The .NET error message is a bit misleading ... in the managed
environment, we didn't get any hint that the is something wrong the 
Find object ("Class does not support automation or does not support
expected interface.
").
 The only clue I could find is this KB: "Troubleshooting Exceptions: System.AccessViolationException"

An access violation that occurs in unsafe managed code can be expressed
as either a NullReferenceException or a AccessViolationException, depending on the platform.
Access violations in unmanaged code that bubble up to managed code are always wrapped in an AccessViolationException.


.. so it appears that if anything goes wrong in the unmanaged code, it will show up as a memory violation in the managed layer.

*  Sometimes, the error surfaces as corrupted memory exceptions:
   > "Attempted to read or write protected memory. This is often
      an indication that other memory is corrupt
";
   > "Es wurde versucht, im geschützten Speicher zu lesen oder
      zu schreiben. Dies ist häufig ein Hinweis darauf, dass
      anderer Speicher beschädigt ist
"
------------------------------------------------------------------------------

Hopefully this blog entry will help you identify and solve the
AccessViolationException error faster.

I would like to thank Mr. Domenico Zanferrari for his valuable
insight and for helping me run my tests in an environment affected
by the aforementioned issue. 
 

 

Thank you for reading my article! Bye 🙂

 

 

Comments (1)

  1. bas says:

    Your solution worked for me. Thank you very much.

Skip to main content