2011-12-27 16 views
2

我想在.NET中創建一個shell擴展或應用程序,用於記錄所有關閉的窗口。日誌應該包含創建窗口的進程名稱。記錄在Windows中關閉的所有Windows

我不知道如何做到這一點。任何指針?

+1

好吧,你想要什麼聽起來像不止一件事..結帳System.Diagnostics.Process和創建日誌還檢查JavaScript和日誌記錄奇怪你爲什麼甚至想記錄所有開始。查看查詢TaskManager提示..WMI可以做到這一點以及...祝你好運 – MethodMan 2011-12-27 19:26:37

回答

5

這需要一個鉤子,通過調用SetWindowsHookEx,WH_SHELL鉤型集。這種鉤子類型需要一個可以注入進程的DLL,這種DLL不能用C#編寫。 64位操作系統和UAC也會產生很多障礙。 This project可以提供幫助。

+0

我從來沒有使用它,看起來很有希望。你必須嘗試。 – 2012-01-07 22:15:27

3

雖然你肯定可以掛鉤程序,但對於你想要做的事情來說,這確實看起來過度。這段代碼應該讓你非常接近(你必須做一些其他的事情來查詢它的當前目錄的Windows資源管理器進程,我沒有這樣做)。此外,我的需求與您的需求不同,因爲我的展示不僅僅是您對Window的定義(工具提示彈出窗口在技術上是'窗口')。 Explorer.exe,Chrome和Internet Explorer都可以有一個進程的多個窗口,這兩個窗口都關閉。根據您的需求,你可能想看看:

Enumerate windows like alt-tab does

EnumWindows filter to only windows that show up on 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 function

你要求的是實際上很難,沒有直接的方法去做你想要的東西。

+0

更新,創建一個新的控制檯應用程序,粘貼代碼,完成。 – 2011-12-28 00:08:13