【问题标题】:Get program handle and window handle for media session获取媒体会话的程序句柄和窗口句柄
【发布时间】:2020-11-07 23:33:21
【问题描述】:

我想获取有关所有当前活动媒体播放的信息。我找到了一种读出所有媒体会话的方法here

using Windows.Media.Control;

namespace ConsoleApp1 {
    public class Program {
        [STAThread]
        static void Main(string[] args) {
            var gsmtcsm = GlobalSystemMediaTransportControlsSessionManager.RequestAsync().GetAwaiter().GetResult().GetSessions();

            foreach (var session in gsmtcsm) {
                var mediaProperties = session.TryGetMediaPropertiesAsync().GetAwaiter().GetResult();
                Console.WriteLine("{0} - {1}", mediaProperties.Artist, mediaProperties.Title);
            }

            Console.ReadKey();
        }
    }
}

现在我想为这些会话获取相应的程序。另外,如果它存在,我想获取程序的窗口。如果窗口存在,我的目标是以编程方式将它移动到另一个屏幕。程序句柄仅用作标识符。

例如: 我打开一个随机的 .mp4 文件。默认情况下,它由 Windows Films & TV 播放。现在我想获取会话、程序和窗口(电影和电视有一个窗口)并将其移动到另一个屏幕(通过代码)

另一个例子: 我在 Youtube 上看一个视频。现在我想获取我打开 Youtube 的浏览器的窗口。

【问题讨论】:

    标签: c# windows


    【解决方案1】:

    您可以找到运行媒体会话的应用的主窗口

    var gsmtcsm = GlobalSystemMediaTransportControlsSessionManager.RequestAsync().GetAwaiter().GetResult().GetSessions();
    foreach (var session in gsmtcsm)
    {
        string modelId = session.SourceAppUserModelId;
        // Get all processes
        Process[] processlist = Process.GetProcesses();
        // Create and array to hold matched processes
        List<Process> modelProcesslist = new List<Process>();
        // Using a direct filter on the Process.GetProcesses() call will raise an exception, you will need to cycle through them 
        // to find a process that has the same filename as reported by the media session
        // The filename may be different to the process name
        foreach (Process p in processlist)
        {
            try
            {
                if (p.MainModule.FileName.Contains(modelId) && p.MainWindowHandle != IntPtr.Zero)
                {
                    modelProcesslist.Add(p);
                }
            }
            catch(System.Exception)
            {
                // Couldn't look at the MainModule of this process, move on
            }
        }
        foreach (Process p in modelProcesslist)
        {
            IntPtr windowHandle = p.MainWindowHandle;
            // The main window(s) for apps that have the same name as the source app for the media session
        }
    }
    

    如果主窗口归 chrome.exe(或任何选项卡式浏览器)所有,那么媒体播放器位于其中一个子选项卡中,那么在浏览器的选项卡中查找内容是一个全新的水平,这将是一个大问题头痛。

    此外,如果您打开了多个浏览器窗口,它们都将具有相同的可执行文件名称并被上述代码提取。

    如果应用是专用的媒体播放器,您应该可以使用手柄来移动窗口。

    【讨论】:

    • 非常感谢。我将实现它,然后我会看到如何找到包含选项卡的正确窗口。下一个级别将关注此选项卡;)
    • 关于附加问题。一个程序不能有多个媒体会话是否有原因?因此,如果我在 chrome 中打开两个 youtube 视频,则只会读出一个。另外,虽然我打开了一个视频,但 Firefox 没有会话
    • GlobalSystemMediaTransportControlsSessionManager 将仅列出与 SystemMediaTransportControls 集成的播放会话,如果应用具有独立/未集成的媒体播放器,则不会列出。
    • 好的。但是列出了一个 youtube 视频。但不是同一浏览器中的另一个(测试了 chrome 和 edge;firefox 没有列出),尽管它应该是相同类型的播放器
    • 我不确定那个,我将不得不调查它,我怀疑 chrome 一次只集成一个会话,即如果你切换,则有焦点的那个tabs 艺术家信息会改变吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    相关资源
    最近更新 更多