200 lines
5.1 KiB
C++
200 lines
5.1 KiB
C++
#include <fmt/chrono.h>
|
|
#include <fmt/core.h>
|
|
#include <iostream>
|
|
#include <windows.h>
|
|
#include <winrt/Windows.Foundation.h> // ReSharper disable once CppUnusedIncludeDirective
|
|
#include <winrt/Windows.Media.Control.h>
|
|
#include <winrt/base.h>
|
|
#include <winrt/impl/windows.media.control.2.h>
|
|
|
|
#include "util.h"
|
|
|
|
using namespace winrt;
|
|
using namespace winrt::Windows::Media::Control;
|
|
|
|
struct KBToGiB {
|
|
u64 value;
|
|
};
|
|
|
|
template <>
|
|
struct fmt::formatter<KBToGiB> : formatter<double> {
|
|
template <typename FormatContext>
|
|
typename FormatContext::iterator
|
|
format(const KBToGiB KTG, FormatContext& ctx) {
|
|
typename FormatContext::iterator out = formatter<double>::format(
|
|
static_cast<double>(KTG.value) / pow(1024, 2), ctx
|
|
);
|
|
|
|
*out++ = 'G';
|
|
*out++ = 'i';
|
|
*out++ = 'B';
|
|
|
|
return out;
|
|
}
|
|
};
|
|
|
|
enum DateNum : u8 { Ones, Twos, Threes, Default };
|
|
|
|
DateNum ParseDate(std::string const& input) {
|
|
if (input == "1" || input == "21" || input == "31") return Ones;
|
|
if (input == "2" || input == "22") return Twos;
|
|
if (input == "3" || input == "23") return Threes;
|
|
return Default;
|
|
}
|
|
|
|
std::string GetNowPlaying() {
|
|
using namespace winrt::Windows::Media::Control;
|
|
using namespace winrt::Windows::Foundation;
|
|
|
|
using MediaProperties =
|
|
GlobalSystemMediaTransportControlsSessionMediaProperties;
|
|
using Session = GlobalSystemMediaTransportControlsSession;
|
|
using SessionManager = GlobalSystemMediaTransportControlsSessionManager;
|
|
|
|
try {
|
|
// Request the session manager asynchronously
|
|
const IAsyncOperation<SessionManager> sessionManagerOp =
|
|
SessionManager::RequestAsync();
|
|
const SessionManager sessionManager = sessionManagerOp.get();
|
|
|
|
if (const Session currentSession = sessionManager.GetCurrentSession()) {
|
|
// Try to get the media properties asynchronously
|
|
const IAsyncOperation<MediaProperties> mediaPropertiesOp =
|
|
currentSession.TryGetMediaPropertiesAsync();
|
|
const MediaProperties mediaProperties = mediaPropertiesOp.get();
|
|
|
|
// Convert the hstring title to std::string
|
|
return to_string(mediaProperties.Title());
|
|
}
|
|
|
|
// If we reach this point, there is no current session
|
|
return "No current media session.";
|
|
} catch (...) { return "Failed to get media properties."; }
|
|
}
|
|
|
|
std::string GetRegistryValue(
|
|
const HKEY& hKey,
|
|
const std::string& subKey,
|
|
const std::string& valueName
|
|
) {
|
|
HKEY key = nullptr;
|
|
if (RegOpenKeyExA(hKey, subKey.c_str(), 0, KEY_READ, &key) != ERROR_SUCCESS)
|
|
return "";
|
|
|
|
DWORD dataSize = 0;
|
|
if (RegQueryValueExA(
|
|
key, valueName.c_str(), nullptr, nullptr, nullptr, &dataSize
|
|
) != ERROR_SUCCESS) {
|
|
RegCloseKey(key);
|
|
return "";
|
|
}
|
|
|
|
std::string value(dataSize, '\0');
|
|
if (RegQueryValueExA(
|
|
key,
|
|
valueName.c_str(),
|
|
nullptr,
|
|
nullptr,
|
|
reinterpret_cast<LPBYTE>(value.data()), // NOLINT(*-reinterpret-cast)
|
|
&dataSize
|
|
) != ERROR_SUCCESS) {
|
|
RegCloseKey(key);
|
|
return "";
|
|
}
|
|
|
|
RegCloseKey(key);
|
|
// Remove null terminator if present
|
|
if (!value.empty() && value.back() == '\0') value.pop_back();
|
|
|
|
return value;
|
|
}
|
|
|
|
std::string GetPrettyWindowsName() {
|
|
std::string productName = GetRegistryValue(
|
|
HKEY_LOCAL_MACHINE,
|
|
R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)",
|
|
"ProductName"
|
|
);
|
|
|
|
const std::string displayVersion = GetRegistryValue(
|
|
HKEY_LOCAL_MACHINE,
|
|
R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)",
|
|
"DisplayVersion"
|
|
);
|
|
|
|
const std::string releaseId = GetRegistryValue(
|
|
HKEY_LOCAL_MACHINE,
|
|
R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)",
|
|
"ReleaseId"
|
|
);
|
|
|
|
const int buildNumber = stoi(GetRegistryValue(
|
|
HKEY_LOCAL_MACHINE,
|
|
R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)",
|
|
"CurrentBuildNumber"
|
|
));
|
|
|
|
fmt::println("Build number: {}", buildNumber);
|
|
|
|
// Check if the build number is 22000 or higher
|
|
if (buildNumber >= 22000 &&
|
|
productName.find("Windows 10") != std::string::npos)
|
|
productName.replace(productName.find("Windows 10"), 10, "Windows 11");
|
|
|
|
if (!productName.empty()) {
|
|
std::string result = productName;
|
|
|
|
if (!displayVersion.empty())
|
|
result += " " + displayVersion;
|
|
else if (!releaseId.empty())
|
|
result += " " + releaseId;
|
|
|
|
return result;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
int main() {
|
|
init_apartment();
|
|
|
|
u64 memInfo = 0;
|
|
GetPhysicallyInstalledSystemMemory(&memInfo);
|
|
fmt::println("Installed RAM: {:.2f}", KBToGiB {memInfo});
|
|
|
|
fmt::println("Now playing: {}", GetNowPlaying());
|
|
|
|
const std::tm localTime = fmt::localtime(time(nullptr));
|
|
|
|
std::string date = fmt::format("{:%e}", localTime);
|
|
|
|
auto start = date.begin();
|
|
while (start != date.end() && std::isspace(*start)) ++start;
|
|
date.erase(date.begin(), start);
|
|
|
|
switch (ParseDate(date)) {
|
|
case Ones:
|
|
date += "st";
|
|
break;
|
|
|
|
case Twos:
|
|
date += "nd";
|
|
break;
|
|
|
|
case Threes:
|
|
date += "rd";
|
|
break;
|
|
|
|
case Default:
|
|
date += "th";
|
|
break;
|
|
}
|
|
|
|
fmt::println("{:%B} {}, {:%-I:%0M %p}", localTime, date, localTime);
|
|
|
|
fmt::println("Version: {}", GetPrettyWindowsName());
|
|
|
|
uninit_apartment();
|
|
return 0;
|
|
}
|