Report Installed Apps Stats on Mac, Windows, and Linux

Introduction
Tracking installed applications across different operating systems is crucial for system administrators, security analysts, and IT professionals. Whether it’s for software auditing, compliance checks, or system monitoring, a reliable way to retrieve installed applications is essential.
This feature enables fetching installed applications on Windows, macOS, and Linux, providing a standardised API to retrieve application details like name, version, vendor, installation date, and additional metadata.
PR: https://github.com/oshi/oshi/pull/2851
Implementation Overview
The feature is designed to be efficient and consistent across all three major operating systems. It utilizes OS-specific mechanisms to retrieve application data and integrates a memoization technique to optimize performance by caching results.
1. Standardised Data Model
We define a single ApplicationInfo
class to represent application details across all OSes:
public class ApplicationInfo {
private final String name;
private final String version;
private final String vendor;
private final long timestamp;
private final Map<String, String> additionalInfo;
}
The first four fields capture standard application details.
additionalInfo
stores OS-specific attributes.
2. Fetching Installed Applications on Different OS
Each operating system uses a unique approach to extract installed applications:
Windows Implementation
On Windows, installed applications are primarily retrieved from the Windows Registry.
Uses
Advapi32Util
to query the Windows Registry for installed applications.Retrieves name, version, vendor, and install date.
Stores install location and install source in
additionalInfo
macOS Implementation
On macOS, applications are listed in /Applications/
and can be queried using system commands.
Runs
system_profiler
to fetch application details.Parses output into
ApplicationInfo
objects.
Linux Implementation
Linux distributions use different package managers (dpkg, rpm) to manage installed software.
Checks if
dpkg
orrpm
is available.Executes the appropriate package manager command.
Parses results into
ApplicationInfo
.
3. Memoization for Performance Optimization
Since installed applications don’t change frequently, memoization is used to cache results and avoid redundant system calls.
oshi.software.os.linux.LinuxOperatingSystem
private final Supplier<List<ApplicationInfo>> installedAppsSupplier = Memoizer
.memoize(LinuxInstalledApps::queryInstalledApps, installedAppsExpiration());
public List<ApplicationInfo> getInstalledApplications() {
return installedAppsSupplier.get();
}
oshi.util.Memoizer
public static long installedAppsExpiration() {
return TimeUnit.MINUTES.toNanos(1);
}
Same implementation is done for Windows and Mac OS specific classes.
Caches results for a configured expiration time (default: 1 minute).
Reduces unnecessary queries to the registry, system commands, or package managers.
Key Improvements
✅ Unified Data Model – Replaces multiple OS-specific classes with a single ApplicationInfo
class.
✅ Efficient Caching – Uses memoization to reduce redundant queries.
✅ Improved Maintainability – OS-specific logic is confined to their respective implementations.
How to use in your Java Apps?
Add the below code snippet in your app to list the installed apps on the respective server.
SystemInfo si = new SystemInfo();
List<ApplicationInfo> apps = si.getOperatingSystem().getInstalledApplications();
Sample Outputs:
Linux:
Ubuntu:
AppInfo{name=zlib1g, version=1:1.3.dfsg-3.1ubuntu2, vendor=Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>, timestamp=1713886044, additionalInfo={source=zlib, installedSize=162, architecture=amd64, homepage=http://zlib.net/}}
AppInfo{name=zstd, version=1.5.5+dfsg2-2build1, vendor=Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>, timestamp=1713886075, additionalInfo={source=libzstd, installedSize=1798, architecture=amd64, homepage=https://github.com/facebook/zstd}}
Redhat:
AppInfo{name=pipewire-alsa, version=1.0.1-1.el9, vendor=Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>, timestamp=1741429838, additionalInfo={source=pipewire-1.0.1-1.el9.src.rpm, installedSize=177582, architecture=x86_64, homepage=https://pipewire.org/}}
AppInfo{name=pipewire-pulseaudio, version=1.0.1-1.el9, vendor=Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>, timestamp=1741429838, additionalInfo={source=pipewire-1.0.1-1.el9.src.rpm, installedSize=437665, architecture=x86_64, homepage=https://pipewire.org/}}
Mac:
AppInfo{name=FaceTime, version=36, vendor=Apple, timestamp=1741255560000, additionalInfo={Get Info String=unknown, Kind=Universal, Location=/System/Applications/FaceTime.app}}
AppInfo{name=IntelliJ IDEA CE, version=2023.1.1, vendor=Developer ID Application: JetBrains s.r.o. (2ZEFAR8TH3), Developer ID Certification Authority, Apple Root CA, timestamp=1682607840000, additionalInfo={Get Info String=IntelliJ IDEA 2023.1.1, build IC-231.8770.65. Copyright JetBrains s.r.o., (c) 2000-2023, Kind=Universal, Location=/Applications/IntelliJ IDEA CE.app}}
Windows:
AppInfo{name=Microsoft Visual C++ 2019 X64 Minimum Runtime - 14.29.30153, version=14.29.30153, vendor=Microsoft Corporation, timestamp=1707868800000, additionalInfo={installLocation=unknown, installSource=C:\ProgramData\Package Cache\{...}v14.29.30153\packages\vcRuntimeMinimum_amd64\}}
AppInfo{name=aws-cfn-bootstrap, version=2.0.29, vendor=Amazon Web Services, timestamp=1707868800000, additionalInfo={installLocation=unknown, installSource=C:\ProgramData\Package Cache\{...}v2.0.29\}}
Conclusion
This feature simplifies fetching installed applications across Windows, macOS, and Linux.
With a unified API, optimised queries, and caching, it ensures efficient and reliable apps monitoring on the server.
Subscribe to my newsletter
Read articles from Rohan Sarnad directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
