fix(app): show toast + open Sound settings when mic enumeration returns nothing

Before: clicking "Запустить" in jarvis-gui spawned jarvis-app, which
silently exited with code 1 (or in release builds, looked like the
console window flashed and closed). The pv_recorder library returns
INVALID_ARGUMENT from pv_recorder_init when Windows Core Audio reports
zero capture endpoints (some other app holding the mic exclusively,
or all input devices disabled in mmsys.cpl). User saw no actionable
feedback.

Now: on recorder::init failure jarvis-app calls notify_mic_problem()
which (Windows-only):
- Fires a long-duration Windows toast titled "J.A.R.V.I.S.: микрофон
  не найден" with a hint pointing at mmsys.cpl / Recording.
- Spawns "start ms-settings:sound" so the Sound settings page opens
  automatically — user can re-enable the mic in two clicks.

Then the original app::close(1, ...) path runs to keep the same exit
behaviour the GUI's get_jarvis_app_stats poller expects.

Cargo.toml: jarvis-app now pulls winrt-notification (already in
workspace.dependencies via jarvis-core) for the toast.

Also incidentally fixed: the release-build C0000139 (entrypoint not
found) loader crash that was showing up before this change. It went
away after the workspace dep was added and the release relink ran.
Most likely the previous release exe had a stale import table from an
earlier partial rebuild; the clean relink resolves it.

Non-Windows builds get a no-op eprintln so the binary still compiles
for Linux/macOS.
This commit is contained in:
Bossiara13 2026-05-15 11:58:47 +03:00
parent 16ef413962
commit 01ea46c091
2 changed files with 24 additions and 0 deletions

View file

@ -26,6 +26,7 @@ features = []
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3", features = ["winuser"] }
winrt-notification.workspace = true
[target.'cfg(target_os = "linux")'.dependencies]
gtk = "0.18"

View file

@ -59,6 +59,7 @@ fn main() -> Result<(), String> {
eprintln!("[jarvis-app] step: recorder::init");
if recorder::init().is_err() {
notify_mic_problem();
app::close(1, "recorder::init failed");
}
@ -173,3 +174,25 @@ fn main() -> Result<(), String> {
pub fn should_stop() -> bool {
SHOULD_STOP.load(Ordering::SeqCst)
}
#[cfg(target_os = "windows")]
fn notify_mic_problem() {
use winrt_notification::{Toast, Duration as ToastDuration};
let _ = Toast::new(Toast::POWERSHELL_APP_ID)
.title("J.A.R.V.I.S.: микрофон не найден")
.text1("Windows не видит ни одного устройства записи.")
.text2("Откройте mmsys.cpl → Recording → включите микрофон и перезапустите Jarvis.")
.duration(ToastDuration::Long)
.show();
// Open Sound recording settings so the user can fix it in two clicks.
let _ = std::process::Command::new("cmd")
.args(["/C", "start", "", "ms-settings:sound"])
.spawn();
}
#[cfg(not(target_os = "windows"))]
fn notify_mic_problem() {
eprintln!("[jarvis-app] no recording device detected; check OS audio settings");
}