winapivisual-c++jump-list

How to get appUserModelId for any app in windows 7/8 using vc++


I want to find out recent/frequent items from jumplist of any app. I know that we can do this using IApplicationDocumentLists interface. But we need appUserModelId for that. So now my problem is to find out appUserModelId for any app, given its exe path. Any help will be highly appreciated.


Solution

  • AppUserModeIDs are not part of the EXE file itself, so it is not enough to just have the path to the EXE file. AppUserModeIDs are assigned while the EXE is running, and they can be assigned on process-wide or per-window basis.

    To query a process's explicit AppUserModeID, you would have to inject code into that process and have it call GetCurrentProcessExplicitAppUserModelID(), then use an IPC mechanism to send the value back to your main app.

    To query a window's explicit AppUserModeID, you can use SHGetPropertyStoreForWindow() to get the window's IPropertyStore interface, and then call IPropertyStore.GetValue() specifying PKEY_AppUserModel_ID as the property key.

    Note that in either case, these functions only work for explicit AppUserModeIDs. They do not work for implicit AppUserModeIDs that are assigned by Windows if an app does not assign an explicit AppUserModeID for itself. This is clearly stated in the documentation:

    Application User Model IDs (AppUserModelIDs)

    Some applications do not declare an explicit AppUserModelID. They are optional. In that case, the system uses a series of heuristics to assign an internal AppUserModelID. However, there is a performance benefit in avoiding those calculations and an explicit AppUserModelID is the only way to guarantee an exact user experience. Therefore, it is strongly recommended that an explicit ID be set. Applications cannot retrieve a system-assigned AppUserModelID.

    Update: in Windows 8, Microsoft added a new GetApplicationUserModelId() function:

    Gets the application user model ID for the specified process.

    You can use that instead of injecting code to call GetCurrentProcessExplicitAppUserModelID(). I have not tried it yet, but I suspect it returns the current AppUserModeID regardless of how it is assigned (explicit or system-assigned).