I'm creating a new instance of Word using the Office interop by doing this:
var word = Microsoft.Office.Interop.Word.Application();
word.Visible = true;
word.Activate;
I can get a window handle like this:
var wordHandle = Process.GetProcessesByName("winword")[0].MainWindowHandle;
The problem is that code works on the assumption that there's no other instance of Word running. If there are multiple, it can't guarantee that the handle it returns is for the instance that I've launched. I've tried using GetForegroundWindow
after detecting a WindowActivate
event from my object but this is all running within a WPF application that's set to run as the topmost window, so I just get the handle to the WPF window. Are there any other ways to get the handle for my instance of word?
Not sure why you need the handle to Word, but one way I've done this before is to actually change the Word window caption and search for it. I did this because I wanted to host the Word application inside a control, but that's another story. :)
var word = new Microsoft.Office.Interop.Word.Application();
word.Visible = true;
word.Activate();
word.Application.Caption = "My Word";
foreach( Process p in Process.GetProcessesByName( "winword" ) )
{
if( p.MainWindowTitle == "My Word" )
{
Debug.WriteLine( p.Handle.ToString() );
}
}
Once you got the handle, you can restore the caption if you like.
I'll leave the answer I've selected as correct, since it was what I found to work back when I wrote this. I've since needed to do do something similar for a different project and found that trying to update the application caption seemed to be less reliable (Office 2013 vs. 2010? Who knows...). Here's the new solution I've come up with that leaves window captions intact.
var startingProcesses = Process.GetProcessesByName("winword").ToList();
var word = new Microsoft.Office.Interop.Word.Application();
var allProcesses = Process.GetProcessesByName("winword").ToList();
var processDiff = allProcesses.Except(startingProcesses, new ProcessComparer());
var handle = processDiff.First().MainWindowHandle;
This uses the following custom comparer to ensure the processes match (found here).
class ProcessComparer : IEqualityComparer<Process>
{
public bool Equals(Process x, Process y)
{
if (ReferenceEquals(x, y))
{
return true;
}
if (x == null || y == null)
{
return false;
}
return x.Id.Equals(y.Id);
}
public int GetHashCode(Process obj)
{
return obj.Id.GetHashCode();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With