c# - 将 ApplicationFrameHost 托管的 UWP 应用程序连接到它们的实际进程

标签 c# wpf windows winapi uwp

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

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

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

谁知道如何实现这个?非常感谢所有帮助。

最佳答案

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

这是带有 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();
    }
}

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

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;
    }
}

关于c# - 将 ApplicationFrameHost 托管的 UWP 应用程序连接到它们的实际进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39702704/

相关文章:

c# - 在 C# 项目中运行时选择连接字符串

WPF 组合框自动完成项目

wpf - 如何将 WindowState 从桌面快捷方式传递到 WPF 应用程序?

windows - 为什么不鼓励在 Windows 上将 PPM perl 模块与 Strawberry perl 一起使用?

c# - C# 集合上的排名搜索

c# - 如何在 ASP.NET 中等待异步 Web 服务调用的结果以获得最佳性能

C#捕获互联网音频流

wpf - 在 VS 2010 中禁用 WPF 设计器?

python - 线程后的代码提前执行,为什么?

python - Autokeras 与 Anaconda 的安装