diff --git a/frame/payload/bin/fenv-tool b/frame/payload/bin/fenv-tool index 6aa03b8..c40fac8 100755 Binary files a/frame/payload/bin/fenv-tool and b/frame/payload/bin/fenv-tool differ diff --git a/frame/payload/bin/frame-home b/frame/payload/bin/frame-home index 3cece1a..fe90ebd 100755 Binary files a/frame/payload/bin/frame-home and b/frame/payload/bin/frame-home differ diff --git a/frame/payload/bin/frame-switcher b/frame/payload/bin/frame-switcher index c4461b1..a401c13 100755 Binary files a/frame/payload/bin/frame-switcher and b/frame/payload/bin/frame-switcher differ diff --git a/src/home_platform.h b/src/home_platform.h index 082a6c8..bd76ef6 100644 --- a/src/home_platform.h +++ b/src/home_platform.h @@ -266,6 +266,28 @@ inline int run(const std::vector& args, int nice, bool wait) { inline void sleepMs(int ms) { std::this_thread::sleep_for(std::chrono::milliseconds(ms)); } +// Is SteamVR running (its server)? Asked before connecting as a utility: on Windows, connecting starts SteamVR. +inline bool steamVrRunning() { +#ifdef _WIN32 + bool found = false; + const HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (snap == INVALID_HANDLE_VALUE) return false; + PROCESSENTRY32W e = {}; + e.dwSize = sizeof e; + for (BOOL ok = Process32FirstW(snap, &e); ok && !found; ok = Process32NextW(snap, &e)) found = _wcsicmp(e.szExeFile, L"vrserver.exe") == 0; + CloseHandle(snap); + return found; +#else + std::error_code ec; + for (const auto& e : std::filesystem::directory_iterator("/proc", ec)) { + std::string comm; + std::getline(std::ifstream(e.path() / "comm"), comm); + if (comm == "vrserver") return true; + } + return false; +#endif +} + // Files by path, whatever the characters in it (Windows: the wide API; a user name like "José" is no problem). inline FILE* openFile(const std::filesystem::path& p, const char* mode) { #ifdef _WIN32 diff --git a/src/main.cpp b/src/main.cpp index 2ea6ca5..c702bf6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1915,6 +1915,7 @@ int runInstall(bool install) { << " \"description\": \"Meta homes as SteamVR's environment\" } }\n" << " } ]\n}\n"; } + if (!homeos::steamVrRunning()) { LOG("SteamVR isn't running: the installer registers Frame Home in its config files"); return 3; } vr::EVRInitError ierr = vr::VRInitError_None; vr::VR_Init(&ierr, vr::VRApplication_Utility); if (ierr != vr::VRInitError_None) { LOG("VR_Init: %s (SteamVR not running)", vr::VR_GetVRInitErrorAsEnglishDescription(ierr)); return 3; } diff --git a/src/switcher.cpp b/src/switcher.cpp index 3405248..84ff428 100644 --- a/src/switcher.cpp +++ b/src/switcher.cpp @@ -1858,6 +1858,7 @@ int runInstall() { << "\",\n \"arguments\": \"\",\n \"is_dashboard_overlay\": true,\n" " \"strings\": { \"en_us\": { \"name\": \"Environments\",\n" " \"description\": \"Switch SteamVR's environment (Frame Home)\" } }\n } ]\n}\n"; + if (!homeos::steamVrRunning()) { LOG("SteamVR isn't running: the installer registers the panel in its config files"); return 3; } vr::EVRInitError ierr = vr::VRInitError_None; vr::VR_Init(&ierr, vr::VRApplication_Utility); // 3: SteamVR not running — the installer registers the manifest in SteamVR's config files instead. @@ -1877,6 +1878,7 @@ int runInstall() { // The panel off SteamVR: no longer started with it, its manifest gone, a running one closed. int runUninstall() { const fs::path manifest = rootDir() / "frame-switcher.vrmanifest"; + if (!homeos::steamVrRunning()) return 3; // (connecting would start it: the uninstaller edits its files) vr::EVRInitError ierr = vr::VRInitError_None; vr::VR_Init(&ierr, vr::VRApplication_Utility); if (ierr != vr::VRInitError_None) { LOG("VR_Init: %s (SteamVR not running)", vr::VR_GetVRInitErrorAsEnglishDescription(ierr)); return 3; }