constructor of the class executes, Office raises the Startup event. When the
document is about to be closed, Office raises the Shutdown event.
How Code Gets Unloaded
Your code gets unloaded in a number of ways, depending on the
development pattern you are using. If you are using the automation
executable pattern, your code unloads when the automation executable you
have written exits. If you are using the add-in pattern, your code unloads
when the Office application exits or when the user turns off the add-in via an
add-in management dialog. If you are using the code behind pattern, your
code unloads when the document associated with your code is closed.
In the hosted patterns of running code there is some method that is called
or event that is raised notifying you that you are about to be unloaded. For
COM add-ins, Office calls the OnDisconnection method. For VSTO code
behind documents and Outlook add-ins, Office raises the Shutdown event
before your code is unloaded.
Office Automation Executables
We now consider each of these three patterns of Office solutions in more
detail. Office solutions that use the automation executable pattern start up an
Office application in a very straightforward manner—by creating a new
instance of the Application object associated with the Office application.
Because the automation executable controls the Office application, the
automation executable runs code at startup and any time thereafter when
executing control returns to the automation executable.
When an automation executable uses new to create an Application object,
the automation executable controls the lifetime of the application by holding
the created Application object in a variable. Office determines whether it can
shut down by determining the reference count or number of clients that are
using its Application object.
In Listing 2-1, as soon as
is used to create the myExcelApp variable,
Excel starts and adds one to its count of clients that it knows are holding a
reference to Excel’s Application object. When the myExcelApp variable goes
out of scope (when Main exits) .NET garbage collection releases the object
and Excel is notified that the console application no longer needs Excel’s
Application object. This causes Excel’s count of clients holding a reference
to Excel’s Application object to go to zero and Excel exits as no clients are
using Excel anymore.
When you create an Office application by creating a new instance of the
Application object, the application starts up without showing its window.
This is useful because you can automate the application without distracting
the user by popping up windows. If you need to show the application
window, you can set the Visible property of the Application object to
If you make the main window visible, the user controls the lifetime of the
application. In Excel, the application will not exit until the user quits the
application and your variable holding the Excel Application object is garbage
collected. Word behaves differently—the application exits when the user
quits the application even if a variable is still holding an instance of the Word
Listing 2-1 sets the status bar of Excel to say “Hello World” and opens a
new blank workbook in Excel by calling the Add method of Excel’s
Workbooks collection. Chapters 3 through 5 cover the Excel object model in
Listing 2-1: Automation of a Excel via a console application.
using Excel = Microsoft.Office.Interop.Excel;
static bool exit = false;
static void Main(string args)
Excel.Application myExcelApp = new
myExcelApp.Visible = true;
myExcelApp.StatusBar = "Hello World";
myExcelApp.SheetBeforeDoubleClick += new
while (exit == false)
static void myExcelApp_SheetBeforeDoubleClick(object
Sh, Microsoft.Office.Interop.Excel.Range Target, ref bool
exit = true;
Listing 2-1 also illustrates how an automation executable can yield time
back to the Office application. A reference to the System.Windows.Forms
assembly must be added to the project. After a event handlers are hooked up,
System.Windows.Forms.Application.DoEvents() is called in a loop to allow
the Excel application to run normally. If the user double clicks on a cell,
Office yields time back to the event handler in the automation executable. In
the handler for the double click event, we set the static variable exit to
which will cause the loop calling DoEvents to exit and the automation
executable to exit.
You can see the lifetime management of Excel in action by running the
automation executable in Listing 2-1 and exiting Excel without double
clicking on a cell. Excel will continue to run in a hidden state, waiting for the
console application to release its reference to Excel’s Application object.
Creating a Console Application that Automates Word
In this section, we are going to walk through the creation of a simple
console application that automates Word. A wiki is a kind of online
encyclopedia that users can contribute to. For an example, see
for a wiki that documents the Office PIAs. Wikis
use simple, easy-to-edit text files that any visitor to the wiki can edit without
having to know HTML. These text files have simple representations of even
complex elements like tables. Our console application will read a simple text
file that specifies a table in wiki text format. It will then automate Word to
create a Word table that matches the text file specification.
In the wiki text format, a table that looks like Table 2-1 is specified by
the text in Listing 2-2.
Table 2-1: A simple table showing the properties and methods of Word’s
Listing 2-2: A Wiki text representation of Table 1-4.
||Property or Method||Name||Return Type||
We will use Visual Studio .NET 2005 to create a console application.
After launching Visual Studio, choose New Project… from the File menu.
The new project dialog shows a variety of project types. Select the Visual C#
node from the list of project types and select the Windows node under the
Visual C# node. This is slightly counter intuitive as there is an Office node
available as well, but the Office node only shows VSTO code behind
document projects and the VSTO Outlook add-in project.
After you select the Windows node, you will see in the window to the
right the available templates. Select the Console Application template. Name
your console application project then press the OK button to create your
project. In Figure 2-1 we’ve created a console application called WordWiki.
Note that the new project dialog can have a different appearance than the one
shown in Figure 2-1 depending on the profile you are using. In this book, we
assume you are using the Visual C# Development Settings profile. You can
change your profile by choosing Import and Export Settings… from the Tools
Figure 2-1: Creating a console application from the New Project dialog.
Once you press the OK button, Visual Studio creates a console
application project for you. Visual Studio displays the contents of the project
in the Solution Explorer window as shown in Figure 2-2.
Figure 2-2: The Console application project “WordWiki” shown in Solution
By default, a newly created console application references the assemblies
System, System.Data, and System.Xml. We also need to add a reference to
the Word 2003 PIA. We do this by right clicking on the References folder
and choosing Add Reference… from the popup menu that appears. This
shows the Add Reference dialog in Figure 2-3. Click on the COM tab and
select the Microsoft Word 11.0 Object Library to add a reference to the Word
2003 PIA. Then click the OK button.
Figure 2-3: Adding a reference to the Microsoft Word 2003 PIA.
Visual Studio adds the reference to the Word 2003 PIA and adds
additional references to the stdole, VBIDE, and Microsoft.Office.Core PIAs
as shown in Figure 2-4. These additional PIAs are ones that the Word PIA
depends on. Stdole is a PIA that contains the definition of some of the types
that COM object models need. VBIDE is the PIA for the object model
associated with the VBA editor integrated into Office. Microsoft.Office.Core
(office.dll) is the PIA for common functionality shared by all the Office
applications such as the object model for the toolbars and menus.
Figure 2-4: When you add the Word 2003 PIA, dependent PIA references are
automatically added to the project.
Now that the proper references have been added to our console
application, let’s start writing code. Double click on Program.cs in the
Solution Explorer window to edit the main source code file for the console
application. If you have outlining turned on, you will see the text “using …”
at the top of the Program.cs file with a + sign next to it. Click on the + sign to
expand out the code where the using directives are placed. Add the following
three using directives so we can use objects from the Word PIA and the
Microsoft.Office.Core PIA as well as classes in the System.IO namespace.
using Office = Microsoft.Office.Core;
using Word = Microsoft.Office.Interop.Word;
We are now ready to write some real code that automates Word to create
a table after reading a text input file in the wiki table format. The entire
listing of our program is shown in Listing 2-3. Rather than explain every line
of code in that listing, we will focus on the lines of code that automate Word.
We assume the reader has some knowledge of how to read a text file in .NET
and parse a string via the Split method. We will briefly touch on some objects
in the Word object model here, but Chapters 6 through 8 cover the Word
object model in much more detail.
The first thing we do in Listing 2-3 is declare a new instance of the Word
application object by adding this line of code to Main method of our program
Word.Application theApplication = new Word.Application();
Although Word.Application is an interface, we are allowed to create a
new instance of this interface because the compiler knows that the
Word.Application interface is associated with a COM object that it knows
how to start. When Word starts in response to an automation executable
creating a new instance of its application object, it starts up without showing
any windows. You can automate Word in this invisible state when you want
to automate Word without confusing the user by bringing up the Word
window. For this example, we want to make Word show its main window,
and we do so by adding this line of code:
theApplication.Visible = true;
Next, we want to create a new empty Word document into which we will
generate our table. We do this by calling the Add method on the Documents
collection returned by Word’s application object. The Add method takes four
optional parameters that we want to omit. Optional parameters in Word
methods are specified as omitted by passing by reference a variable
containing the special value Type.Missing. We declare a variable called
that we set to Type.Missing and pass it by reference to each
parameter we wish to omit as shown here:
object missing = Type.Missing;
Word.Document theDocument = theApplication.Documents.Add(
With a document created, we want to read the input text file specified by
the command line argument passed to our console application. We want to
parse that text file to calculate the number of columns and rows. Once we
know the number of columns and rows, we use the line of code below to get a
Range object from the Document object. By passing our
the optional parameters, the Range method will return a range that includes
the entire text of the document.
Word.Range range = theDocument.Range(ref missing, ref
We then use our Range object to add a table by calling the Add method of
the Tables collection returned by the Range object. We pass the Range object
again as the first parameter to the Add method to specify that we want to
replace the entire contents of the document with the table. We also specify
the number of rows and columns we want.
Word.Table table = range.Tables.Add(
The Table object has a Cell method that takes a row and column and
returns a Cell object. The Cell object has a Range property that returns a
Range object for the cell in question that we can use to set the text and
formatting of the cell. The code that sets the cells of the table is shown
below. Note that as in most of the Office object models, the indices are 1-
based meaning they start with one as the minimum value rather than being 0-
based and starting with zero as the minimum value.
for (columnIndex = 1; columnIndex <= columnCount;
Word.Cell cell = table.Cell(rowIndex, columnIndex);
cell.Range.Text = splitRow[columnIndex];
Code to set the formatting of the table by setting the table to size to fit
contents and bolding the header row is shown below. We use the Row object
which also has a Range property that returns a
Range object for the row in question. Also, we encounter code that sets the
first row of the table to be bolded. One would expect to be able to write the
table.Rows.Range.Bold = true
, but Word’s object model
value (0 or 1) rather than a
. This is one of many
examples you will come across where the Office object models don’t match
.NET guidelines because of their origins in COM.
// Format table
table.Rows.Range.Bold = 1;
Documents you may be interested
Documents you may be interested