将 ApplicationFrameHost 托管的 UWP 应用程序连接到它们的真实进程 [英] Connecting UWP apps hosted by ApplicationFrameHost to their real processes

查看:21
本文介绍了将 ApplicationFrameHost 托管的 UWP 应用程序连接到它们的真实进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 WPF 应用程序来监控我在计算机上的活动.我使用 Process.GetProcesses() 和一些过滤来获取我感兴趣的进程(例如:Calculator),然后我记录它们的 StartTime.我还使用 WIN32/USER32 API 方法 GetForegroundWindow() 来获取用户正在使用的窗口.

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 (example:Calculator) then I record their StartTime. I am also using WIN32/USER32 API method GetForegroundWindow() to get the window the user is using.

问题是当窗口是 Windows/UWP 应用程序时,它们总是由进程 ApplicationFrameHost 托管.所以 GetForegroundWindow() 方法返回带有标题的窗口(例如:Calculator),但不是托管的真实进程.

The problem is that when the windows are Windows/UWP applications they are always hosted by the process ApplicationFrameHost. So the GetForegroundWindow() method returns that window with a title (example:Calculator), but not the real process being hosted.

我需要的是获取包含托管真实进程的前台窗口的另一种方法,或者将窗口连接到进程的某种方法.

What I need is either another way to get the foreground window that includes the real process being hosted, or some way to connect the window to process.

有人知道如何做到这一点吗?非常感谢所有帮助.

Anyone that knows how to accomplish this? All help would be really appreciated.

推荐答案

我最终找到了一种方法来做到这一点,所以我将回答我自己的问题,以便将来遇到同样问题的人可能会发现它有用.

I eventually found a way to do this, so I am going answer my own question so maybe someone in the future with the same problem could find it useful.

这是带有 WinApiFunctions 的类:

This is the class with the WinApiFunctions:

public class WinAPIFunctions
{
    //Used to get Handle for Foreground Window
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr GetForegroundWindow();

    //Used to get ID of any Window
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
    public delegate bool WindowEnumProc(IntPtr hwnd, IntPtr lparam);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc callback, IntPtr lParam);

    public static int GetWindowProcessId(IntPtr hwnd)
    {
        int pid;
        GetWindowThreadProcessId(hwnd, out pid);
        return pid;
    }

    public static IntPtr GetforegroundWindow()
    {
        return GetForegroundWindow();
    }
}

这是我用来测试它是否有效的类.我在一个简单的控制台程序中使用它,该程序只写出当前具有焦点的进程的名称:

And this is the class I used to test if it would work. I used it in a simple console program that just writes out the name of the process that has current focus:

class FindHostedProcess
{
    public Timer MyTimer { get; set; }
    private Process _realProcess;
    public FindHostedProcess()
    {
        MyTimer = new Timer(TimerCallback, null, 0, 1000);
        Console.ReadKey();
    }

    private void TimerCallback(object state)
    {
        var foregroundProcess = Process.GetProcessById(WinAPIFunctions.GetWindowProcessId(WinAPIFunctions.GetforegroundWindow()));
        if (foregroundProcess.ProcessName == "ApplicationFrameHost")
        {
            foregroundProcess = GetRealProcess(foregroundProcess);
        }
        Console.WriteLine(foregroundProcess.ProcessName);
    }

    private Process GetRealProcess(Process foregroundProcess)
    {
        WinAPIFunctions.EnumChildWindows(foregroundProcess.MainWindowHandle, ChildWindowCallback, IntPtr.Zero);
        return _realProcess;
    }

    private bool ChildWindowCallback(IntPtr hwnd, IntPtr lparam)
    {
        var process = Process.GetProcessById(WinAPIFunctions.GetWindowProcessId(hwnd));
        if (process.ProcessName != "ApplicationFrameHost")
        {
            _realProcess = process;
        }
        return true;
    }
}

这篇关于将 ApplicationFrameHost 托管的 UWP 应用程序连接到它们的真实进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆