EnumThreadWindows (user32)
Last changed: Lindos Pechos-205.205.212.238

.
Summary

C# Signature:

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

vb Signature:

<DllImport("user32.dll")>_
Friend Shared Function EnumThreadWindows(dwThreadId as Int32, lpfn as EnumThreadDelegate, lParam as IntPtr) as Boolean
End Function

User-Defined Types:

public delegate bool EnumThreadDelegate (IntPtr hwnd, IntPtr lParam);

Delegate Function EnumThreadDelegate(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean

Notes:

None.

Tips & Tricks:

Please add some!

Sample Code:

[C#]

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace ExitApp
{
    public class ExitApp
    {
        private const UInt32 WM_CLOSE = 0x0010;

        public delegate bool EnumThreadDelegate (IntPtr hWnd, IntPtr lParam);

        [DllImport("user32.dll")]
        static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [STAThread]
        static void Main(string[] args)
        {
            string processName;

            // Find process.
            Process[] p = Process.GetProcessesByName(args[0]);

            if (p.Length > 0)
            {
                foreach(Process proc in p)
                {
                    // Check if main window exists. If the window is minimized to the tray this might be not the case.
                    if (proc.MainWindowHandle == IntPtr.Zero)
                    {
                        // Try closing application by sending WM_CLOSE to all child windows in all threads.
                        foreach (ProcessThread pt in proc.Threads)
                        {
                            EnumThreadWindows((uint) pt.Id, new EnumThreadDelegate(ExitApp.EnumThreadCallback), IntPtr.Zero);
                        }
                    }
                    else
                    {
                        // Try to close main window.
                        if(proc.CloseMainWindow())
                        {
                            // Free resources used by this Process object.
                            proc.Close();
                        }
                    }
                }
            }
        }

        static bool EnumThreadCallback(IntPtr hWnd, IntPtr lParam)
        {
            // Close the enumerated window.
            PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);

            return true;
        }
    }
}

[VisualBasic.Net]

Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Data
Imports System.Diagnostics
Imports System.Runtime.InteropServices
Imports System.Threading

Public Class ExitApp
   Private Const WM_CLOSE As UInt32 = &H10


   Delegate Function EnumThreadDelegate(hWnd As IntPtr, lParam As IntPtr) As Boolean


   <DllImport("user32.dll")>  _
   Shared Function EnumThreadWindows(dwThreadId As UInteger, lpfn As EnumThreadDelegate, lParam As IntPtr) As Boolean
       ' No code here.
   End Function

   <DllImport("user32.dll", SetLastError := True)>  _
   Shared Function PostMessage(hWnd As IntPtr, Msg As UInteger, wParam As IntPtr, lParam As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
       ' No code here.
   End Function

   Public Overloads Shared Sub Main()
     Main(System.Environment.GetCommandLineArgs())
   End Sub


   <STAThread()>  _
   Overloads Shared Sub Main(args() As String)
     Dim processName As String

     ' Find process.
     Dim p As Process() = Process.GetProcessesByName(args(0))

     If p.Length > 0 Then
       For Each proc As Process In p
     ' Check if main window exists. If the window is minimized to the tray this might be not the case.
     If proc.MainWindowHandle = IntPtr.Zero Then
       ' Try closing application by sending WM_CLOSE to all child windows in all threads.
       For Each pt As ProcessThread In proc.Threads
         EnumThreadWindows(CUInt(pt.Id), New EnumThreadDelegate(ExitApp.EnumThreadCallback), IntPtr.Zero)
       Next pt
     Else
       ' Try to close main window.
       If proc.CloseMainWindow() Then
         ' Free resources used by this Process object.
         proc.Close()
       End If
     End If
       Next proc
     End If
   End Sub


   Shared Function EnumThreadCallback(hWnd As IntPtr, lParam As IntPtr) As Boolean
     ' Close the enumerated window.
     PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero)

     Return True
   End Function
End Class

Alternative Managed API:

Do you know one? Please contribute it!

Documentation