How to get process name and title of the top window on Windows / C#

前端 未结 4 552
故里飘歌
故里飘歌 2020-12-31 14:44

As in the topic... or better - how to get this information from events when the top window changes?

相关标签:
4条回答
  • 2020-12-31 15:04

    I don't think there is a .Net way of doing this, so I think you will have use PInvoke.

    Here's some sample code http://www.pinvoke.net/default.aspx/user32.getforegroundwindow

    And as can be seen in that link there's a project (Managed Windows API) that wraps that up in managed code if you don't want to deal with the PInvoke code yourself.

    0 讨论(0)
  • 2020-12-31 15:07

    You can find window handle by process name using this code:

     Process[] processes = Process.GetProcessesByName(m.ProcessName);
                                        if (processes != null && processes.Length > 0)
                                        {
                                            Process process = processes[0];
                                            process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
                                            process.Refresh();
                                            if (process.MainWindowHandle != IntPtr.Zero)
                                            { // process.mainwindows handle is needed for you
    

    and than you can find window text by handle title = GetWindowTitle(process.MainWindowHandle);

    private String GetWindowTitle(IntPtr hWn)
            {
                object LParam = new object();
                int WParam = 0;
                StringBuilder title = new StringBuilder(1024);
                SendMessage(hWn, WM_GETTEXT, WParam, LParam);
                GetWindowText(hWn, title, title.Capacity);
                return title.ToString();
    
            }
    

    You need following declarations to call winapi functions:

     [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
            internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);
            [DllImport("User32.dll", EntryPoint = "SendMessage")]
            public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, object lParam);
    
    0 讨论(0)
  • 2020-12-31 15:14

    Thanks for hints. So I should use P/Invoke anyhow. Here is the complete code:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace CuckooCoach
    {
        class Monitor
        {
            [DllImport("user32.dll")]
            private static extern IntPtr GetForegroundWindow();
    
            [DllImport("user32.dll")]
            static extern int GetWindowTextLength(IntPtr hWnd);
    
            //  int GetWindowText(
            //      __in   HWND hWnd,
            //      __out  LPTSTR lpString,
            //      __in   int nMaxCount
            //  );
            [DllImport("user32.dll")]
            private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
    
            //  DWORD GetWindowThreadProcessId(
            //      __in   HWND hWnd,
            //      __out  LPDWORD lpdwProcessId
            //  );
            [DllImport("user32.dll")]
            private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    
            //HANDLE WINAPI OpenProcess(
            //  __in  DWORD dwDesiredAccess,
            //  __in  BOOL bInheritHandle,
            //  __in  DWORD dwProcessId
            //);
            [DllImport("kernel32.dll")]
            private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
    
            [DllImport("kernel32.dll")]
            private static extern bool CloseHandle(IntPtr handle);
    
            //  DWORD WINAPI GetModuleBaseName(
            //      __in      HANDLE hProcess,
            //      __in_opt  HMODULE hModule,
            //      __out     LPTSTR lpBaseName,
            //      __in      DWORD nSize
            //  );
            [DllImport("psapi.dll")]
            private static extern uint GetModuleBaseName(IntPtr hWnd, IntPtr hModule, StringBuilder lpFileName, int nSize);
    
            //  DWORD WINAPI GetModuleFileNameEx(
            //      __in      HANDLE hProcess,
            //      __in_opt  HMODULE hModule,
            //      __out     LPTSTR lpFilename,
            //      __in      DWORD nSize
            //  );
            [DllImport("psapi.dll")]
            private static extern uint GetModuleFileNameEx(IntPtr hWnd, IntPtr hModule, StringBuilder lpFileName, int nSize);
    
            public static string GetTopWindowText()
            {
                IntPtr hWnd = GetForegroundWindow();
                int length = GetWindowTextLength(hWnd);
                StringBuilder text = new StringBuilder(length + 1);
                GetWindowText(hWnd, text, text.Capacity);
                return text.ToString();
            }
    
            public static string GetTopWindowName()
            {
                IntPtr hWnd = GetForegroundWindow();
                uint lpdwProcessId;
                GetWindowThreadProcessId(hWnd, out lpdwProcessId);
    
                IntPtr hProcess = OpenProcess(0x0410, false, lpdwProcessId);
    
                StringBuilder text = new StringBuilder(1000);
                //GetModuleBaseName(hProcess, IntPtr.Zero, text, text.Capacity);
                GetModuleFileNameEx(hProcess, IntPtr.Zero, text, text.Capacity);
    
                CloseHandle(hProcess); 
    
                return text.ToString();
            }
    
        }
    }
    
    0 讨论(0)
  • 2020-12-31 15:20

    For the window title, you'll have to do a P/Invoke of GetWindowText with the HWND returned from GetForegroundWindow().

    As for the process info, I believe that P/Invoking GetWindowModuleFileName should work.

    0 讨论(0)
提交回复
热议问题