From 557f8667ad1d2ceb9720ec9a33163549994c751a Mon Sep 17 00:00:00 2001 From: Exest Date: Fri, 7 Aug 2026 10:38:08 +0300 Subject: [PATCH] Release v1.0.25: fix auto-updater elevation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Апдейтер: повышение прав через cmd.exe /c вместо запуска .cmd напрямую (ShellExecute runas на .cmd срабатывал не на всех системах — elevated процесс молча не стартовал, обновление в Program Files не применялось, клиент зацикливался на уведомлении). Payload переносится в ASCII-путь, чтобы имя папки из архива не ломало аргумент SRC для robocopy. Co-Authored-By: Claude Opus 4.8 --- src/ElectronicPharmacy/Classes/AutoUpdater.cs | 38 ++++++++++++++++--- .../Properties/AssemblyInfo.cs | 4 +- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/ElectronicPharmacy/Classes/AutoUpdater.cs b/src/ElectronicPharmacy/Classes/AutoUpdater.cs index 45d6542..f1433f0 100644 --- a/src/ElectronicPharmacy/Classes/AutoUpdater.cs +++ b/src/ElectronicPharmacy/Classes/AutoUpdater.cs @@ -74,6 +74,24 @@ namespace Электронная_Фармация.Classes throw new InvalidOperationException("В архиве не найден exe приложения."); } + // Переносим payload в путь без спецсимволов: имя корневой папки в архиве + // бывает в чужой кодировке, и такой путь ломает аргумент SRC у robocopy + // (особенно при запуске под elevated cmd с OEM-кодовой страницей). + var asciiPayload = Path.Combine(workRoot, "payload"); + try + { + if (Directory.Exists(asciiPayload)) + { + Directory.Delete(asciiPayload, true); + } + Directory.Move(payloadDir, asciiPayload); + payloadDir = asciiPayload; + } + catch + { + // Если перенос не удался — работаем с исходным путём. + } + var needsElevation = !IsDirectoryWritable(installDir); var updaterBat = Path.Combine(workRoot, "apply-update.cmd"); WriteUpdaterScript(updaterBat); @@ -82,12 +100,12 @@ namespace Электронная_Фармация.Classes ? "Нужны права администратора для установки в Program Files..." : "Подготовка перезапуска..."); + var batchArgs = Quote(payloadDir) + " " + Quote(installDir) + " " + + Quote(Path.GetFileName(currentExe)) + " " + + Process.GetCurrentProcess().Id; + var psi = new ProcessStartInfo { - FileName = updaterBat, - Arguments = Quote(payloadDir) + " " + Quote(installDir) + " " + - Quote(Path.GetFileName(currentExe)) + " " + - Process.GetCurrentProcess().Id, UseShellExecute = true, WorkingDirectory = workRoot, WindowStyle = needsElevation ? ProcessWindowStyle.Normal : ProcessWindowStyle.Hidden, @@ -95,9 +113,19 @@ namespace Электронная_Фармация.Classes }; if (needsElevation) { - // UAC prompt — без этого robocopy в Program Files молча не заменяет exe. + // ВАЖНО: повышаем права через cmd.exe (PE-исполняемый), а НЕ через + // .cmd-файл напрямую. ShellExecute с verb=runas на .cmd срабатывает не + // на всех системах (у batch может не быть runas-ассоциации), из-за чего + // elevated-процесс молча не запускается и обновление не применяется. + psi.FileName = "cmd.exe"; + psi.Arguments = "/c \"\"" + updaterBat + "\" " + batchArgs + "\""; psi.Verb = "runas"; } + else + { + psi.FileName = updaterBat; + psi.Arguments = batchArgs; + } try { diff --git a/src/ElectronicPharmacy/Properties/AssemblyInfo.cs b/src/ElectronicPharmacy/Properties/AssemblyInfo.cs index 2a8745c..174ef7d 100644 --- a/src/ElectronicPharmacy/Properties/AssemblyInfo.cs +++ b/src/ElectronicPharmacy/Properties/AssemblyInfo.cs @@ -32,6 +32,6 @@ using System.Runtime.InteropServices; // пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ // пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ "*", пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅ: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.24.0")] -[assembly: AssemblyFileVersion("1.0.24.0")] +[assembly: AssemblyVersion("1.0.25.0")] +[assembly: AssemblyFileVersion("1.0.25.0")]