Fix update hang: allow dialog close after download; harden updater wait.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Exest 2026-07-31 17:18:11 +03:00
parent 2230d4c73f
commit ee5e2db953
3 changed files with 26 additions and 16 deletions

View File

@ -151,28 +151,36 @@ namespace Электронная_Фармация.Classes
private static void WriteUpdaterScript(string path)
{
// Waits for app exit, copies files, keeps local DB/Logs, restarts exe.
// Waits for app exit (max ~30s, then force-kill), copies files, keeps DB/Logs, restarts.
var sb = new StringBuilder();
sb.AppendLine("@echo off");
sb.AppendLine("setlocal");
sb.AppendLine("setlocal EnableDelayedExpansion");
sb.AppendLine("set \"SRC=%~1\"");
sb.AppendLine("set \"DST=%~2\"");
sb.AppendLine("set \"EXENAME=%~3\"");
sb.AppendLine("set \"PID=%~4\"");
sb.AppendLine("set \"N=0\"");
sb.AppendLine("echo Waiting for PID %PID% ... > \"%TEMP%\\elfisa-updater.log\"");
sb.AppendLine(":waitloop");
sb.AppendLine("tasklist /FI \"PID eq %PID%\" 2>nul | find \"%PID%\" >nul");
sb.AppendLine("if not errorlevel 1 (");
sb.AppendLine(" timeout /t 1 /nobreak >nul");
sb.AppendLine(" goto waitloop");
sb.AppendLine("tasklist /FI \"PID eq %PID%\" 2>nul | findstr /C:\" %PID% \" >nul");
sb.AppendLine("if errorlevel 1 goto donewait");
sb.AppendLine("set /a N+=1");
sb.AppendLine("echo still alive n=!N! >> \"%TEMP%\\elfisa-updater.log\"");
sb.AppendLine("if !N! GEQ 30 (");
sb.AppendLine(" echo force kill %PID% >> \"%TEMP%\\elfisa-updater.log\"");
sb.AppendLine(" taskkill /PID %PID% /F >nul 2>&1");
sb.AppendLine(" goto donewait");
sb.AppendLine(")");
sb.AppendLine("timeout /t 1 /nobreak >nul");
// ping instead of timeout — timeout often hangs in hidden windows
sb.AppendLine("ping 127.0.0.1 -n 2 >nul");
sb.AppendLine("goto waitloop");
sb.AppendLine(":donewait");
sb.AppendLine("ping 127.0.0.1 -n 2 >nul");
sb.AppendLine("echo Copying update... >> \"%TEMP%\\elfisa-updater.log\"");
// /E copy tree; exclude local DB and logs from being overwritten/removed.
sb.AppendLine("robocopy \"%SRC%\" \"%DST%\" /E /R:2 /W:1 /NFL /NDL /NJH /NJS /XF efClient.db *.db /XD Logs");
sb.AppendLine("set \"RC=%ERRORLEVEL%\"");
sb.AppendLine("echo robocopy=%RC% >> \"%TEMP%\\elfisa-updater.log\"");
// robocopy 0-7 = success-ish
sb.AppendLine("set \"RC=!ERRORLEVEL!\"");
sb.AppendLine("echo robocopy=!RC! >> \"%TEMP%\\elfisa-updater.log\"");
sb.AppendLine("echo Starting \"%DST%\\%EXENAME%\" >> \"%TEMP%\\elfisa-updater.log\"");
sb.AppendLine("start \"\" /D \"%DST%\" \"%DST%\\%EXENAME%\"");
sb.AppendLine("exit /b 0");
File.WriteAllText(path, sb.ToString(), Encoding.Default);

View File

@ -53,8 +53,9 @@ namespace Электронная_Фармация.HelpForms
{
await AutoUpdater.ApplyUpdateAsync(_result, progress);
lblMessage.Text = "Обновление скачано. Перезапуск...";
// Нельзя звать Application.Exit() из async continuation — падает
// «коллекция была изменена». Закрываем диалог; Form1 завершит процесс.
// Снимаем блокировку закрытия, иначе диалог зависает навечно
// на «Перезапуск...» и updater ждёт PID, который не завершается.
_updating = false;
DialogResult = DialogResult.OK;
Close();
}
@ -86,7 +87,8 @@ namespace Электронная_Фармация.HelpForms
private void HF_UpdateAvailable_FormClosing(object sender, FormClosingEventArgs e)
{
if (_updating)
// Блокируем только ручное закрытие во время скачивания.
if (_updating && DialogResult != DialogResult.OK)
{
e.Cancel = true;
return;

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// Можно задать все значения или принять номера сборки и редакции по умолчанию
// используя "*", как показано ниже:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.15.0")]
[assembly: AssemblyFileVersion("1.0.15.0")]
[assembly: AssemblyVersion("1.0.16.0")]
[assembly: AssemblyFileVersion("1.0.16.0")]