Connecting UWP apps hosted by ApplicationFrameHost to their real processes

前端 未结 4 1199
暗喜
暗喜 2021-02-08 00:30

I am working on an WPF application to monitor my activities on my computer. I use Process.GetProcesses() and some filtering to get the processes I am interested in

4条回答
  •  粉色の甜心
    2021-02-08 01:24

    Basically, the answer you provided will also fail if the active window is in full screen mode,

    for example if you have Skype app opened along with Microsoft Remote Desktop, which is the active one and on full screen mode, EnumChildWindows would return SkypeApp not RDPClient.

    and to get this fixed, you should follow the workaround suggested by Ivanmoskalev,

    check this out:

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetGUIThreadInfo(uint idThread, ref GUITHREADINFO lpgui);
    
    public static IntPtr getThreadWindowHandle(uint dwThreadId)
    {
        IntPtr hWnd;
    
        // Get Window Handle and title from Thread
        var guiThreadInfo = new GUITHREADINFO();
        guiThreadInfo.cbSize = Marshal.SizeOf(guiThreadInfo);
    
        GetGUIThreadInfo(dwThreadId, ref guiThreadInfo);
    
        hWnd = guiThreadInfo.hwndFocus;
        //some times while changing the focus between different windows, it returns Zero so we would return the Active window in that case
        if (hWnd == IntPtr.Zero)
        {
            hWnd = guiThreadInfo.hwndActive;
        }
        return hWnd;
    }
    
    [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    public static extern int GetWindowThreadProcessId(IntPtr windowHandle, out int processId);
    
    static void Main(string[] args)
    {
        var current = getThreadWindowHandle(0);
        int processId = 0;
        GetWindowThreadProcessId(current, out processId);
        var foregroundProcess = GetActiveProcess(processId);
    }
    
    private static Process GetActiveProcess(int activeWindowProcessId)
    {
        Process foregroundProcess = null;
        try
        {
            foregroundProcess = Process.GetProcessById(activeWindowProcessId);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        if (string.IsNullOrWhiteSpace(GetProcessNameSafe(foregroundProcess)))
        {
            var msg = "Process name is empty.";
            Console.WriteLine(msg);
        }
        return foregroundProcess;
    }
    

提交回复
热议问题