get the titles of all open windows

How can I retrieve the titles of all open windows (including windows such as tabs in Internet Explorer)?


Solution 1:

Something like this:

using System.Diagnostics;

Process[] processlist = Process.GetProcesses();

foreach (Process process in processlist)
{
    if (!String.IsNullOrEmpty(process.MainWindowTitle))
    {
        Console.WriteLine("Process: {0} ID: {1} Window title: {2}", process.ProcessName, process.Id, process.MainWindowTitle);
    }
}

Solution 2:

Here’s some code you can use to get a list of all the open windows. Actually, you get a dictionary where each item is a KeyValuePair where the key is the handle (hWnd) of the window and the value is its title. It also finds pop-up windows, such as those created by MessageBox.Show.

using System.Runtime.InteropServices;
using HWND = System.IntPtr;

/// <summary>Contains functionality to get all the open windows.</summary>
public static class OpenWindowGetter
{
  /// <summary>Returns a dictionary that contains the handle and title of all the open windows.</summary>
  /// <returns>A dictionary that contains the handle and title of all the open windows.</returns>
  public static IDictionary<HWND, string> GetOpenWindows()
  {
    HWND shellWindow = GetShellWindow();
    Dictionary<HWND, string> windows = new Dictionary<HWND, string>();

    EnumWindows(delegate(HWND hWnd, int lParam)
    {
      if (hWnd == shellWindow) return true;
      if (!IsWindowVisible(hWnd)) return true;

      int length = GetWindowTextLength(hWnd);
      if (length == 0) return true;

      StringBuilder builder = new StringBuilder(length);
      GetWindowText(hWnd, builder, length + 1);

      windows[hWnd] = builder.ToString();
      return true;

    }, 0);

    return windows;
  }

  private delegate bool EnumWindowsProc(HWND hWnd, int lParam);

  [DllImport("USER32.DLL")]
  private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);

  [DllImport("USER32.DLL")]
  private static extern int GetWindowText(HWND hWnd, StringBuilder lpString, int nMaxCount);

  [DllImport("USER32.DLL")]
  private static extern int GetWindowTextLength(HWND hWnd);

  [DllImport("USER32.DLL")]
  private static extern bool IsWindowVisible(HWND hWnd);

  [DllImport("USER32.DLL")]
  private static extern IntPtr GetShellWindow();
}

And here’s some code that uses it:

foreach(KeyValuePair<IntPtr, string> window in OpenWindowGetter.GetOpenWindows())
{
  IntPtr handle = window.Key;
  string title = window.Value;

  Console.WriteLine("{0}: {1}", handle, title);
}

Credit: http://www.tcx.be/blog/2006/list-open-windows/

Solution 3:

Based on the previous answer that give me some errors, finaly I use this code with GetOpenedWindows function:

public class InfoWindow
{
            public IntPtr Handle = IntPtr.Zero;
            public FileInfo File = new FileInfo( Application.ExecutablePath );
            public string Title = Application.ProductName;
            public override string ToString() {
                return  File.Name + "\t>\t" + Title;
            }
 }//CLASS

/// <summary>Contains functionality to get info on the open windows.</summary>
public static class RuningWindows
{   
            internal static event EventHandler WindowActivatedChanged;    
            internal static Timer TimerWatcher = new Timer();    
            internal static InfoWindow WindowActive = new InfoWindow();       
            internal static void DoStartWatcher() {
                TimerWatcher.Interval = 500;
                TimerWatcher.Tick += TimerWatcher_Tick;
                TimerWatcher.Start();    
            }                    

            /// <summary>Returns a dictionary that contains the handle and title of all the open windows.</summary>
            /// <returns>A dictionary that contains the handle and title of all the open windows.</returns>
            public static IDictionary<IntPtr , InfoWindow> GetOpenedWindows()
            {
                IntPtr shellWindow = GetShellWindow();
                Dictionary<IntPtr , InfoWindow> windows = new Dictionary<IntPtr , InfoWindow>();

                EnumWindows( new EnumWindowsProc( delegate( IntPtr hWnd , int lParam ) {
                    if ( hWnd == shellWindow ) return true;
                    if ( !IsWindowVisible( hWnd ) ) return true;    
                    int length = GetWindowTextLength( hWnd );
                    if ( length == 0 ) return true;    
                    StringBuilder builder = new StringBuilder( length );
                    GetWindowText( hWnd , builder , length + 1 );    
                    var info = new InfoWindow();
                    info.Handle = hWnd;
                    info.File = new FileInfo( GetProcessPath( hWnd ) );
                    info.Title = builder.ToString();    
                    windows[hWnd] = info;
                    return true;    
                } ) , 0 );    
                return windows;
            }

            private delegate bool EnumWindowsProc( IntPtr hWnd , int lParam );  

            public static string GetProcessPath( IntPtr hwnd )
            {
                uint pid = 0;
                GetWindowThreadProcessId( hwnd , out pid );
                if ( hwnd != IntPtr.Zero ) {
                    if ( pid != 0 ) {
                        var process = Process.GetProcessById( (int) pid );
                        if ( process != null ) {
                            return process.MainModule.FileName.ToString();
                        }
                    }
                }
                return "";
            }    

            [DllImport( "USER32.DLL" )]
            private static extern bool EnumWindows( EnumWindowsProc enumFunc , int lParam );

            [DllImport( "USER32.DLL" )]
            private static extern int GetWindowText( IntPtr hWnd , StringBuilder lpString , int nMaxCount );

            [DllImport( "USER32.DLL" )]
            private static extern int GetWindowTextLength( IntPtr hWnd );

            [DllImport( "USER32.DLL" )]
            private static extern bool IsWindowVisible( IntPtr hWnd );

            [DllImport( "USER32.DLL" )]
            private static extern IntPtr GetShellWindow();

            [DllImport( "user32.dll" )]
            private static extern IntPtr GetForegroundWindow();

            //WARN: Only for "Any CPU":
            [DllImport( "user32.dll" , CharSet = CharSet.Auto , SetLastError = true )]
            private static extern int GetWindowThreadProcessId( IntPtr handle , out uint processId );    


            static void TimerWatcher_Tick( object sender , EventArgs e )
            {
                var windowActive = new InfoWindow();
                windowActive.Handle = GetForegroundWindow();
                string path = GetProcessPath( windowActive.Handle );
                if ( string.IsNullOrEmpty( path ) ) return;
                windowActive.File = new FileInfo( path );
                int length = GetWindowTextLength( windowActive.Handle );
                if ( length == 0 ) return;
                StringBuilder builder = new StringBuilder( length );
                GetWindowText( windowActive.Handle , builder , length + 1 );
                windowActive.Title = builder.ToString();
                if ( windowActive.ToString() != WindowActive.ToString() ) {
                    //fire:
                    WindowActive = windowActive;
                    if ( WindowActivatedChanged != null ) WindowActivatedChanged( sender , e );
                    Console.WriteLine( "Window: " + WindowActive.ToString() );
                }
            }

}//CLASS

Warning: You can only compil/debug under "Any CPU" to access to 32bits Apps...

Solution 4:

you should use the EnumWindow API.

there are plenty of examples on how to use it from C#, I found something here:

Get Application's Window Handles

Issue with EnumWindows

Solution 5:

http://pinvoke.net/default.aspx/user32.EnumDesktopWindows

There is an example of using user.dll's EnumWindow in C# to list all open windows.