I am exporting word documents to PDFs using the interop word library in a multi-threaded WPF application and then convert them to PNGs using MagickNet library.
private void generateImagesFromOfficeDoc(Document currentDocument, CustomThread thread = null)
{
var token = tokenSource.Token;
Microsoft.Office.Interop.Word.Application wordApplication = null;
string[] filePath = currentDocument.OriginalPath.Split('\\');
currentDocument.Filename = filePath[filePath.Length - 1].Trim();
string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(currentDocument.Filename).Trim();
string destinationPath;
destinationPath = pngPath + "\\" + currentDocument.CreatedDate.Year.ToString() + "\\" + currentDocument.Specialty + "\\" + currentDocument.CreatedDate.Month + "\\" +
currentDocument.CreatedDate.Day + "\\" + fileNameWithoutExtension;
string pdfPath = magickNETTempDir + "\\" + fileNameWithoutExtension + ".pdf";
string pdfName = fileNameWithoutExtension + ".pdf";
string tempFile = magickNETTempDir + "\\" + currentDocument.Filename;
try
{
// Copying the file from the original location to the temp folder. ** This is because impersonation have issues with the interop library.
File.Copy(currentDocument.OriginalPath, tempFile);
// Create the directory if it does not exist.
if (!Directory.Exists(destinationPath))
{
Directory.CreateDirectory(destinationPath);
}
/************ CONVERTING THE DOCUMENT TO PDF ***************/
wordApplication = new Microsoft.Office.Interop.Word.Application();
// Opening the word document
var wordDocument = wordApplication.Documents.Open(tempFile);
var pageCount = wordDocument.ComputeStatistics(Microsoft.Office.Interop.Word.WdStatistic.wdStatisticPages, false);
// Exporting the document to the PDF
wordDocument.ExportAsFixedFormat(pdfPath, Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF);
// Closing the document and the application.
((Microsoft.Office.Interop.Word._Document)wordDocument).Close(false);
((Microsoft.Office.Interop.Word._Application)wordApplication).Quit(false);
}
Each thread opens up a word application and is supposed to close it after exporting the document. In the same method, I convert the exported PDF to PNG and then delete the temporary PDF (Code is excluded as I think it is not related to the issue).
The process does its work but since I am converting thousands of documents, I get quite a lot of word processes in the background eating up my RAM. The processes do close themselves eventually but it is very slow and thus I end up with more and more of the processes in the background. This does not happen on all machines and also not on every document so I am not sure what is going wrong.
Is there a way of closing them forcefully? I have tried the method of killing the processes by their name but that requires the application window to be visible which is something I don't want.
I have run into similar problems when using the Microsoft.Office.Interop.Excel
dll. I found out that I had to release all of the COM objects that I had been using before Excel
would disappear from the Windows Task Manager Processes tab. To be clear, I'd close the application, but its process would remain visible in the Task Manager until I released the COM objects. Try something like this:
private void ReleaseComObjects(bool isQuitting)
{
try
{
if (isQuitting)
{
workbook.Close(false, missing, missing);
excelApplication.Quit();
}
Marshal.ReleaseComObject(workbooks);
Marshal.ReleaseComObject(workbook);
if (worksheets != null) Marshal.ReleaseComObject(worksheets);
Marshal.ReleaseComObject(worksheet);
Marshal.ReleaseComObject(excelApplication);
workbook = null;
worksheets = null;
worksheet = null;
excelApplication = null;
}
catch { }
finally { GC.Collect(); }
}
private void ReleaseComObjects()
{
ReleaseComObjects(false);
}