Application Identification
To provide per-application volume control, EarTrumpet must accurately identify which process is associated with each audio session. This is handled by the AppInformationFactory
.
The AppInformationFactory
The AppInformationFactory
is responsible for creating an IAppInfo
object from a given Process ID (PID). This object contains crucial metadata about the application, including:
- Display Name
- Executable Name (
ExeName
) - Installation Path
- Icon Path
Differentiating App Types
Windows has two primary types of applications, and EarTrumpet uses different strategies to identify each:
1. Modern Apps (UWP/Packaged)
For modern applications, EarTrumpet uses the Kernel32.GetApplicationUserModelId
function. This provides a unique AppUserModelID (AUMID) which can be used to query the system for rich metadata, including the correct icon and display name.
2. Classic Desktop Apps (Win32)
For traditional desktop applications, identification is more complex. The process involves a prioritized series of lookups:
- AppsFolder: EarTrumpet first attempts to find a corresponding entry in the shell's
AppsFolder
. If a match is found, this usually provides the highest quality metadata. - Window Caption: If the
AppsFolder
lookup fails, it falls back to reading the main window title of the process. - Executable Name: As a last resort, it uses the name of the executable file (e.g.,
firefox.exe
).
This layered approach ensures that EarTrumpet displays the most user-friendly name and icon available for each application.
Handling Zombie Processes
A "zombie process" is a process that has terminated but has not yet been fully cleaned up by the operating system. These processes can sometimes still appear to have active audio sessions, leading to stale entries in the EarTrumpet UI.
EarTrumpet's ProcessWatcherService
is designed to handle this. It uses a background thread to monitor the process handles of all applications with audio sessions. When a process terminates, the service is signaled, and it promptly removes the corresponding entry from the UI, preventing these zombie entries from lingering.