Record all Windows closed in Windows

I want to make a shell extension or application in .NET that registers all closed windows. The log should contain the name of the process that created the window.

I have no idea how to do this. Any pointers?

+2
source share
3 answers

This requires the hook specified with SetWindowsHookEx, such as the hook type WH_SHELL. This type of hook requires a DLL that can be injected into the process, so the DLL cannot be written in C #. A 64-bit operating system and UAC will also create many obstacles. This project can help.

+5
source

Despite the fact that you, of course, can use programs that really seem excessive for what you want to do. This code should make you VERY close (you will need to do something else to request the Windows Explorer process for its current directory, I did not). In addition, my needs are different from yours, as mine shows more than just the definition of Window (the popup tooltip is technically a β€œwindow”). Explorer.exe, Chrome and Internet Explorer can have several windows for one process, both windows are closed. Depending on your needs, you can see:

List windows e.g. alt-tab

EnumWindows filter for windows displayed on alt-tab only

 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; } } } } 

Exit: (I have many open windows, this is just a small list of them)

enter image description here

NOTE This does not list child windows, so if I have Internet Options open in IE and I close it, it will be a child window, not the main window of the process. If you need child windows, you will have to implement the EnumChildWindows function in a similar way.

What you asked for is SO complicated, there is no direct way to do exactly what you want.

+3
source

This is an older article, but I have used it in the past with success when using .NET interceptors:

Windows Hooks in the .NET Framework

+1
source

Source: https://habr.com/ru/post/905355/


All Articles