Saturday, June 16, 2007

Threading, Word Interop and processes

A not so nice thing with threading is you can't kill threads running unmanaged (and so Office Interop) code.

A quick and dirty way to handle those things is use the diagnostic library to kill the process with the unmanaged code name. An example with word gives:


using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.Office.Interop.Word;

namespace WordThreadingTest
{
class Program
{
static void Main(string[] args)
{
ApplicationClass apc = new ApplicationClass();
Application app = apc.Application;
object missingValue = Type.Missing;

Thread t = new Thread(RunWord);
string filename = @"D:\My Documents\Visual Studio 2005\Projects\WordThreadingTest\test.rtf";
Console.WriteLine("start thread");
t.Start(app); // Run WriteY on the new thread
Thread.Sleep(50000);
if (t.IsAlive)
{
object myFalse = false;
Console.WriteLine("quit app on main thread");
app.Quit(ref missingValue, ref missingValue, ref missingValue);
t.Abort();
Process[] pProcess;

pProcess = Process.GetProcessesByName("WINWORD");

pProcess[0].Kill();

}
}

private static void RunWord(object application)
{
Application app = (Application) application;
app.DisplayAlerts = WdAlertLevel.wdAlertsNone;
object filename = @"D:\My Documents\Visual Studio 2005\Projects\WordThreadingTest\test.rtf";

// Open the document to print...
object missingValue = Type.Missing;

// use OpenOld so as to be compatible with other versions of
// word
Console.WriteLine("open file");
Document document = app.Documents.OpenOld(ref filename,
ref missingValue, ref missingValue,
ref missingValue, ref missingValue, ref missingValue,
ref missingValue, ref missingValue, ref missingValue,
ref missingValue);


object myTrue = true; // Print in background
object myFalse = false;

app.ActivePrinter = "Adobe PDF";
// Using PrintOutOld to be version independant
Console.WriteLine("print file");
app.ActiveDocument.PrintOutOld(ref myTrue,
ref myFalse, ref missingValue, ref missingValue,
ref missingValue, ref missingValue, ref missingValue,
ref missingValue, ref missingValue, ref missingValue,
ref myFalse, ref missingValue, ref missingValue,
ref missingValue);
Console.WriteLine("close file");
document.Close(ref missingValue, ref missingValue, ref missingValue);

// Make sure all of the documents are gone from the queue
while(app.BackgroundPrintingStatus > 0)
{
Console.WriteLine("waiting...");
Thread.Sleep(250);
}
Console.WriteLine("quit app on thread");
app.Quit(ref missingValue, ref missingValue, ref missingValue);

}
}
}

No comments: