Word Automation in VB6 vs .NET

Microsoft Word can be used in VB6 applications to print reports, letters and any other Word document. This post covers issues when dealing with upgraded VB6 applications using Word Automation in .NET.

The Word.Application

Most of the VB6 applications converted to .NET use late-binding to create Word-related objects. This approach will make the application working with Word without depending on the specific MS-Word version installed in the machine. The same happens in .NET: Word-related objects can be constructed at runtime.

In this case, the reference to MS Office Word is included in the application, then consider the next:

For Word 2007, click Microsoft Word 12.0 Object Library. For Word 2003, click Microsoft Word 11.0 Object Library. For Word 2002, click Microsoft Word 10.0 Object Library. For Word 2000, click Microsoft Word 9.0 Object Library.

The Word.Application is the interface that represents the Word Application itself and exposes the functionality to open/create/edit word documents.

Using Word in a Migrated Application

VB6

Dim objWord
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
'open word document
objWord.documents.Open ("Test.docx")

C#

object objWord = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application"));
ReflectionHelper.LetMember(objWord, "Visible", true);
//open word document
ReflectionHelper.Invoke(ReflectionHelper.GetMember(objWord, "documents"), "Open", new object[]{"test.docx"});

VB.NET

Dim objWord As Object
objWord = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application"))
objWord.Visible = True
'open word document
objWord.Documents.Open("test.docx")

Additional resources for Word Automation in .NET at this link.

The WordBasic object issues

This interface returns an automation object (WordBasic) that includes methods for all the WordBasic statements and functions available in Word version 6.0 and Word for Windows 95.

Some VB6 applications may use this interface to access the Word functionality, however, in .NET, some runtime issues may appear when trying to access certain functionality that exists in the WordBasic object.

WordBasic.AppMinimize

This method works in VB6 but not in .NET: Displays Microsoft Word app and then, minimizes the application, showing the icon in the taskbar, but it doesn't work in the same way in .NET:

VB6

Dim gWP As Variant
' See if Word is already open
Set gWP = CreateObject("Word.Basic")
gWP.AppMinimize
gWP.FileOpen "test.docx"

C#

object gWP = null;
//UPGRADE_WARNING: (7008) The ProgId could not be found on computer where this application was migrated
gWP = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Basic"));
ReflectionHelper.Invoke(gWP, "AppMinimize", new object[]{});
ReflectionHelper.Invoke(gWP, "FileOpen", new object[]{"test.docx"});

VB.NET

Dim gWP As Object
'UPGRADE_WARNING: (7008) The ProgId could not be found on computer where this application was migrated
gWP = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Basic"))
ReflectionHelper.Invoke(gWP, "AppMinimize", New Object() {})
ReflectionHelper.Invoke(gWP, "FileOpen", New Object() {"test.docx"})

In .NET, the document is opened, however, the Word Application is not loaded. Unlike VB6, in .NET, the line gWP.AppMinimize() will not open the application and minimize, as the application has not been opened, this can be achieved by using Word.Application object instead and explicitly makes it visible:

Workaround

C#

// See if Word is already open
object gWApp = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application"));
object gWP = null;
gWP = gWApp.WordBasic;

gWApp.Visible = true;
gWApp.WindowState = 2;
'ReflectionHelper.Invoke(gWP, "AppMinimize", New Object() {});**

ReflectionHelper.Invoke(gWP, "FileOpen", New Object() {"test.docx"});

Note: A similar situation happens with WordBasic.AppMaximize().

WordBasic.NextField()

It returns the next field object defined in the word document. This method works when iterating through the list of legacy fields of the document. If no legacy fields are defined in the Word document, then it will throw an exception in .NET if the newest versions of Word Office are installed.

Let's remember WordBasic object is intended to bring support for very legacy Word documents.

Word Automation in .NET Core

COM Interop exceptions may be generated by .NET code targeting .NET Core 3.1 when code uses dynamic type for objects accessing various COM components related to Word/Excel Automation objects. In a Migration project, this scenario may be generated when Word/Excel Automation is used in late-binding variables.

In the above code, the shown exception is thrown by a dynamic variable for the Word.Application object, trying to access ParentWindows property.

This issue was documented on an external site on 2019

In converted code, this may happen if "Static code analysis + dynamic variables" are chosen in the VBUC Late Binding Resolution Upgrade Option.

Possible Workaround

Reflection seems to resolve this issue with dynamic variables, however, it may impact the readability of the code.

The VBUC provides a mechanism to resolve Late Binding objects using the Mobilize ReflectionHelper class.

Last updated