closing all applicatios vs processes

C

cj

I know how to write code to find, kill and closeMainWindow on all
processes but I really don't want to do that. I want work with
applications not processes. As you know there are a lot more processes
running than applications and many processes are critical to Windows
running. For instance right now Task Manger show 3 applications running
on my computer but maybe 40 processes.

How can I do this?
 
W

Walter Wang [MSFT]

Hi,

First of all, the Task Manager's Applications tab shows the captions of
visible, top-level windows. The Task Manager builds this list by walking
through all of the top-level windows in the system (using something like
EnumWindows), and adds to the list the windows that have the WS_VISIBLE
style bit turned on.

I've created a simple WinForm application to demonstrate how to get the
window list as shown in Task Manager:

1) Create a simple Windows Application using VB.NET
2) Add a ListBox (set its "Sorted" to true) and a Button to the default
WinForm
3) Paste following code in the default WinForm's class:

Delegate Function EnumWindowsProc(ByVal hWnd As System.IntPtr, ByVal
lParam As IntPtr) As Boolean

Declare Auto Function EnumWindows Lib "user32" (ByVal lpEnumFunc As
EnumWindowsProc, ByVal lParam As IntPtr) As Boolean
Declare Auto Function IsWindowVisible Lib "user32" (ByVal hWnd As
IntPtr) As Boolean
Declare Auto Function GetWindowText Lib "user32" (ByVal hwnd As IntPtr,
ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer
Declare Auto Function GetWindowTextLength Lib "user32" (ByVal hwnd As
IntPtr) As Integer

Declare Auto Function SendMessage Lib "user32" (ByVal hWnd As IntPtr,
ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As
Integer
Const WM_CLOSE As Integer = &H10

Private Function MyEnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam
As IntPtr) As Boolean
If IsWindowVisible(hWnd) Then
Dim buffLen As Integer = GetWindowTextLength(hWnd)
Dim sb As New StringBuilder(buffLen + 1)
GetWindowText(hWnd, sb, sb.Capacity)
Dim caption As String = sb.ToString()
If (caption.Length > 0) Then
ListBox1.Items.Add(caption)
End If
End If
Return True
End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
EnumWindows(AddressOf MyEnumWindowsProc, IntPtr.Zero)
End Sub

To close the window using window handle ("hWnd" in MyEnumWindowsProc), you
can use:

SendMessage(hWnd, WM_CLOSE, 0, 0)

Hope this helps. Please feel free to post here if anything is unclear.

Sincerely,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
C

cj

Actually it shows more applications than task manager does. I'll have
to do some experimenting on the specific app I want to close.
 
C

cj

This seems to work for listing programs showing in the task bar

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim targets() As System.Diagnostics.Process
Dim target As System.Diagnostics.Process
targets = System.Diagnostics.Process.GetProcesses
For Each target In targets
If target.MainWindowTitle <> "" Then
ListBox1.Items.Add(target.MainWindowTitle)
End If
Next
End Sub
 
W

Walter Wang [MSFT]

Hi,

Your method using System.Diagnostics.Process.GetProcesses will only show
the main window of each process. If a process has multiple top-level
windows, for example, if you open a Outlook 2003 email window, it shows
multiple windows for Outlook in Task Manager.

It seems Task Manager will not show window that has no caption, and it will
not show dialogs displayed using RunDll32, such as the System Properties
dialog, the Add/Remove dialog, etc. Using EnumWindows will find them
correctly. I think if your intention is to find them and close them, then
using my method will do the job.

Hope this helps. Please feel free to post here if anything is unclear.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
C

cj

Take right now. I have running and showing in the task bar:
-Thunderbird
-VB 2003 with my program running
-my program which is being run in debug mode
-this email being composed

process showing only those with main windows gives me:
-VB 2003
-my program
-this email being composed

It doesn't show the main thunderbird app. But enumwindows is turning up
strange results too.

When I run your code I get:
-thunderbird
-2 identically named listings for VB 2003
-my program
-this email
-program manager

Hummmm....

Anyway, I need to shutdown one specific program and thankfully it isn't
like thunderbird with other windows--although I could loop after closing
each time to see if it is still listed which I tested with
thunderbird--so process is working for identifying the app I want to
close and closing it via close main window. It's a lot less code too.

Thanks for the input enumwindows might be useful in the future.
 
W

Walter Wang [MSFT]

Hi,

Thank you for your update.

How the Task Manager get the window list is undocumented. A reasonable
heuristic is windows which are visible, which do not have an owner, and
which do have a caption. My previous code is missing the condition "do not
have an owner". To get the owner of a window, we can use "GetWindow()" with
GW_OWNER as parameter.

Then we have to deal with the window "Program Manager": it's still present
for reasons of compatibility. We can ignore it by checking its window class
name: "Progman".

So the complete code listing would be:

Delegate Function EnumWindowsProc(ByVal hWnd As System.IntPtr, ByVal
lParam As IntPtr) As Boolean

Declare Auto Function EnumWindows Lib "user32" (ByVal lpEnumFunc As
EnumWindowsProc, ByVal lParam As IntPtr) As Boolean
Declare Auto Function IsWindowVisible Lib "user32" (ByVal hWnd As
IntPtr) As Boolean
Declare Auto Function GetWindowText Lib "user32" (ByVal hwnd As IntPtr,
ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer
Declare Auto Function GetWindowTextLength Lib "user32" (ByVal hwnd As
IntPtr) As Integer
Declare Auto Function GetWindowLong Lib "user32.dll" (ByVal hwnd As
IntPtr, ByVal nIndex As Int32) As Int32
Declare Auto Function GetParent Lib "user32" (ByVal hwnd As IntPtr) As
IntPtr
Declare Auto Function GetWindow Lib "user32" (ByVal hwnd As IntPtr,
ByVal wCmd As Int32) As IntPtr
Const GW_OWNER As Int32 = 4
Declare Auto Function GetClassName Lib "user32" (ByVal hwnd As IntPtr,
ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer

Declare Auto Function SendMessage Lib "user32" (ByVal hWnd As IntPtr,
ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As
Integer
Const WM_CLOSE As Integer = &H10


Function GetWindowOwner(ByVal hwnd As IntPtr) As IntPtr
Return GetWindow(hwnd, GW_OWNER)
End Function

Function GetWindowCaption(ByVal hwnd As IntPtr) As String
Dim buffLen As Integer = GetWindowTextLength(hwnd)
Dim sb As New StringBuilder(buffLen + 1)
GetWindowText(hwnd, sb, sb.Capacity)
Return sb.ToString()
End Function

Function GetWindowClass(ByVal hwnd As IntPtr) As String
Dim sb As New StringBuilder(256)
GetClassName(hwnd, sb, sb.Capacity)
Return sb.ToString()
End Function

Private Function MyEnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam
As IntPtr) As Boolean
If IsWindowVisible(hWnd) AndAlso GetWindowOwner(hWnd).ToInt32() = 0
AndAlso GetWindowClass(hWnd) <> "Progman" Then
Dim caption As String = GetWindowCaption(hWnd)
If (caption.Length > 0) Then
ListBox1.Items.Add(caption)
End If
End If
Return True
End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
ListBox1.Items.Clear()
EnumWindows(AddressOf MyEnumWindowsProc, IntPtr.Zero)
End Sub

Hope this helps. Please feel free to post here if anything is unclear.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
C

cj

Thanks.

Hi,

Thank you for your update.

How the Task Manager get the window list is undocumented. A reasonable
heuristic is windows which are visible, which do not have an owner, and
which do have a caption. My previous code is missing the condition "do not
have an owner". To get the owner of a window, we can use "GetWindow()" with
GW_OWNER as parameter.

Then we have to deal with the window "Program Manager": it's still present
for reasons of compatibility. We can ignore it by checking its window class
name: "Progman".

So the complete code listing would be:

Delegate Function EnumWindowsProc(ByVal hWnd As System.IntPtr, ByVal
lParam As IntPtr) As Boolean

Declare Auto Function EnumWindows Lib "user32" (ByVal lpEnumFunc As
EnumWindowsProc, ByVal lParam As IntPtr) As Boolean
Declare Auto Function IsWindowVisible Lib "user32" (ByVal hWnd As
IntPtr) As Boolean
Declare Auto Function GetWindowText Lib "user32" (ByVal hwnd As IntPtr,
ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer
Declare Auto Function GetWindowTextLength Lib "user32" (ByVal hwnd As
IntPtr) As Integer
Declare Auto Function GetWindowLong Lib "user32.dll" (ByVal hwnd As
IntPtr, ByVal nIndex As Int32) As Int32
Declare Auto Function GetParent Lib "user32" (ByVal hwnd As IntPtr) As
IntPtr
Declare Auto Function GetWindow Lib "user32" (ByVal hwnd As IntPtr,
ByVal wCmd As Int32) As IntPtr
Const GW_OWNER As Int32 = 4
Declare Auto Function GetClassName Lib "user32" (ByVal hwnd As IntPtr,
ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer

Declare Auto Function SendMessage Lib "user32" (ByVal hWnd As IntPtr,
ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As
Integer
Const WM_CLOSE As Integer = &H10


Function GetWindowOwner(ByVal hwnd As IntPtr) As IntPtr
Return GetWindow(hwnd, GW_OWNER)
End Function

Function GetWindowCaption(ByVal hwnd As IntPtr) As String
Dim buffLen As Integer = GetWindowTextLength(hwnd)
Dim sb As New StringBuilder(buffLen + 1)
GetWindowText(hwnd, sb, sb.Capacity)
Return sb.ToString()
End Function

Function GetWindowClass(ByVal hwnd As IntPtr) As String
Dim sb As New StringBuilder(256)
GetClassName(hwnd, sb, sb.Capacity)
Return sb.ToString()
End Function

Private Function MyEnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam
As IntPtr) As Boolean
If IsWindowVisible(hWnd) AndAlso GetWindowOwner(hWnd).ToInt32() = 0
AndAlso GetWindowClass(hWnd) <> "Progman" Then
Dim caption As String = GetWindowCaption(hWnd)
If (caption.Length > 0) Then
ListBox1.Items.Add(caption)
End If
End If
Return True
End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
ListBox1.Items.Clear()
EnumWindows(AddressOf MyEnumWindowsProc, IntPtr.Zero)
End Sub

Hope this helps. Please feel free to post here if anything is unclear.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 

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