windowsdelphiwinapiwindows-runtimec++-winrt

How does the Windows Action Center get the name and icon of an application playing media?


I'm developing a library for easy integration of a media player with the action center playback. For this I used the known windows runtime interfaces ISystemMediaTransportControls and ISystemMediaTransportControls2.

What I'm trying to do

Currently the library works, but I don't know and cannot find any documentation regarding how to set the app icon and name. The information I want to change can be seen In the image below, "Firefox" and the icon.

Currently, when I add my media player, the name and icon just default to the name of the last media player app. So in this case, it just shows up as Firefox, even if it's actually my app.

Example of a player with name and icon

Some sources I read

I also looked at the source code of Firefox and Chromium, both having integrations with the System Media Transport Controls, and I still can't see how they managed to register their custom app names and icons.

Here are some files I took a look at:

Question

So how do apps with a Media Transport Control notify Windows of their name and icon?


Solution

  • I have found out how to add the app icon to the Action Center

    And I've figured out It's a good idea to answer my own question for anyone who may also want to find out how this works.

    It seems that Windows get application information using something called AppUserModelID. These were introduced in Windows 7 to be able to identify apps stored in the start menu.

    AppUserModelID's are stored in two places:

    The first one is used for posting Windows Notifications to the action center. The ladder is used for the media playback controls and maybe a few other Windows features I'm unaware of.

    To register a app's AppUserModelID all you need to do is create a shortcut to you application in the start menu folder, with a special not very known property. I found this GitHub repository which showcases how this can be done. The same code but in Pascal can be found the the repository I linked below.

    Here is a sample function which can do this:

    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes,
      ActiveX, ComObj, Winapi.ShlObj, Winapi.PropKey, Winapi.PropSys;
    
    function InstallShortcut(AppUserModelID, ExePath, ShortcutPath, Description, Arguments, IconPath: string; IconIndex: integer): boolean;
    var
      newShortcut: IShellLink;
    
      persistFileSave: IPersistFile;
      newShortcutProperties: IPropertyStore;
    
      propVariant: TPropVariant;
    begin
      newShortcut:= CreateComObject(CLSID_ShellLink) as IShellLink;
    
      // Add data
      with newShortcut do
      begin
        SetArguments(PChar(Arguments));
        SetDescription(PChar(Description));
        SetPath(PChar(ExePath));
        SetWorkingDirectory(PChar( ExtractFileDir(ExePath) ));
    
        if IconPath <> '' then
          SetIconLocation(PChar(IconPath), 0);
      end;
    
      // Property store
      newShortcutProperties := newShortcut as IPropertyStore;
    
      propVariant.vt := VT_BSTR;
      propVariant.bstrVal := Pchar(AppUserModelID);
    
      if not Succeeded(newShortcutProperties.SetValue(PKEY_AppUserModel_ID, propVariant)) then
        Exit( false );
      if not Succeeded(newShortcutProperties.Commit) then
        Exit( false );
    
      // Save
      persistFileSave := newShortcut as IPersistFile;
      Result := Succeeded( persistFileSave.Save(PWChar(WideString(ShortcutPath)), FALSE) );
    end;
    

    Example usage:

    InstallShortcut('com.example.appname', 'C:\App Name\appfile.exe', 'C:\Users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\App Name.lnk', 'Application Description', '', '', 0);
    

    And of course you need to set the app user model ID of the running applicaton with:

    SetCurrentProcessExplicitAppUserModelID( 'com.example.appname' );
    

    I've also added everything I was able to write to integrate this in Delphi with classes to manage the Media Transport Controls to the following repositories on GitHub: