From bca88a56a6d8a8bfea89cabcfb8413fe1bdcb1f3 Mon Sep 17 00:00:00 2001 From: Hermes Team Date: Mon, 24 Aug 2026 10:07:33 +0700 Subject: [PATCH] =?UTF-8?q?fix(launcher):=20=D0=B1=D1=80=D0=B0=D1=83=D0=B7?= =?UTF-8?q?=D0=B5=D1=80=20=D1=83=D0=B1=D0=B8=D0=B2=D0=B0=D0=BB=20=D1=81?= =?UTF-8?q?=D0=B5=D1=80=D0=B2=D0=B5=D1=80,=20=D1=83=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D1=89=D0=B8=D0=BA=20=D0=B7=D0=B0=D0=BF=D1=83?= =?UTF-8?q?=D1=81=D0=BA=D0=B0=D0=BB=20=D0=B4=D0=B5=D1=81=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D0=BF=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20=D0=B2=D0=B5?= =?UTF-8?q?=D0=B1=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Главное: ERR_CONNECTION_REFUSED в окне приложения. browserProc.WaitForExit() возвращался МГНОВЕННО, когда Edge уже был запущен: новый msedge.exe передаёт окно работающему экземпляру и сразу завершается. Лаунчер считал, что окно закрыли, и убивал сервер, пока страница ещё грузилась. Браузер теперь запускается с отдельным профилем (--user-data-dir), то есть процесс живёт столько же, сколько окно. Плюс подстраховка: выход браузера быстрее пяти секунд не считается закрытием окна. Та же ловушка была в Linux-лаунчере — исправлена там же. Проверено вживую: сервер отвечает 200 И окно приложения живо («Hermes Hub — Панель управления»). 2. Установщик по галочке «Запустить сейчас» открывал ДЕСКТОП. Владелец получал десктопное окно и принимал его за старую версию — внешне оно и правда другое. Теперь запускается веб-интерфейс, подпись галочки уточнена. Десктоп остаётся доступен своим ярлыком. Тесты: 373 passed, ruff чисто. Установщик пересобран. Co-Authored-By: Claude Opus 5 --- installer/HermesHubSetup.cs | 19 ++++++++++++++----- launcher/HermesHub.exe | Bin 6144 -> 6144 bytes launcher/HermesHubWeb.cs | 21 ++++++++++++++++++++- launcher/HermesHubWeb.exe | Bin 12288 -> 12800 bytes launcher/hermes-hub-web.sh | 8 +++++++- 5 files changed, 41 insertions(+), 7 deletions(-) diff --git a/installer/HermesHubSetup.cs b/installer/HermesHubSetup.cs index bafc630..80b101f 100644 --- a/installer/HermesHubSetup.cs +++ b/installer/HermesHubSetup.cs @@ -18,7 +18,7 @@ namespace HermesHubSetup // Подставляется сборщиком из фактического git-коммита. Раньше здесь // жил зашитый "8cddc9f", то есть манифест сообщал неправду о том, из // какого кода собран установщик. - public const string BuildCommit = "57e7ca2"; + public const string BuildCommit = "ef6a9e1"; public const string MIN_HERMES_VERSION = "0.20.0"; public const string MAX_TESTED_HERMES = "0.20.4"; @@ -993,7 +993,7 @@ namespace HermesHubSetup lblDone.Height = 140; chkLaunchNow = new CheckBox(); - chkLaunchNow.Text = "Запустить Hermes Hub сейчас"; + chkLaunchNow.Text = "Запустить веб-интерфейс Hermes Hub сейчас"; chkLaunchNow.Checked = true; chkLaunchNow.Location = new Point(0, 150); chkLaunchNow.AutoSize = true; @@ -1030,10 +1030,19 @@ namespace HermesHubSetup { if (chkLaunchNow != null && chkLaunchNow.Checked) { - string exe = Path.Combine(SetupEngine.TargetInstallDir, "HermesHub.exe"); - if (File.Exists(exe)) + // Запускаем ВЕБ-интерфейс, а не десктоп. Владелец после + // установки получал десктопное окно и принимал его за старую + // версию: внешне оно и правда другое. Веб — то, ради чего + // ставили; десктоп остаётся доступен своим ярлыком. + string webExe = Path.Combine(SetupEngine.TargetInstallDir, "HermesHubWeb.exe"); + string desktopExe = Path.Combine(SetupEngine.TargetInstallDir, "HermesHub.exe"); + if (File.Exists(webExe)) { - Process.Start(exe); + Process.Start(webExe); + } + else if (File.Exists(desktopExe)) + { + Process.Start(desktopExe); } } this.Close(); diff --git a/launcher/HermesHub.exe b/launcher/HermesHub.exe index 22fae0c99851073d087b2946e7cf5436adb471c6..a5aa2fb9e32ca3ed3495f24f72100cde7b65db6a 100644 GIT binary patch delta 35 rcmZoLXfT-2!4$o9W7jDjfje@&;syue9i}R77Yx15c5ibE?;I`w0r(Cv delta 35 rcmZoLXfT-2!DPF6W7jDjfkV}az0DJz`)>&-_`2bzis0rH-Z@+V9oi5P diff --git a/launcher/HermesHubWeb.cs b/launcher/HermesHubWeb.cs index d633e42..87164bf 100644 --- a/launcher/HermesHubWeb.cs +++ b/launcher/HermesHubWeb.cs @@ -178,17 +178,28 @@ namespace HermesHub // 4. Locate browser in strict priority: Edge -> Chrome -> Chromium registry -> Fallback string browserPath = FindChromiumBrowser(); Process browserProc = null; + DateTime browserStartedAt = DateTime.UtcNow; if (!string.IsNullOrEmpty(browserPath)) { ProcessStartInfo browserPsi = new ProcessStartInfo(); browserPsi.FileName = browserPath; - browserPsi.Arguments = string.Format("--app=\"{0}\" --window-size=1400,900", targetUrl); + // Отдельный профиль браузера обязателен. Без него запущенный + // msedge.exe передаёт задачу УЖЕ РАБОТАЮЩЕМУ экземпляру и тут же + // завершается: WaitForExit возвращается мгновенно, лаунчер + // считает окно закрытым и убивает сервер, пока страница ещё + // грузится. Владелец видел ERR_CONNECTION_REFUSED. + string browserProfile = Path.Combine(hermesHome, "web_browser_profile"); + try { Directory.CreateDirectory(browserProfile); } catch { } + browserPsi.Arguments = string.Format( + "--app=\"{0}\" --window-size=1400,900 --user-data-dir=\"{1}\" --no-first-run --no-default-browser-check", + targetUrl, browserProfile); browserPsi.UseShellExecute = false; try { browserProc = Process.Start(browserPsi); + browserStartedAt = DateTime.UtcNow; } catch (Exception ex) { @@ -226,6 +237,14 @@ namespace HermesHub } catch { } + // Подстраховка: если процесс браузера завершился почти сразу, + // это почти наверняка передача окна другому экземпляру, а не + // закрытие пользователем. Убивать сервер в этом случае нельзя. + if (DateTime.UtcNow - browserStartedAt < TimeSpan.FromSeconds(5)) + { + return; + } + try { if (!serverProcess.HasExited) diff --git a/launcher/HermesHubWeb.exe b/launcher/HermesHubWeb.exe index 527ab8b36e22345c67963ba6baa9ac786c548c31..04036e9853b371dc3b91a79c251fd0c73187c23e 100644 GIT binary patch delta 2138 zcmaJ>eQZ-z6hHU1@4of5D|_wO2K(yPwS8mj?7qif!p61^&9a1=I8{tZ5+w7vpmuv zUUj3#fv?P7B1L2d`;>TykByOh$0UM%}wl0vMD71V%j*dYc2gqeR?t#N_4Ci zJURvhFS*Hf3t3iV)!rSye_zVc6FwK*!&=2uy;L=p0vO|QPGeZSW{b9c*?{}E=cn48 zat+4q1ya6@!xpvt+Ji`daDisJB$t%0xU>?2N^pd-NprhFa?3MOb59nQTxuc4r70Lm zgJBRATu=nbm8RfHVh55-_G-BkE5cZrJqy&^T2hvhk0Es_#RbweEuDjbv|OK@freX} zBG+oD_g~}(bwBbFl(}&VJm9#rs@z$D4bdz%n&fyw8$~Cs?^I@Cl?S8HcPEqxe`Z$1U2|=EN-A1q)5vjw0 z2dm6Q2T+wH!GKb)>q>*h@gTyf&WW6ONrK=ytm5kgh8Cw_COcQG~w{X2C z_OiJ;bF(QyyB=32X#tU4GPjWTS)paN@3a_aP1I;HC+;1tkfDBn7An&wqE-vrXYq5b z7B*&S@^o2XfRph!MR5qfdyy*hQR1exmW`6pn~kcnfGtS&I1~FBTKGS_y~!TpXJ01w z)TI~!oI?Q5BVNV5Iol#?sJ}OiCjp%}#&dYC&h|Da#ygvWKBvEZK8_e>qkWOBvU;ZC z&kx}7=r;t5==wr-z$pX59l#)&wAa~#w z=q2@_(gCuVyg;3>oP0uGB>{4p9zuDJzD<^spU~sLyX=9I46wr&qy)_HG3ka)=*lF6 zWD7aU{*+e67TXqa1@%=;<@4&x%e>7El@;EK>Y7S#LwRMXx1y@1s?^uuE3a-Ui=9cm z!3{SCBEco0z994lBOUFL?p9?3G=|h*cSKP)&hKBNz&tgGoJk)n3xp!girVyCC<0n$ z+d!Znl!1=6!LEoJ=#GSxerQ&ezP4bu(%%!-LXQQ*;U#O4*0wPm3HFt=1|zU6*!5)a z+1Q12j>IlxaQqC<1_(kIbl|Ik0vjNVwu<(EZm)q5JcAyHo?$;^Hx4_%i+_U&mKS;; z01x!2X5+5HYK+r*BS{VpOCGU#jSj+DlLcyv z?z2T-V^6uWQ;$;z#*SMtlw~yuycG?$)9tk#!=Iyx=Q~YzjO3+prfEi&R0{skecqlEwf delta 1676 zcmaJ=U2GIp6h8Ov%$@z|PCL8XKe{a2-R?N-*ZZFgG|K|?`J3R1AflthM1 zYl0!teZapqMwcs^5`jchABaBas%fLt_@tQlKqMw4x~Xp%QfU(-L`?C_?N;%{N#=a# zeCOw$d*)1Gv@r7KtC37;`Y2SMMWDn(JOFVdoNJ_-D_(kBo$Ch}vWXFZWvSTg=gs7h zJJ5nm7~eRbB5g$HpOXYh@-m5pmodS92JxjJ!(VLxUp4>`wDDzpMNjd^XchgM@u%n( zM~l|N&(LiGuh3S3f6#t`8AnFoi;j@M3yuzfKRVI^ebS)7gHpG^b5fKX;S18Ru!8b~ z0{2v~Aiqo+xx(Her}?|ADTpT#syQhUj!n_inv?~TgsZJ~fP?m9?Wh~wmx38}|@c#Ztz#r8jI!@Vb zCmI%v$80^O#k7ctgLQ)zvxp4GwQ9W!O%sdQT%D=g3TnE6ia!eFc7G780XsBkMqm%P zt&h;q>(Oo1Q#f9?DW&7=-El0Hwo!D`HUQQV##KUgu7$wAF)eo45HCA3F}uSKJTq!` zWBz?ts?1B={ith$1liw#zv4POxhMm8@wRvZv?Fd<`}WYu0IJaLL$udtou97o?;v7| zy(IRq;5^z*h;#SxO(_bOk)zlVO8p`1X(ECNZWa#Xbj=+wiCr@5Nd=CZ8M|Xgvw^(A8*q>U~WaAN}cOtFh{=3JsD5}6|rVza@Ys4cKCS zw>txs8j92G!yxzxs>?p*A67B@c-C{EX$lkH)138|%U=hF21j7kWhZUYDcQUy;f|!#znMs7goa)8Z3uLcpKNf&v>}YJ3wbW ze6Kf`m`5+wqZsTyg+HpBnK_g=7`tUjlZ=h1nt8t9O++gfIyLaWadkYTYNU^+)X~fh z`~=Zc0Q)3>0^Tn=G+~V$dv+Yh4cBmaV)*@|`-k989Y76o(SiNDunTbF!hXuHs)^do zXkiht0a!%n1KeBvONR-%3X|e*>p@(Flh7FQ5X<<>wlD*6%yT~Cnf$}IjNwQ=dnJ{j00+Qed zPLkk(De^R&MCLZ^Cc~t_i@pP;o4&m?mQLq;w{J`5jci9cXKc%F?J~02T;6EkvOV3| z+u7BdPNhnRYnQ0!iNj+PdDF_B7@H`4(GVc-Uu~30j^7RSm%iHcGt=PW=-rtMvt5r~ zy45^(^29vw593Q-s;WU5i0^qdsl@qriOpMm&rya%;U!fLgRk&9O095K=rhhRMbC`S zkivwjUWNGzulWi^-l}g5%(5{0W>s_rRhJ^GXz*d(@GbV+173SpZ9QCUuA|HSrBCz+ TNJ(w|Q>HZ?B`tM}6jRFIte!N7 diff --git a/launcher/hermes-hub-web.sh b/launcher/hermes-hub-web.sh index 7f25fab..9c6cbcf 100644 --- a/launcher/hermes-hub-web.sh +++ b/launcher/hermes-hub-web.sh @@ -121,7 +121,13 @@ done if [ -n "$CHROMIUM_BIN" ]; then # Launch in Application Window mode without address bar, tabs, or menus - "$CHROMIUM_BIN" --app="$TARGET_URL" --window-size=1400,900 "$@" + # Отдельный профиль: иначе запущенный браузер передаёт окно уже + # работающему экземпляру и сразу завершается — ожидание его закрытия + # срабатывает мгновенно. На Windows это приводило к тому, что сервер + # убивали, пока страница ещё грузилась. + BROWSER_PROFILE="$HERMES_HOME/web_browser_profile" + mkdir -p "$BROWSER_PROFILE" + "$CHROMIUM_BIN" --app="$TARGET_URL" --window-size=1400,900 --user-data-dir="$BROWSER_PROFILE" --no-first-run --no-default-browser-check "$@" else # Fallback to standard default browser echo "Запуск в обычном браузере: режим приложения (без адресной строки) требует Google Chrome, Chromium или Microsoft Edge."