2

I need to be able to list all active applications on a windows machine. I had been using this code:

Process[] procs = Process.GetProcesses("."); foreach (Process proc in procs) { if (proc.MainWindowTitle.Length > 0) { toolStripComboBox_StartSharingProcessWindow.Items.Add(proc.MainWindowTitle); } } 

Until, I realized that this doesn't list cases like WORD or ACROREAD when multiple files are opened each in their own window. In that situation, only the topmost window is listed using the above technique. I assume that's because there's only one process even though two (or more) files are opened. So, I guess my question is: How do I list all windows rather than their underlying process?

2 Answers 2

8

pinvoke using EnumWindows in user32.dll. something like this would do what you want.

public delegate bool WindowEnumCallback(int hwnd, int lparam); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool EnumWindows(WindowEnumCallback lpEnumFunc, int lParam); [DllImport("user32.dll")] public static extern void GetWindowText(int h, StringBuilder s, int nMaxCount); [DllImport("user32.dll")] public static extern bool IsWindowVisible(int h); private List<string> Windows = new List<string>(); private bool AddWnd(int hwnd, int lparam) { if (IsWindowVisible(hwnd)) { StringBuilder sb = new StringBuilder(255); GetWindowText(hwnd, sb, sb.Capacity); Windows.Add(sb.ToString()); } return true; } private void Form1_Load(object sender, EventArgs e) { EnumWindows(new WindowEnumCallback(this.AddWnd), 0); } 
Sign up to request clarification or add additional context in comments.

3 Comments

Ok, I tried this and it does show me multiple instances of AcroReader (for example), but it also lists about 100 (probably more) names of processes or apps that I've never heard of. Note I have 3-4 apps running on my desktop. According to the EnumWindows documentation, it should list "top-level" windows, but it appears to be listing a lot more than that.
Ok, I think I got it. If I add IsWindowVisible() to the AddWnd() callback, that appears to do what I need. Hope you don't mind, I edited your code to show this, plus the need to have the callback return true.
yeah, i was just getting ready to update it to add exactly that. it'll list a couple of things you might not want (like the start menu button), but that lists all the visible windows in the taskbar basically (everything is a window). sorry it had a couple of mistakes, i wrote that mostly from memory.
0

I have made a similar method, but it also filter on window style ToolWindow and hidden windows store applications that circument the hidden flag by being cloaked.

public static class WindowFilter { public static bool NormalWindow(IWindow window) { if (IsHiddenWindowStoreApp(window, window.ClassName)) return false; return !window.Styles.IsToolWindow && window.IsVisible; } private static bool IsHiddenWindowStoreApp(IWindow window, string className) => (className == "ApplicationFrameWindow" || className == "Windows.UI.Core.CoreWindow") && window.IsCloaked; } 

The above example is part of a project of github, were you can see the rest of the code. https://github.com/mortenbrudvik/WindowExplorer

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.