2017-01-30 168 views
2

我想做一個小應用程序來枚舉每個進程線程中的每個窗口名稱在控制檯中。C#試圖枚舉每個進程線程的每個窗口

我目前使用的代碼可以在Windows 7機器上正常工作,但由於某種原因,它在沒有任何堆棧跟蹤或錯誤消息的情況下在Windows 10中查找,我試圖添加幾乎所有內部​​的try-catch,但我didn我也沒有收到任何消息,所以我迷路了。

下面是代碼:

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

    namespace ConsoleApplication3 
    { 
     class Program 
     { 
      private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); 

      [DllImport("user32.dll")] 
      private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam); 

      [DllImport("user32.dll", CharSet = CharSet.Auto)] 
      private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam); 

      static void Main(string[] args) 
      { 
       Process[] processes = Process.GetProcesses(); 
       Console.WriteLine("Detected: " + processes.Length + " processes."); 
       foreach (Process process in processes) 
       { 
        IEnumerable<IntPtr> windowHandles = null; 
        try 
        { 
         windowHandles = EnumerateProcessWindowHandles(process); 
        } 
        catch (Exception e) 
        { 
         Console.WriteLine(e.StackTrace); 
         continue; 
        } 

        Console.WriteLine("Checking process" + process.ProcessName); 
        foreach (var handle in windowHandles) 
        { 
         StringBuilder message = new StringBuilder(); 
         try 
         { 
          SendMessage(handle, 0x000D, message.Capacity, message); 
         } 
         catch (Exception e) 
         { 
          Console.WriteLine(e.StackTrace); 
          continue; 
         } 
         if (message.Length == 0) 
         { 
          continue; 
         } 
         Console.WriteLine("Window name: " + message.ToString()); 
        } 
       } 
       Console.WriteLine("Finished!"); 
       Console.ReadLine(); 
      } 

      private static IEnumerable<IntPtr> EnumerateProcessWindowHandles(Process process) 
      { 
       List<IntPtr> handles = new List<IntPtr>(); 

       ProcessThreadCollection threads = null; 
       try 
       { 
        threads = process.Threads; 
       } 
       catch (Exception e) 
       { 
        Console.WriteLine(e.StackTrace); 
        return handles; 
       } 

       foreach (ProcessThread thread in threads) 
       { 
        try 
        { 
         EnumThreadWindows(thread.Id, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero); 
        } 
        catch (Exception e) 
        { 
         Console.WriteLine(e.StackTrace); 
         continue; 
        } 
       } 
       return handles; 
      } 
     } 
    } 

爲什麼它可能卡住任何想法?

UPDATE

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

    namespace ConsoleApplication3 
    { 
     class Program 
     { 
      private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); 

      [DllImport("user32.dll")] 
      [return: MarshalAs(UnmanagedType.Bool)] 
      private static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam); 

      [DllImport("user32.dll", CharSet = CharSet.Auto)] 
      private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam); 

      [DllImport("user32.dll")] 
      [return: MarshalAs(UnmanagedType.Bool)] 
      private static extern bool IsWindowVisible(IntPtr handle); 

      static void Main(string[] args) 
      { 
       Process[] processes = Process.GetProcesses(); 
       Console.WriteLine("Detected: " + processes.Length + " processes."); 
       foreach (Process process in processes) 
       { 
        IEnumerable<IntPtr> windowHandles = null; 
        try 
        { 
         windowHandles = EnumerateProcessWindowHandles(process); 
        } 
        catch (Exception e) 
        { 
         Console.WriteLine(e.StackTrace); 
         continue; 
        } 

        Console.WriteLine("Checking process: " + process.ProcessName); 
        foreach (IntPtr handle in windowHandles) 
        { 
         if (handle == null) 
         { 
          continue; 
         } 
         if (!IsWindowVisible(handle)) 
         { 
          continue; 
         } 
         StringBuilder message = new StringBuilder(); 
         int capacity = 0; 
         try 
         { 
          capacity = message.Capacity; 
         } 
         catch(Exception e) 
         { 
          Console.WriteLine(e.StackTrace); 
          continue; 
         } 
         try 
         { 
          SendMessage(handle, 0x000D, capacity, message); 
         } 
         catch (Exception e) 
         { 
          Console.WriteLine(e.StackTrace); 
          continue; 
         } 
         if (message.Length == 0) 
         { 
          continue; 
         } 
         Console.WriteLine("Window name: " + message.ToString()); 
        } 
       } 
       Console.WriteLine("Finished!"); 
       Console.ReadLine(); 
      } 

      private static IEnumerable<IntPtr> EnumerateProcessWindowHandles(Process process) 
      { 
       List<IntPtr> handles = new List<IntPtr>(); 

       ProcessThreadCollection threads = null; 
       try 
       { 
        threads = process.Threads; 
       } 
       catch (Exception e) 
       { 
        Console.WriteLine(e.StackTrace); 
        return handles; 
       } 

       foreach (ProcessThread thread in threads) 
       { 
        if (thread == null) 
        { 
         continue; 
        } 

        int threadId = 0; 
        try 
        { 
         threadId = thread.Id; 
        } 
        catch(Exception e) 
        { 
         Console.WriteLine(e.StackTrace); 
         continue; 
        } 
        try 
        { 
         EnumThreadWindows(threadId, (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero); 
        } 
        catch (Exception e) 
        { 
         Console.WriteLine(e.StackTrace); 
         continue; 
        } 
       } 
       return handles; 
      } 
     } 
    } 

謝謝大家。

+0

我相信這與了Windows 10應用程序沙箱和應用程序,但我做的不確定。我知道我們無法深入瞭解我們使用的方式,但我不知道這樣做的正確方法。 Windows 10使用了很多虛擬環境來託管應用程序,所以我只是在這裏猜測......請不要將此作爲任何答案。 –

+0

感謝您的回答邁克爾Pucket II,我試着在另一臺機器與Windows 10和工作正常,但看起來像代碼隨機失敗也在Windows 7沒有任何消息/痕跡/錯誤...我真的不知道在哪裏開始解決我的問題。 –

+0

我有一個想法。你的windowHandles = null已經。 EnumerateProcessWindowHandles(進程)不會失敗,但仍然返回null。然後當你輸入foreach(var handle在windowHandles中)它會崩潰。你應該得到一個錯誤,但如果這是部署你可能不會。我將windowHandles設置爲一個空的枚舉,以便foreach循環至少有一個零計數值,並且永遠不會有空值。這是我能夠立即注意到的唯一缺陷,如果是我,就必須從那裏開始。 –

回答

0

嘗試運行控制檯應用程序管理員,如果問題仍然出現,我建議使用API​​ GetLastError這就是它的作用:

檢索調用線程的最後一個錯誤代碼值。最後的錯誤代碼以每個線程爲基礎進行維護。多線程不會覆蓋彼此的最後一個錯誤代碼。

要讀出值知道的問題,嘗試如何使用它此鏈接爲指導做好: https://msdn.microsoft.com/en-us/library/windows/desktop/ms679360(v=vs.85).aspx

+0

感謝您的回答,我試過這個,但我沒有得到任何輸出。 –

相關問題