Войти все Windows, которые закрыты в Windows - PullRequest
2 голосов
/ 27 декабря 2011

Я хочу создать расширение оболочки или приложение в .NET, которое регистрирует все закрытые окна.Журнал должен содержать имя процесса, который создал окно.

У меня нет идей, как это сделать.Есть указатели?

Ответы [ 3 ]

5 голосов
/ 27 декабря 2011

Для этого требуется перехват, установленный SetWindowsHookEx, тип перехвата WH_SHELL.Этот тип ловушки требует DLL, которая может быть внедрена в процесс, такая DLL не может быть написана на C #.64-разрядная операционная система и UAC также создадут множество препятствий. Этот проект может помочь.

3 голосов
/ 28 декабря 2011

Хотя вы, безусловно, можете подключать программы, это действительно кажется излишним для того, что вы хотите сделать. Этот код должен вас ОЧЕНЬ близко (вам придется сделать что-то еще для запроса процесса проводника Windows для его текущего каталога, я этого не делал). Кроме того, мои потребности отличаются от ваших, поскольку мои показывают больше, чем просто ваше определение Window (всплывающая подсказка технически является «окном»). Explorer.exe, Chrome и Internet Explorer могут иметь несколько окон для одного процесса, оба они закрываются. В зависимости от ваших потребностей вы можете посмотреть:

Перечислять окна, как это делает alt-tab

EnumWindows фильтрует только те окна, которые отображаются на alt-tab

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            ProcessListModel processes = Program.GetProccesses();

            foreach (ProcessModel process in processes.Items)
            {
                Console.WriteLine("Program: " 
                  + process.Filename 
                  + "[" + process.IsWindowsExplorer.ToString() + "]");
                Console.WriteLine("- Window Text: " + process.WindowText);
            }
            Console.ReadKey();
        }

        [DllImport("user32")]
        public static extern int EnumWindows(EnumWindowsDelegate CallBack,
                                             ProcessListModel Processes);
        [DllImport("user32.dll")]
        private static extern IntPtr GetWindowThreadProcessId(int hWnd, 
          out int lpdwProcessId);
        [DllImport("user32")]
        internal static extern int GetAncestor(int hwnd, int gaFlags);
        [DllImport("user32")]
        internal static extern int GetLastActivePopup(int hWnd);
        [DllImport("user32")]
        internal static extern bool IsWindowVisible(int hWnd);
        [DllImport("User32.Dll")]
        public static extern void GetWindowText(int h, 
          StringBuilder s, 
          int nMaxCount);

        internal delegate bool EnumWindowsDelegate(int Hwnd, 
          ProcessListModel Processes);

        internal static bool EnumWindowsCallBack(int Hwnd, 
          ProcessListModel Processes)
        {
            ProcessModel model = new ProcessModel();

            // Visible != Minimized (I think) 
            if (!IsWindowVisible(Hwnd))
                return true;

            // Can the Window be shown by using alt-tab 
            if (IsAltTabWindow(Hwnd))
            {
                model.WindowsHandle = Hwnd;
                try
                {
                    int pid = 0;
                    Program.GetWindowThreadProcessId(Hwnd, out pid);
                    if (pid > 0)
                    {
                        try
                        {
                            model.ProcessID = pid;

                            Process p = Process.GetProcessById(pid);
                            if (p != null)
                            {
                                string filename = p.MainModule.FileName;
                                filename = System.IO.Path.GetFileName(filename);
                                model.Filename = filename;

                                StringBuilder windowText = new StringBuilder(256);
                                Program.GetWindowText(Hwnd, windowText, 256);
                                model.WindowText = windowText.ToString();

                                if (filename.Contains("explorer.exe"))
                                {
                                    model.IsWindowsExplorer = true;
                                }

                                Processes.Items.Add(model);
                            }
                        }
                        // Do something or not,  
                        // catch probably if window process 
                        // is closed while querying info 
                        catch { }
                    }
                }
                // Do something or not,  
                // catch probably if window process 
                // is closed while querying info 
                catch { }
            }
            return true;
        }

        internal static bool IsAltTabWindow(int hwnd)
        {
            // Start at the root owner 
            int hwndWalk = GetAncestor(hwnd, 3);

            // See if we are the last active visible popup 
            int hwndTry;
            while ((hwndTry = GetLastActivePopup(hwndWalk)) != hwndTry)
            {
                if (IsWindowVisible(hwndTry))
                    break;
                hwndWalk = hwndTry;
            }

            return hwndWalk == hwnd;
        }

        public static ProcessListModel GetProccesses() 
        {
          ProcessListModel processes = new ProcessListModel();
          EnumWindowsDelegate enumCallback = 
            new EnumWindowsDelegate(EnumWindowsCallBack); 
          EnumWindows(enumCallback, processes); 
          return processes; 
        }

        public class ProcessListModel
        {
            public ProcessListModel()
            {
                this.Items = new List<ProcessModel>();
            }

            public List<ProcessModel> Items { get; private set; }
        }

        public class ProcessModel
        {
            public int WindowsHandle { get; set; }
            public int ProcessID { get; set; }
            public string Filename { get; set; }
            public bool IsWindowsExplorer { get; set; }
            public string WindowText { get; set; }
        }

    }
}

Вывод: (У меня открыто много окон, это лишь небольшой список)

enter image description here

ПРИМЕЧАНИЕ : Это не перечисляет дочерние окна, поэтому, если у меня в IE откроется Internet Options, и я закрою его, это будет дочернее окно, а не главное окно процесса. Если вам нужны дочерние окна, вам придется реализовать функцию EnumChildWindows аналогичным образом.

То, о чем вы просили, В действительности сложно, прямого способа сделать именно то, что вы хотите, нет.

1 голос
/ 27 декабря 2011

Это старая статья, но я успешно использовал ее в прошлом при использовании хуков из .NET:

Windows-хуки в .NET Framework

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...