Nouveau Kind « VrDevice » dans le bandeau de santé. Pour chaque appareil SteamVR (HMD, manettes, trackers, base stations) on lit via OpenVR : batterie %, état de charge, niveau d'activité (actif / veille / inactif) et serial number. Severity du pill calculée sur le batterie : < 15% rouge, < 30% orange, sinon vert ; charging force le vert. Implémentation : P/Invoke direct dans openvr_api.dll (BSD-3) — pas de NuGet, pas de bundling de la DLL. La runtime est résolue dynamiquement via DllImportResolver depuis : 1. %LocalAppData%\openvr\openvrpaths.vrpath (canon écrit par SteamVR), 2. fallback C:\Program Files (x86)\Steam\steamapps\common\SteamVR\bin\win64\. Si SteamVR n'est pas installé → pill « SteamVR non installé » (Unknown, gris). Si SteamVR pas lancé → pill « SteamVR non lancé / aucun HMD » (Error, rouge). Init en mode VRApplication_Background, donc on lit l'état sans devenir scene application ni monopoliser le compositor. Éditeur : nouveau radio « Appareil SteamVR » à côté de Process / Ping ; quand il est sélectionné, le champ Target devient une ComboBox d'alias (HMD, Manette gauche/droite, Tracker 1-3, Base station 1-2) au lieu du TextBox libre. Le mapping alias → TrackedDeviceIndex se fait à chaque query (controllers via GetTrackedDeviceIndexForControllerRole, trackers et base stations par énumération avec compteur de classe). Robustesse : init lazy une fois pour toute la vie du process (init/shutdown répétés coûtent 100-500 ms). Vtable IVRSystem_022 résolue par index slot dans une struct contiguë de IntPtr (pas de struct marshaling, donc immune aux changements de slots qu'on n'utilise pas). Si SteamVR crash en cours de session, le service détecte au prochain tick et marque la session broken pour retenter au tick suivant. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PS_Launcher — Installeur
Génère un setup Windows (PSLauncher-Setup-{version}.exe) qui distribue
le launcher principal + son updater dans Program Files\ASTERION VR\PSLauncher\.
Pré-requis
- .NET 8 SDK (déjà installé pour build le projet)
- Inno Setup 6.x — https://jrsoftware.org/isdl.php (gratuit, ~6 Mo)
Build en une commande
Depuis la racine du repo :
powershell -ExecutionPolicy Bypass -File installer\build-installer.ps1
Ça enchaîne :
dotnet publish src/PSLauncher.App -c Release→PSLauncher.exe(~77 Mo)dotnet publish src/PSLauncher.Updater -c Release→PSLauncher.Updater.exe(~10 Mo)ISCC PSLauncher.iss→installer/output/PSLauncher-Setup-X.Y.Z.exe
Le fichier final fait ~80 Mo (compression ultra Inno + binaires self-contained).
Distribution
Tu balances un seul .exe au client :
- Il lance, choisit français/anglais, clique Suivant×3, c'est installé.
- Raccourci bureau + menu Démarrer créés.
- Désinstallation propre via Programmes et fonctionnalités.
Le cache utilisateur (%LocalAppData%\PSLauncher\config.json, logs, downloads partiels)
n'est pas touché par l'install/désinstall — la license et les paramètres survivent.
Mise à jour du launcher
Le launcher se met à jour seul via PSLauncher.Updater.exe (cf. flow auto-update).
Le client n'a pas besoin de rejouer l'installeur sauf changement majeur (TFM, déps).
Bumper la version
Avant de rebuild un installeur :
src/PSLauncher.App/PSLauncher.App.csproj→<Version>X.Y.Z</Version>(et AssemblyVersion / FileVersion)installer/PSLauncher.iss→#define MyAppVersion "X.Y.Z"installer/build-installer.ps1
Côté serveur, mets aussi à jour manifest/versions.json section launcher avec la
nouvelle version + URL de download du nouveau PSLauncher.exe (via le backoffice
ou édition manuelle, puis php tools/sign-manifest.php).
Code-signing (optionnel)
Pour éviter le warning SmartScreen "éditeur inconnu", il faut signer
PSLauncher.exe, PSLauncher.Updater.exe et PSLauncher-Setup-X.Y.Z.exe avec
un certificat Authenticode (OV ~250 €/an, EV ~400 €/an, ou gratuit via SignPath
pour OSS). Hors-scope du script actuel.