In Windows 7, how to see if MS Word is open

R

Rick

I have an app written in another language but I thought folks here
might be able to help me out with something related to MS Word. In my
app I need to determine if MS Word is open. We've done this for years
using the FindWindowA() API call inside user32.dll, giving it the
string "OpusApp" --

retval = FindWindowA("OpusApp", [nullvalue])

and it's worked fine -- if I get a positive integer back I know Word
is open. But now using Windows 7 (32-bit) I'm getting a positive
value back even if Word is open. Any thoughts? Thanks.
 
R

Rick

Thanks. My language (Powerbuilder) doesn't seem to have anything
similar. Is there a Windows API function besides the FindWindow
series that I could use for this? (Guess I'm not in the right
newsgroup for this; sorry...)

In VBA, I'd use the GetObject function and check the result for an
error, as inhttp://www.word.mvps.org/FAQs/InterDev/ControlWordFromXL.htm

--
Regards,
Jay Freedman
Microsoft Word MVP        FAQ:http://word.mvps.org
Email cannot be acknowledged; please post all follow-ups to the
newsgroup so all may benefit.

I have an app written in another language but I thought folks here
might be able to help me out with something related to MS Word.  In my
app I need to determine if MS Word is open.  We've done this for years
using the FindWindowA() API call inside user32.dll, giving it the
string "OpusApp" --
retval = FindWindowA("OpusApp", [nullvalue])
and it's worked fine -- if I get a positive integer back I know Word
is open.  But now using Windows 7 (32-bit) I'm getting a positive
value back even if Word is open.  Any thoughts?  Thanks.- Hide quoted text -

- Show quoted text -
 
J

Jay Freedman

'GetObject' is a keyword in VB, VBA, and VBScript. It isn't a Windows
API function. Beyond that, though, I don't have any more information.
I'll see if I can interest some of the gurus in showing up to give a
real answer.

Thanks. My language (Powerbuilder) doesn't seem to have anything
similar. Is there a Windows API function besides the FindWindow
series that I could use for this? (Guess I'm not in the right
newsgroup for this; sorry...)

In VBA, I'd use the GetObject function and check the result for an
error, as inhttp://www.word.mvps.org/FAQs/InterDev/ControlWordFromXL.htm

--
Regards,
Jay Freedman
Microsoft Word MVP        FAQ:http://word.mvps.org
Email cannot be acknowledged; please post all follow-ups to the
newsgroup so all may benefit.

I have an app written in another language but I thought folks here
might be able to help me out with something related to MS Word.  In my
app I need to determine if MS Word is open.  We've done this for years
using the FindWindowA() API call inside user32.dll, giving it the
string "OpusApp" --
retval = FindWindowA("OpusApp", [nullvalue])
and it's worked fine -- if I get a positive integer back I know Word
is open.  But now using Windows 7 (32-bit) I'm getting a positive
value back even if Word is open.  Any thoughts?  Thanks.- Hide quoted text -

- Show quoted text -
 
K

Karl E. Peterson

Rick was thinking very hard :
I have an app written in another language but I thought folks here
might be able to help me out with something related to MS Word. In my
app I need to determine if MS Word is open. We've done this for years
using the FindWindowA() API call inside user32.dll, giving it the
string "OpusApp" --

retval = FindWindowA("OpusApp", [nullvalue])

and it's worked fine -- if I get a positive integer back I know Word
is open. But now using Windows 7 (32-bit) I'm getting a positive
value back even if Word is open. Any thoughts? Thanks.

Okay, first off, FindWindows returns a handle. I'm not sure about
PowerBuilder, but in VB(A) this translates to a non-zero value. It may
be either positive or negative. If you're using an unsigned data type,
sure, I guess you could test for >0 for success. But otherwise, I'd
suggest testing <>0 instead.

Second, I don't think this has anything to do with the version of
Windows. I think I've tracked down the window you're finding, and it
appears that Outlook 2007 is loading a window titled "Microsoft Word"
with the classname "OpusApp" into its own process, regardless of
whether or not Outlook is configured to use Word as the email editor.
This, I confirmed using Spy++.

So the question becomes, *why* do you want to know whether Word is
running or not? To illustrate why I ask that, would a call to
IsWindowVisible against the handle returned by FindWindow suit your
needs?

My next suggestion, if you absolutely/positively need to know if
winword.exe is actually executing as its own process, would be to
actually test for that. The details of iterating the process list can
be a bit long, so I'd like to hear first the purpose of your test, to
know whether this would be overkill.

-- Karl
 
J

Jay Freedman

Rick was thinking very hard :
I have an app written in another language but I thought folks here
might be able to help me out with something related to MS Word. In my
app I need to determine if MS Word is open. We've done this for years
using the FindWindowA() API call inside user32.dll, giving it the
string "OpusApp" --

retval = FindWindowA("OpusApp", [nullvalue])

and it's worked fine -- if I get a positive integer back I know Word
is open. But now using Windows 7 (32-bit) I'm getting a positive
value back even if Word is open. Any thoughts? Thanks.

Okay, first off, FindWindows returns a handle. I'm not sure about
PowerBuilder, but in VB(A) this translates to a non-zero value. It may
be either positive or negative. If you're using an unsigned data type,
sure, I guess you could test for >0 for success. But otherwise, I'd
suggest testing <>0 instead.

Second, I don't think this has anything to do with the version of
Windows. I think I've tracked down the window you're finding, and it
appears that Outlook 2007 is loading a window titled "Microsoft Word"
with the classname "OpusApp" into its own process, regardless of
whether or not Outlook is configured to use Word as the email editor.
This, I confirmed using Spy++.

So the question becomes, *why* do you want to know whether Word is
running or not? To illustrate why I ask that, would a call to
IsWindowVisible against the handle returned by FindWindow suit your
needs?

My next suggestion, if you absolutely/positively need to know if
winword.exe is actually executing as its own process, would be to
actually test for that. The details of iterating the process list can
be a bit long, so I'd like to hear first the purpose of your test, to
know whether this would be overkill.

-- Karl

To add one more tidbit, Outlook 2010 also loads a window titled
"Microsoft Word" with the classname "OpusApp", so this behavior isn't
just an Outlook 2007 thing.
 
K

Karl E. Peterson

Jay Freedman explained on 6/30/2010 :
Rick was thinking very hard :
I have an app written in another language but I thought folks here
might be able to help me out with something related to MS Word. In my
app I need to determine if MS Word is open. We've done this for years
using the FindWindowA() API call inside user32.dll, giving it the
string "OpusApp" --

retval = FindWindowA("OpusApp", [nullvalue])

and it's worked fine -- if I get a positive integer back I know Word
is open. But now using Windows 7 (32-bit) I'm getting a positive
value back even if Word is open. Any thoughts? Thanks.

Okay, first off, FindWindows returns a handle. I'm not sure about
PowerBuilder, but in VB(A) this translates to a non-zero value. It may
be either positive or negative. If you're using an unsigned data type,
sure, I guess you could test for >0 for success. But otherwise, I'd
suggest testing <>0 instead.

Second, I don't think this has anything to do with the version of
Windows. I think I've tracked down the window you're finding, and it
appears that Outlook 2007 is loading a window titled "Microsoft Word"
with the classname "OpusApp" into its own process, regardless of
whether or not Outlook is configured to use Word as the email editor.
This, I confirmed using Spy++.

So the question becomes, *why* do you want to know whether Word is
running or not? To illustrate why I ask that, would a call to
IsWindowVisible against the handle returned by FindWindow suit your
needs?

My next suggestion, if you absolutely/positively need to know if
winword.exe is actually executing as its own process, would be to
actually test for that. The details of iterating the process list can
be a bit long, so I'd like to hear first the purpose of your test, to
know whether this would be overkill.

To add one more tidbit, Outlook 2010 also loads a window titled
"Microsoft Word" with the classname "OpusApp", so this behavior isn't
just an Outlook 2007 thing.

Yeah, I was guessing it was likely a lasting change. I don't remember
Outlook 2003 doing it, though. But I never had it configured to use
Word as the email editor, so there may indeed be cases where that
happens too?
 
K

Karl E. Peterson

Rick has brought this to us :
I have an app written in another language but I thought folks here
might be able to help me out with something related to MS Word. In my
app I need to determine if MS Word is open. We've done this for years
using the FindWindowA() API call inside user32.dll, giving it the
string "OpusApp" --

retval = FindWindowA("OpusApp", [nullvalue])

and it's worked fine -- if I get a positive integer back I know Word
is open. But now using Windows 7 (32-bit) I'm getting a positive
value back even if Word is open. Any thoughts? Thanks.

Here's a routine that will search the list of all running processes for
an executable with a given filename. Paths are not considered in this
case. I've indented it here, to illuminate linewrap.

' Process info API declarations - 9x/NT5+
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32"
(ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
Private Declare Function Process32First Lib "kernel32" (ByVal
hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32" (ByVal
hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long

' Toolhelp constants.
Private Const TH32CS_SNAPPROCESS As Long = &H2&
Private Const MAX_PATH As Long = 260

' Uncover process information on 9x/NT5+.
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String * MAX_PATH
End Type


Public Function ExeRunning(ByVal ExeName As String) As Boolean
Dim hSnap As Long
Dim ProcEntry As PROCESSENTRY32
Dim ThisProc As String

' Use the documented methods...
' Make sure we have the needed function.
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)
If hSnap Then
ProcEntry.dwSize = Len(ProcEntry)

' Iterate through the processes once to find the parent:
If Process32First(hSnap, ProcEntry) Then
Do
ThisProc = Left$(ProcEntry.szExeFile,
InStr(ProcEntry.szExeFile, vbNullChar) - 1)
If StrComp(ThisProc, ExeName, vbTextCompare) = 0 Then
ExeRunning = True
Exit Do
End If
Loop While Process32Next(hSnap, ProcEntry)
End If
End If
End Function

For your situation, you'd call it like this:

If ExeRunning("winword.exe") Then

That help?
 
K

Karl E. Peterson

Karl E. Peterson used his keyboard to write :
Rick has brought this to us :
I have an app written in another language but I thought folks here
might be able to help me out with something related to MS Word. In my
app I need to determine if MS Word is open. We've done this for years
using the FindWindowA() API call inside user32.dll, giving it the
string "OpusApp" --

retval = FindWindowA("OpusApp", [nullvalue])

and it's worked fine -- if I get a positive integer back I know Word
is open. But now using Windows 7 (32-bit) I'm getting a positive
value back even if Word is open. Any thoughts? Thanks.

Here's a routine that will search the list of all running processes for an
executable with a given filename. Paths are not considered in this case.
I've indented it here, to illuminate linewrap.

' Process info API declarations - 9x/NT5+
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal
dwFlags As Long, ByVal th32ProcessID As Long) As Long
Private Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As
Long, ByRef lppe As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As
Long, ByRef lppe As PROCESSENTRY32) As Long

' Toolhelp constants.
Private Const TH32CS_SNAPPROCESS As Long = &H2&
Private Const MAX_PATH As Long = 260

' Uncover process information on 9x/NT5+.
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String * MAX_PATH
End Type


Public Function ExeRunning(ByVal ExeName As String) As Boolean
Dim hSnap As Long
Dim ProcEntry As PROCESSENTRY32
Dim ThisProc As String

' Use the documented methods...
' Make sure we have the needed function.
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)
If hSnap Then
ProcEntry.dwSize = Len(ProcEntry)

' Iterate through the processes once to find the parent:
If Process32First(hSnap, ProcEntry) Then
Do
ThisProc = Left$(ProcEntry.szExeFile,
InStr(ProcEntry.szExeFile, vbNullChar) - 1)
If StrComp(ThisProc, ExeName, vbTextCompare) = 0 Then
ExeRunning = True
Exit Do
End If
Loop While Process32Next(hSnap, ProcEntry)
End If
End If
End Function

For your situation, you'd call it like this:

If ExeRunning("winword.exe") Then

That help?

Wow, the *comments* in that snippet make no sense. Obviously(?), the
code was modified from another project, but I didn't get around to
updating the comments to match. Sorry about that. :-(
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top