PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Visual Studio 2008/VBAutomateWord/ReadMe.txt

#
Plain Text | 226 lines | 171 code | 55 blank | 0 comment | 0 complexity | c43f681330bd27a6cdc91f4d25aa2dfe MD5 | raw file
  1. ========================================================================
  2. CONSOLE APPLICATION : VBAutomateWord Project Overview
  3. ========================================================================
  4. /////////////////////////////////////////////////////////////////////////////
  5. Summary:
  6. The VBAutomateWord example demonstrates the use of Visual Basic.NET codes to
  7. create a Microsoft Word instance, create a new document, insert a paragraph
  8. and a table, save the document, close the Microsoft Word application and then
  9. clean up unmanaged COM resources.
  10. Office automation is based on Component Object Model (COM). When you call a
  11. COM object of Office from managed code, a Runtime Callable Wrapper (RCW) is
  12. automatically created. The RCW marshals calls between the .NET application
  13. and the COM object. The RCW keeps a reference count on the COM object. If
  14. all references have not been released on the RCW, the COM object of Office
  15. does not quit and may cause the Office application not to quit after your
  16. automation. In order to make sure that the Office application quits cleanly,
  17. the sample demonstrates two solutions.
  18. Solution1.AutomateWord demonstrates automating Microsoft Word application by
  19. using Microsoft Word Primary Interop Assembly (PIA) and explicitly assigning
  20. each COM accessor object to a new varaible that you would explicitly call
  21. Marshal.FinalReleaseComObject to release it at the end.
  22. Solution2.AutomateWord demonstrates automating Microsoft Word application by
  23. using Microsoft Word PIA and forcing a garbage collection as soon as the
  24. automation function is off the stack (at which point the RCW objects are no
  25. longer rooted) to clean up RCWs and release COM objects.
  26. /////////////////////////////////////////////////////////////////////////////
  27. Prerequisite:
  28. You must run this code sample on a computer that has Microsoft Word 2007
  29. installed.
  30. /////////////////////////////////////////////////////////////////////////////
  31. Demo:
  32. The following steps walk through a demonstration of the Word automation
  33. sample that starts a Microsoft Word instance, creates a new document,
  34. inserts a paragraph and a table, saves the document, and quits the Microsoft
  35. Word application cleanly.
  36. Step1. After you successfully build the sample project in Visual Studio 2008,
  37. you will get the application: VBAutomateWord.exe.
  38. Step2. Open Windows Task Manager (Ctrl+Shift+Esc) to confirm that no
  39. winword.exe is running.
  40. Step3. Run the application. It should print the following content in the
  41. console window if no error is thrown.
  42. Word.Application is started
  43. A new document is created
  44. Insert a paragraph
  45. Save and close the document
  46. Quit the Word application
  47. Word.Application is started
  48. Insert a paragraph
  49. Insert a table
  50. Save and close the document
  51. Quit the Word application
  52. Then, you will see two new documents in the directory of the application:
  53. Sample1.docx and Sample2.docx. Both documents have the following content.
  54. Heading 1
  55. Sample2.docx additionally has this table in the document.
  56. r1c1 r1c2
  57. r2c1 r2c2
  58. r3c1 r3c2
  59. r4c1 r4c2
  60. r5c1 r5c2
  61. Step4. In Windows Task Manager, confirm that the winword.exe process does not
  62. exist, i.e. the Microsoft Word intance was closed and cleaned up properly.
  63. /////////////////////////////////////////////////////////////////////////////
  64. Project Relation:
  65. VBAutomateWord - CSAutomateWord - CppAutomateWord
  66. These examples automate Microsoft Word to do the same thing in different
  67. programming languages.
  68. /////////////////////////////////////////////////////////////////////////////
  69. Creation:
  70. Step1. Create a Console application and reference the Word Primary Interop
  71. Assembly (PIA). To reference the Word PIA, right-click the project file
  72. and click the "Add Reference..." button. In the Add Reference dialog,
  73. navigate to the .NET tab, find Microsoft.Office.Interop.Word 12.0.0.0 and
  74. click OK.
  75. Step2. Import and rename the Excel interop namepace:
  76. Imports Word = Microsoft.Office.Interop.Word
  77. Step3. Start up a Word application by creating a Word.Application object.
  78. oWord = New Word.Application()
  79. Step4. Get the Documents collection from Application.Documents and call its
  80. Add function to create a new document. The Add function returns a Document
  81. object.
  82. Step5. Insert a paragraph.
  83. oParas = oDoc.Paragraphs
  84. oPara = oParas.Add()
  85. oParaRng = oPara.Range
  86. oParaRng.Text = "Heading 1"
  87. oFont = oParaRng.Font
  88. oFont.Bold = 1
  89. oParaRng.InsertParagraphAfter()
  90. Step6. Insert a table.
  91. The following code has the problem that it invokes accessors which will also
  92. create RCWs and reference them. For example, calling Document.Bookmarks.Item
  93. creates an RCW for the Bookmarks object. If you invoke these accessors via
  94. tunneling as this code does, the RCWs are created on the GC heap, but the
  95. references are created under the hood on the stack and are then discarded. As
  96. such, there is no way to call MarshalFinalReleaseComObject on those RCWs. To
  97. get them to release, you would either need to force a garbage collection as
  98. soon as the calling function is off the stack (at which point these objects
  99. are no longer rooted) and then call GC.WaitForPendingFinalizers, or you would
  100. need to change the syntax to explicitly assign these accessor objects to a
  101. variable that you would then explicitly call Marshal.FinalReleaseComObject on.
  102. oBookmarkRng = oDoc.Bookmarks.Item("\endofdoc").Range
  103. oTable = oDoc.Tables.Add(oBookmarkRng, 5, 2)
  104. oTable.Range.ParagraphFormat.SpaceAfter = 6
  105. For r As Integer = 1 To 5
  106. For c As Integer = 1 To 2
  107. oTable.Cell(r, c).Range.Text = "r" & r & "c" & c
  108. Next
  109. Next
  110. ' Change width of columns 1 & 2
  111. oTable.Columns(1).Width = oWord.InchesToPoints(2)
  112. oTable.Columns(2).Width = oWord.InchesToPoints(3)
  113. Step7. Save the document as a docx file and close it.
  114. Dim fileName As String = Path.GetDirectoryName( _
  115. Assembly.GetExecutingAssembly().Location) & "\Sample1.docx"
  116. oDoc.SaveAs(fileName, Word.WdSaveFormat.wdFormatXMLDocument)
  117. oDoc.Close()
  118. Step8. Quit the Word application.
  119. oWord.Quit(False)
  120. Step9. Clean up the unmanaged COM resource. To get Word terminated rightly,
  121. we need to call Marshal.FinalReleaseComObject() on each COM object we used.
  122. We can either explicitly call Marshal.FinalReleaseComObject on all accessor
  123. objects:
  124. ' See Solution1.AutomateWord
  125. If Not oFont Is Nothing Then
  126. Marshal.FinalReleaseComObject(oFont)
  127. oFont = Nothing
  128. End If
  129. If Not oParaRng Is Nothing Then
  130. Marshal.FinalReleaseComObject(oParaRng)
  131. oParaRng = Nothing
  132. End If
  133. If Not oPara Is Nothing Then
  134. Marshal.FinalReleaseComObject(oPara)
  135. oPara = Nothing
  136. End If
  137. If Not oParas Is Nothing Then
  138. Marshal.FinalReleaseComObject(oParas)
  139. oParas = Nothing
  140. End If
  141. If Not oDoc Is Nothing Then
  142. Marshal.FinalReleaseComObject(oDoc)
  143. oDoc = Nothing
  144. End If
  145. If Not oDocs Is Nothing Then
  146. Marshal.FinalReleaseComObject(oDocs)
  147. oDocs = Nothing
  148. End If
  149. If Not oWord Is Nothing Then
  150. Marshal.FinalReleaseComObject(oWord)
  151. oWord = Nothing
  152. End If
  153. and/or force a garbage collection as soon as the calling function is off the
  154. stack (at which point these objects are no longer rooted) and then call
  155. GC.WaitForPendingFinalizers.
  156. ' See Solution2.AutomateWord
  157. GC.Collect()
  158. GC.WaitForPendingFinalizers()
  159. ' GC needs to be called twice in order to get the Finalizers called
  160. ' - the first time in, it simply makes a list of what is to be
  161. ' finalized, the second time in, it actually is finalizing. Only
  162. ' then will the object do its automatic ReleaseComObject.
  163. GC.Collect()
  164. GC.WaitForPendingFinalizers()
  165. /////////////////////////////////////////////////////////////////////////////
  166. References:
  167. MSDN: Word 2007 Developer Reference
  168. http://msdn.microsoft.com/en-us/library/bb244391.aspx
  169. How to automate Word from Visual Basic .NET to create a new document
  170. http://support.microsoft.com/kb/316383/
  171. /////////////////////////////////////////////////////////////////////////////