blez's : blog

code / design / music and more


Leave a comment

How to detect a Metro process?

I was searching for a way to detect if a process is IE 10 metro, not IE 10 desktop, then I saw that metro apps have no windows. I don’t know how Spy++ enums IE metro’s subwindows, but mine code doesn’t. That’s somehow a good thing, cause I can use that for detecting a metro app. I tried it with x86/x64 and console apps. Seems to work fine and detects only metro apps. Write if there’s a bug or a smarter solution.

        public static bool IsMetroApp(Process process) {            
            foreach (ProcessThread threadInfo in process.Threads) {
                var windows = GetWindowHandlesForThread(threadInfo.Id);
                if (windows != null && windows.Length > 0) return false;
            }

            return true;
        }

        private static IntPtr[] GetWindowHandlesForThread(int threadHandle) {
            results.Clear();
            EnumWindows(WindowEnum, threadHandle);
            return results.ToArray();
        }

        private delegate int EnumWindowsProc(IntPtr hwnd, int lParam);

        [DllImport("user32.Dll")]
        private static extern int EnumWindows(EnumWindowsProc x, int y);
        [DllImport("user32")]
        private static extern bool EnumChildWindows(IntPtr window, EnumWindowsProc callback, int lParam);
        [DllImport("user32.dll")]
        public static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);

        private static List<IntPtr> results = new List<IntPtr>();

        private static int WindowEnum(IntPtr hWnd, int lParam) {
            int processID = 0;
            int threadID = GetWindowThreadProcessId(hWnd, out processID);
            if (threadID == lParam) {
                results.Add(hWnd);
                EnumChildWindows(hWnd, WindowEnum, threadID);
            }

            return 1;
        }
Advertisements