I am working on a vb.net core console app that queries data from a database into a DataTable, opens a Word (.dot) template file, updates some text, and then saves as a .pdf without saving changes to the original template. Word is being very fussy. While debugging, if an exception is thrown, by the time I get to the catch block the Word.Application is gone, so I can't seem to exit gracefully, and apparently an instance is maintained in memory, as I have to reboot my machine to get the program to run again as Word won't start.
Is there a better way to interact with Word?
Here's my code:
Dim application As Word.Application = Nothing
Try
application = New Word.Application With {.Visible = True}
application.Documents.Open("C:\MattsFunctionReport.dot")
Dim document = application.ActiveDocument
'There are lots of these Items, just showing one as an example.
If IsDBNull(row.Item("FunctionName"))
document.Content.Find.Execute(FindText:="<<FunctionName>>", ReplaceWith:="", Replace:=WdReplace.wdReplaceAll)
Else
document.Content.Find.Execute(FindText:="<<FunctionName>>", ReplaceWith:=row.Item("FunctionName"), Replace:=WdReplace.wdReplaceAll)
End If
'save as PDF
application.ActiveDocument.SaveAs2("C:\SampleOutput.pdf", WdSaveFormat.wdFormatPDF)
'Close the document.
application.Documents.Close(WdSaveOptions.wdDoNotSaveChanges)
'Quit Word.Application
application.Quit()
Catch ex As Exception
'Close Word
application.Documents.Close(WdSaveOptions.wdDoNotSaveChanges)
application.Quit()
'Show Exception
ConsoleEx.WriteError(ex.Message)
ConsoleEx.WriteLineInRed(ex.StackTrace)
'Log Exception
WriteLog(ex.ToString)
Console.Writeline("Press any key to exit the program.")
Console.ReadKey()
End
End Try
This is the exception I get when I try to debug again without rebooting.
This is the exception when application.ActiveDocument.SaveAs("C:\SampleOutput.pdf", WdSaveFormat.wdFormatPDF)blows up..
CodePudding user response:
The following shows how to open a .dot
(or .dotx
) Word template using Word interop in a .NET Console App, replace some text, and then export (ie: save) it as a PDF. For testing, I used .NET 6.
Try the following:
Add reference:
- Microsoft Word xx.x Object Library (ex: Microsoft Word 16.0 Object Library)
Add the following Imports statement:
- Imports Word = Microsoft.Office.Interop.Word
ModifyWordDoc:
Private Function ModifyWordDoc(filename As String, pdfFilename As String, Optional isVisible As Boolean = False) As String
Dim wordApp As Word.Application = Nothing
Dim document As Word.Document = Nothing
Try
'create new instance
wordApp = New Word.Application() With {.Visible = isVisible}
'create new document from template
document = wordApp.Documents.Add(Template:=filename)
'ToDo: add desired code
document.Content.Find.Execute(FindText:="<<FunctionName>>", ReplaceWith:="TEST", Replace:=Word.WdReplace.wdReplaceAll)
'export (ie: save) as PDF
document.ExportAsFixedFormat(pdfFilename, Word.WdExportFormat.wdExportFormatPDF)
Return "Successfully completed"
Catch ex As Exception
'ToDo: add desired code
Debug.WriteLine($"Error (ModifyWordDoc) - {ex.Message}")
Finally
If document IsNot Nothing Then
document.Close(Word.WdSaveOptions.wdDoNotSaveChanges)
End If
If wordApp IsNot Nothing Then
wordApp.Quit()
End If
End Try
Return "Unsuccessful"
End Function
Note: You may desire to return an Integer instead of a String.
Usage:
Sub Main(args As String())
Dim filename As String = "C:\Temp\Test.dot"
Dim pdfFilename As String = "C:\Temp\Test.pdf"
Console.WriteLine($"Modifying Word document '{filename}'...")
Dim result As String = ModifyWordDoc(filename, pdfFilename, True)
Debug.WriteLine($"result: {result}")
If result = "Successfully completed" Then
Environment.Exit(0)
Else
Environment.Exit(-1)
End If
End Sub
Resources: