diff --git a/docs/gitea-updates.md b/docs/gitea-updates.md
new file mode 100644
index 0000000..7d82714
--- /dev/null
+++ b/docs/gitea-updates.md
@@ -0,0 +1,24 @@
+# Gitea + принудительные обновления десктопа
+
+Полная инструкция по установке Gitea: в репозитории `source` → `docs/gitea/`.
+
+Клиент при старте (`ElectroPharmacy_Load`) вызывает Gitea API:
+
+`GET {UpdateCheckBaseUrl}/api/v1/repos/{UpdateRepo}/releases/latest`
+
+Настройки (можно сменить без пересборки через user settings):
+
+| Ключ | По умолчанию |
+|------|----------------|
+| `UpdateCheckBaseUrl` | `https://git.24pharmdata.ru` |
+| `UpdateRepo` | `pharmdata/elfisa-pharmacy` |
+| `UpdateApiToken` | пусто (нужен для private releases) |
+
+## Регламент релиза
+
+1. Поднять `AssemblyVersion` / `AssemblyFileVersion` в `Properties/AssemblyInfo.cs`.
+2. `git tag vX.Y.Z && git push gitea master --tags`
+3. `powershell -File dist\build-release.ps1`
+4. Gitea → Releases → New Release → прикрепить ZIP.
+
+Старый клиент с меньшей версией увидит модалку «Доступно новое обновление» и не пустит в работу.
diff --git a/src/ElectronicPharmacy/App.config b/src/ElectronicPharmacy/App.config
index 262f9c5..40c70be 100644
--- a/src/ElectronicPharmacy/App.config
+++ b/src/ElectronicPharmacy/App.config
@@ -42,6 +42,15 @@
+
+ https://git.24pharmdata.ru
+
+
+ pharmdata/elfisa-pharmacy
+
+
+
+
Электронная_Фармация.Properties.Settings>
\ No newline at end of file
diff --git a/src/ElectronicPharmacy/Classes/AppConfig.cs b/src/ElectronicPharmacy/Classes/AppConfig.cs
index 195d2f1..6fa57c2 100644
--- a/src/ElectronicPharmacy/Classes/AppConfig.cs
+++ b/src/ElectronicPharmacy/Classes/AppConfig.cs
@@ -10,6 +10,8 @@ namespace Электронная_Фармация.Classes
public static class AppConfig
{
public const string DefaultApiBaseUrl = "https://24pharmdata.ru";
+ public const string DefaultUpdateCheckBaseUrl = "https://git.24pharmdata.ru";
+ public const string DefaultUpdateRepo = "pharmdata/elfisa-pharmacy";
private const string LegacyApiBaseUrl = "http://195.34.241.84:9988";
private const string ApiBaseUrlEnvVar = "ELF_API_BASE_URL";
private static bool _sqliteInteropPrepared;
@@ -126,6 +128,69 @@ namespace Электронная_Фармация.Classes
Settings.Default.Save();
}
+ ///
+ /// Gitea base URL for forced update checks (no trailing slash).
+ ///
+ public static string UpdateCheckBaseUrl
+ {
+ get
+ {
+ var fromEnv = Environment.GetEnvironmentVariable("ELF_UPDATE_CHECK_BASE_URL");
+ if (!string.IsNullOrWhiteSpace(fromEnv))
+ {
+ return NormalizeApiBaseUrl(fromEnv);
+ }
+
+ var fromSettings = Settings.Default.UpdateCheckBaseUrl;
+ if (!string.IsNullOrWhiteSpace(fromSettings))
+ {
+ return NormalizeApiBaseUrl(fromSettings);
+ }
+
+ return DefaultUpdateCheckBaseUrl;
+ }
+ }
+
+ ///
+ /// owner/repo on Gitea, e.g. pharmdata/elfisa-pharmacy.
+ ///
+ public static string UpdateRepo
+ {
+ get
+ {
+ var fromEnv = Environment.GetEnvironmentVariable("ELF_UPDATE_REPO");
+ if (!string.IsNullOrWhiteSpace(fromEnv))
+ {
+ return fromEnv.Trim().Trim('/');
+ }
+
+ var fromSettings = Settings.Default.UpdateRepo;
+ if (!string.IsNullOrWhiteSpace(fromSettings))
+ {
+ return fromSettings.Trim().Trim('/');
+ }
+
+ return DefaultUpdateRepo;
+ }
+ }
+
+ ///
+ /// Optional read-only Gitea token for private release repos.
+ ///
+ public static string UpdateApiToken
+ {
+ get
+ {
+ var fromEnv = Environment.GetEnvironmentVariable("ELF_UPDATE_API_TOKEN");
+ if (!string.IsNullOrWhiteSpace(fromEnv))
+ {
+ return fromEnv.Trim();
+ }
+
+ return Settings.Default.UpdateApiToken ?? string.Empty;
+ }
+ }
+
private static void EnsureSQLiteInteropInBaseDir()
{
// System.Data.SQLite ожидает SQLite.Interop.dll рядом с exe.
diff --git a/src/ElectronicPharmacy/Classes/UpdateChecker.cs b/src/ElectronicPharmacy/Classes/UpdateChecker.cs
new file mode 100644
index 0000000..1c780e6
--- /dev/null
+++ b/src/ElectronicPharmacy/Classes/UpdateChecker.cs
@@ -0,0 +1,302 @@
+using System;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Reflection;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace Электронная_Фармация.Classes
+{
+ public sealed class UpdateCheckResult
+ {
+ public bool CheckedOk { get; set; }
+ public bool UpdateRequired { get; set; }
+ public string LocalVersion { get; set; }
+ public string LatestVersion { get; set; }
+ public string ReleaseUrl { get; set; }
+ public string DownloadUrl { get; set; }
+ public string ErrorMessage { get; set; }
+ }
+
+ ///
+ /// Checks Gitea Releases API for a newer desktop build.
+ ///
+ public static class UpdateChecker
+ {
+ private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true
+ };
+
+ public static UpdateCheckResult CheckForUpdate()
+ {
+ return CheckForUpdate(null, null, null, null);
+ }
+
+ ///
+ /// Overload for tests / smoke scripts (null = use AppConfig).
+ ///
+ public static UpdateCheckResult CheckForUpdate(
+ string baseUrl,
+ string repo,
+ string token,
+ string localVersionOverride)
+ {
+ try
+ {
+ return CheckForUpdateAsync(baseUrl, repo, token, localVersionOverride)
+ .GetAwaiter().GetResult();
+ }
+ catch (Exception ex)
+ {
+ AppDebugLog.Info("UpdateChecker", $"Проверка обновлений пропущена: {ex.Message}");
+ return new UpdateCheckResult
+ {
+ CheckedOk = false,
+ UpdateRequired = false,
+ LocalVersion = localVersionOverride ?? GetLocalVersionString(),
+ ErrorMessage = ex.Message
+ };
+ }
+ }
+
+ public static async Task CheckForUpdateAsync()
+ {
+ return await CheckForUpdateAsync(null, null, null, null).ConfigureAwait(false);
+ }
+
+ public static async Task CheckForUpdateAsync(
+ string baseUrlOverride,
+ string repoOverride,
+ string tokenOverride,
+ string localVersionOverride)
+ {
+ var localVersion = string.IsNullOrWhiteSpace(localVersionOverride)
+ ? GetLocalVersionString()
+ : NormalizeVersion(localVersionOverride);
+ var result = new UpdateCheckResult
+ {
+ LocalVersion = localVersion
+ };
+
+ var baseUrl = (baseUrlOverride ?? AppConfig.UpdateCheckBaseUrl).TrimEnd('/');
+ var repo = (repoOverride ?? AppConfig.UpdateRepo).Trim('/');
+ if (string.IsNullOrWhiteSpace(baseUrl) || string.IsNullOrWhiteSpace(repo))
+ {
+ result.CheckedOk = false;
+ result.ErrorMessage = "UpdateCheckBaseUrl/UpdateRepo не заданы";
+ return result;
+ }
+
+ var url = $"{baseUrl}/api/v1/repos/{repo}/releases/latest";
+ using (var client = new HttpClient { Timeout = TimeSpan.FromSeconds(8) })
+ {
+ var token = tokenOverride ?? AppConfig.UpdateApiToken;
+ if (!string.IsNullOrWhiteSpace(token))
+ {
+ client.DefaultRequestHeaders.Authorization =
+ new AuthenticationHeaderValue("token", token.Trim());
+ }
+
+ client.DefaultRequestHeaders.Accept.Add(
+ new MediaTypeWithQualityHeaderValue("application/json"));
+
+ AppDebugLog.Info("UpdateChecker", $"GET {url}");
+ HttpResponseMessage response;
+ try
+ {
+ response = await client.GetAsync(url).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ // Offline pharmacies must continue working.
+ AppDebugLog.Info("UpdateChecker", $"Сеть недоступна, обновление не блокируем: {ex.Message}");
+ result.CheckedOk = false;
+ result.ErrorMessage = ex.Message;
+ return result;
+ }
+
+ var body = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ if (!response.IsSuccessStatusCode)
+ {
+ AppDebugLog.Info("UpdateChecker",
+ $"releases/latest HTTP {(int)response.StatusCode}: {Truncate(body, 200)}");
+ result.CheckedOk = false;
+ result.ErrorMessage = $"HTTP {(int)response.StatusCode}";
+ return result;
+ }
+
+ var release = JsonSerializer.Deserialize(body, JsonOptions);
+ if (release == null || string.IsNullOrWhiteSpace(release.TagName))
+ {
+ result.CheckedOk = false;
+ result.ErrorMessage = "Пустой ответ releases/latest";
+ return result;
+ }
+
+ var latest = NormalizeVersion(release.TagName);
+ result.LatestVersion = latest;
+ result.ReleaseUrl = string.IsNullOrWhiteSpace(release.HtmlUrl)
+ ? $"{baseUrl}/{repo}/releases/tag/{release.TagName}"
+ : release.HtmlUrl;
+ result.DownloadUrl = PickZipAssetUrl(release) ?? result.ReleaseUrl;
+ result.CheckedOk = true;
+ result.UpdateRequired = IsRemoteNewer(latest, localVersion);
+
+ AppDebugLog.Info("UpdateChecker",
+ $"Локально={localVersion}, latest={latest}, updateRequired={result.UpdateRequired}");
+ return result;
+ }
+ }
+
+ public static string GetLocalVersionString()
+ {
+ try
+ {
+ var asm = Assembly.GetExecutingAssembly();
+ var file = asm.GetCustomAttribute()?.Version;
+ if (!string.IsNullOrWhiteSpace(file))
+ {
+ return NormalizeVersion(file);
+ }
+
+ return NormalizeVersion(asm.GetName().Version?.ToString() ?? "0.0.0.0");
+ }
+ catch
+ {
+ return "0.0.0.0";
+ }
+ }
+
+ ///
+ /// Returns true when remoteTag is strictly newer than localVersion.
+ /// Accepts "v1.0.9", "1.0.9", "1.0.9.0".
+ ///
+ public static bool IsRemoteNewer(string remoteTag, string localVersion)
+ {
+ if (!TryParseVersion(remoteTag, out var remote) ||
+ !TryParseVersion(localVersion, out var local))
+ {
+ return false;
+ }
+
+ return remote > local;
+ }
+
+ public static string NormalizeVersion(string value)
+ {
+ if (string.IsNullOrWhiteSpace(value))
+ {
+ return "0.0.0.0";
+ }
+
+ value = value.Trim();
+ if (value.StartsWith("v", StringComparison.OrdinalIgnoreCase))
+ {
+ value = value.Substring(1);
+ }
+
+ // Drop pre-release suffix: 1.0.9-beta -> 1.0.9
+ var dash = value.IndexOf('-');
+ if (dash > 0)
+ {
+ value = value.Substring(0, dash);
+ }
+
+ if (TryParseVersion(value, out var v))
+ {
+ return v.ToString();
+ }
+
+ return value;
+ }
+
+ public static bool TryParseVersion(string value, out Version version)
+ {
+ version = null;
+ if (string.IsNullOrWhiteSpace(value))
+ {
+ return false;
+ }
+
+ value = value.Trim();
+ if (value.StartsWith("v", StringComparison.OrdinalIgnoreCase))
+ {
+ value = value.Substring(1);
+ }
+
+ var dash = value.IndexOf('-');
+ if (dash > 0)
+ {
+ value = value.Substring(0, dash);
+ }
+
+ var parts = value.Split('.');
+ if (parts.Length == 1)
+ {
+ value = value + ".0.0.0";
+ }
+ else if (parts.Length == 2)
+ {
+ value = value + ".0.0";
+ }
+ else if (parts.Length == 3)
+ {
+ value = value + ".0";
+ }
+
+ return Version.TryParse(value, out version);
+ }
+
+ private static string PickZipAssetUrl(GiteaRelease release)
+ {
+ if (release?.Assets == null || release.Assets.Length == 0)
+ {
+ return null;
+ }
+
+ var zip = release.Assets.FirstOrDefault(a =>
+ !string.IsNullOrWhiteSpace(a?.Name) &&
+ a.Name.EndsWith(".zip", StringComparison.OrdinalIgnoreCase));
+ if (zip == null)
+ {
+ zip = release.Assets.FirstOrDefault(a => !string.IsNullOrWhiteSpace(a?.BrowserDownloadUrl));
+ }
+
+ return zip?.BrowserDownloadUrl;
+ }
+
+ private static string Truncate(string s, int max)
+ {
+ if (string.IsNullOrEmpty(s) || s.Length <= max)
+ {
+ return s ?? string.Empty;
+ }
+
+ return s.Substring(0, max) + "...";
+ }
+
+ private sealed class GiteaRelease
+ {
+ [JsonPropertyName("tag_name")]
+ public string TagName { get; set; }
+
+ [JsonPropertyName("html_url")]
+ public string HtmlUrl { get; set; }
+
+ [JsonPropertyName("assets")]
+ public GiteaAsset[] Assets { get; set; }
+ }
+
+ private sealed class GiteaAsset
+ {
+ [JsonPropertyName("name")]
+ public string Name { get; set; }
+
+ [JsonPropertyName("browser_download_url")]
+ public string BrowserDownloadUrl { get; set; }
+ }
+ }
+}
diff --git a/src/ElectronicPharmacy/ElectronicPharmacy.csproj b/src/ElectronicPharmacy/ElectronicPharmacy.csproj
index 46400ed..176bf79 100644
--- a/src/ElectronicPharmacy/ElectronicPharmacy.csproj
+++ b/src/ElectronicPharmacy/ElectronicPharmacy.csproj
@@ -129,6 +129,7 @@
+
Form
@@ -201,6 +202,12 @@
HF_Settings.cs
+
+ Form
+
+
+ HF_UpdateAvailable.cs
+
Form
diff --git a/src/ElectronicPharmacy/Form1.cs b/src/ElectronicPharmacy/Form1.cs
index 1ce1d3e..1bde269 100644
--- a/src/ElectronicPharmacy/Form1.cs
+++ b/src/ElectronicPharmacy/Form1.cs
@@ -67,6 +67,28 @@ namespace Электронная_Фармация
{
FinalizeModernShell();
+ // Принудительное обновление: если на Gitea есть более новый Release — не пускаем в работу.
+ // При недоступной сети не блокируем (офлайн-аптека должна открываться).
+ try
+ {
+ var update = UpdateChecker.CheckForUpdate();
+ if (update != null && update.UpdateRequired)
+ {
+ using (var dlg = new HF_UpdateAvailable(update))
+ {
+ UiThemeHelper.ApplyToControlTree(dlg);
+ dlg.ShowDialog(this);
+ }
+
+ Application.Exit();
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ AppDebugLog.Info("App", $"Проверка обновлений пропущена: {ex.Message}");
+ }
+
FCheckDatabaseIntegrary fCheckDatabaseIntegrary = new FCheckDatabaseIntegrary();
UiThemeHelper.ApplyToControlTree(fCheckDatabaseIntegrary);
fCheckDatabaseIntegrary.ShowDialog();
diff --git a/src/ElectronicPharmacy/HelpForms/HF_UpdateAvailable.Designer.cs b/src/ElectronicPharmacy/HelpForms/HF_UpdateAvailable.Designer.cs
new file mode 100644
index 0000000..07d26ce
--- /dev/null
+++ b/src/ElectronicPharmacy/HelpForms/HF_UpdateAvailable.Designer.cs
@@ -0,0 +1,107 @@
+namespace Электронная_Фармация.HelpForms
+{
+ partial class HF_UpdateAvailable
+ {
+ private System.ComponentModel.IContainer components = null;
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ private void InitializeComponent()
+ {
+ this.panelHeader = new System.Windows.Forms.Panel();
+ this.lblTitle = new System.Windows.Forms.Label();
+ this.lblMessage = new System.Windows.Forms.Label();
+ this.btnDownload = new Elfisa.UI.Controls.ModernButton();
+ this.btnExit = new Elfisa.UI.Controls.ModernButton();
+ this.panelHeader.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // panelHeader
+ //
+ this.panelHeader.Controls.Add(this.lblTitle);
+ this.panelHeader.Dock = System.Windows.Forms.DockStyle.Top;
+ this.panelHeader.Location = new System.Drawing.Point(0, 0);
+ this.panelHeader.Name = "panelHeader";
+ this.panelHeader.Size = new System.Drawing.Size(520, 56);
+ this.panelHeader.TabIndex = 0;
+ //
+ // lblTitle
+ //
+ this.lblTitle.Font = new System.Drawing.Font("Segoe UI Semibold", 13.8F, System.Drawing.FontStyle.Bold);
+ this.lblTitle.ForeColor = System.Drawing.Color.White;
+ this.lblTitle.Location = new System.Drawing.Point(12, 10);
+ this.lblTitle.Name = "lblTitle";
+ this.lblTitle.Size = new System.Drawing.Size(480, 36);
+ this.lblTitle.TabIndex = 0;
+ this.lblTitle.Text = "Доступно новое обновление";
+ this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // lblMessage
+ //
+ this.lblMessage.Font = new System.Drawing.Font("Segoe UI", 11F);
+ this.lblMessage.Location = new System.Drawing.Point(24, 72);
+ this.lblMessage.Name = "lblMessage";
+ this.lblMessage.Size = new System.Drawing.Size(472, 120);
+ this.lblMessage.TabIndex = 1;
+ this.lblMessage.Text = "Доступно новое обновление";
+ //
+ // btnDownload
+ //
+ this.btnDownload.Font = new System.Drawing.Font("Segoe UI", 11F);
+ this.btnDownload.Location = new System.Drawing.Point(24, 220);
+ this.btnDownload.Name = "btnDownload";
+ this.btnDownload.Size = new System.Drawing.Size(180, 40);
+ this.btnDownload.TabIndex = 2;
+ this.btnDownload.Text = "Скачать";
+ this.btnDownload.Click += new System.EventHandler(this.btnDownload_Click);
+ //
+ // btnExit
+ //
+ this.btnExit.Font = new System.Drawing.Font("Segoe UI", 11F);
+ this.btnExit.Location = new System.Drawing.Point(316, 220);
+ this.btnExit.Name = "btnExit";
+ this.btnExit.Size = new System.Drawing.Size(180, 40);
+ this.btnExit.TabIndex = 3;
+ this.btnExit.Text = "Выход";
+ this.btnExit.Click += new System.EventHandler(this.btnExit_Click);
+ //
+ // HF_UpdateAvailable
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(520, 290);
+ this.Controls.Add(this.btnExit);
+ this.Controls.Add(this.btnDownload);
+ this.Controls.Add(this.lblMessage);
+ this.Controls.Add(this.panelHeader);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "HF_UpdateAvailable";
+ this.ShowIcon = false;
+ this.ShowInTaskbar = false;
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Обновление";
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.HF_UpdateAvailable_FormClosing);
+ this.panelHeader.ResumeLayout(false);
+ this.ResumeLayout(false);
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel panelHeader;
+ private System.Windows.Forms.Label lblTitle;
+ private System.Windows.Forms.Label lblMessage;
+ private Elfisa.UI.Controls.ModernButton btnDownload;
+ private Elfisa.UI.Controls.ModernButton btnExit;
+ }
+}
diff --git a/src/ElectronicPharmacy/HelpForms/HF_UpdateAvailable.cs b/src/ElectronicPharmacy/HelpForms/HF_UpdateAvailable.cs
new file mode 100644
index 0000000..85b762a
--- /dev/null
+++ b/src/ElectronicPharmacy/HelpForms/HF_UpdateAvailable.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Diagnostics;
+using System.Windows.Forms;
+using Электронная_Фармация.Classes;
+
+namespace Электронная_Фармация.HelpForms
+{
+ public partial class HF_UpdateAvailable : Form
+ {
+ private readonly UpdateCheckResult _result;
+
+ public HF_UpdateAvailable(UpdateCheckResult result)
+ {
+ _result = result ?? throw new ArgumentNullException(nameof(result));
+ InitializeComponent();
+ UiThemeHelper.ApplyToControlTree(this);
+
+ var latest = string.IsNullOrWhiteSpace(_result.LatestVersion) ? "?" : _result.LatestVersion;
+ var local = string.IsNullOrWhiteSpace(_result.LocalVersion) ? "?" : _result.LocalVersion;
+ lblMessage.Text =
+ $"Доступно новое обновление {latest} (у вас {local}).{Environment.NewLine}{Environment.NewLine}" +
+ "Для продолжения работы необходимо установить новую версию.";
+ }
+
+ private void btnDownload_Click(object sender, EventArgs e)
+ {
+ var url = !string.IsNullOrWhiteSpace(_result.DownloadUrl)
+ ? _result.DownloadUrl
+ : _result.ReleaseUrl;
+ if (string.IsNullOrWhiteSpace(url))
+ {
+ UiDialogs.ShowError("Ссылка на обновление не задана.", "Обновление", this);
+ return;
+ }
+
+ try
+ {
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = url,
+ UseShellExecute = true
+ });
+ }
+ catch (Exception ex)
+ {
+ UiDialogs.ShowError($"Не удалось открыть ссылку:{Environment.NewLine}{ex.Message}", "Обновление", this);
+ }
+ }
+
+ private void btnExit_Click(object sender, EventArgs e)
+ {
+ DialogResult = DialogResult.Abort;
+ Close();
+ }
+
+ private void HF_UpdateAvailable_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ // Крестик / Alt+F4 — тоже выход из приложения (не пускать в работу).
+ if (DialogResult != DialogResult.Abort)
+ {
+ DialogResult = DialogResult.Abort;
+ }
+ }
+ }
+}
diff --git a/src/ElectronicPharmacy/Properties/AssemblyInfo.cs b/src/ElectronicPharmacy/Properties/AssemblyInfo.cs
index db6856a..3251393 100644
--- a/src/ElectronicPharmacy/Properties/AssemblyInfo.cs
+++ b/src/ElectronicPharmacy/Properties/AssemblyInfo.cs
@@ -1,36 +1,36 @@
-using System.Reflection;
+using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// Общие сведения об этой сборке предоставляются следующим набором
-// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
-// связанных со сборкой.
-[assembly: AssemblyTitle("Электронная Фармация")]
+//
+// . ,
+// .
+[assembly: AssemblyTitle(" ")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Электронная Фармация")]
-[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyProduct(" ")]
+[assembly: AssemblyCopyright("Copyright 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
-// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
-// COM, следует установить атрибут ComVisible в TRUE для этого типа.
+// False ComVisible
+// COM.
+// COM, ComVisible TRUE .
[assembly: ComVisible(false)]
-// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+// GUID , COM
[assembly: Guid("145d8060-4187-4871-b4fb-8df795727b66")]
-// Сведения о версии сборки состоят из указанных ниже четырех значений:
+// :
//
-// Основной номер версии
-// Дополнительный номер версии
-// Номер сборки
-// Редакция
+//
+//
+//
+//
//
-// Можно задать все значения или принять номера сборки и редакции по умолчанию
-// используя "*", как показано ниже:
+//
+// "*", :
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.3.0")]
-[assembly: AssemblyFileVersion("1.0.3.0")]
+[assembly: AssemblyVersion("1.0.10.0")]
+[assembly: AssemblyFileVersion("1.0.10.0")]
diff --git a/src/ElectronicPharmacy/Properties/Settings.Designer.cs b/src/ElectronicPharmacy/Properties/Settings.Designer.cs
index bd579f2..d574351 100644
--- a/src/ElectronicPharmacy/Properties/Settings.Designer.cs
+++ b/src/ElectronicPharmacy/Properties/Settings.Designer.cs
@@ -167,5 +167,41 @@ namespace Электронная_Фармация.Properties {
}
}
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("https://git.24pharmdata.ru")]
+ public string UpdateCheckBaseUrl {
+ get {
+ return ((string)(this["UpdateCheckBaseUrl"]));
+ }
+ set {
+ this["UpdateCheckBaseUrl"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("pharmdata/elfisa-pharmacy")]
+ public string UpdateRepo {
+ get {
+ return ((string)(this["UpdateRepo"]));
+ }
+ set {
+ this["UpdateRepo"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string UpdateApiToken {
+ get {
+ return ((string)(this["UpdateApiToken"]));
+ }
+ set {
+ this["UpdateApiToken"] = value;
+ }
+ }
+
}
}
diff --git a/src/ElectronicPharmacy/Properties/Settings.settings b/src/ElectronicPharmacy/Properties/Settings.settings
index 83ffe4b..995ccdf 100644
--- a/src/ElectronicPharmacy/Properties/Settings.settings
+++ b/src/ElectronicPharmacy/Properties/Settings.settings
@@ -38,5 +38,14 @@
01.01.0001 00:00:00
+
+ https://git.24pharmdata.ru
+
+
+ pharmdata/elfisa-pharmacy
+
+
+
+
\ No newline at end of file
diff --git a/tools/UpdateCheckSmoke/Program.cs b/tools/UpdateCheckSmoke/Program.cs
new file mode 100644
index 0000000..1bacc34
--- /dev/null
+++ b/tools/UpdateCheckSmoke/Program.cs
@@ -0,0 +1,31 @@
+using System;
+using Электронная_Фармация.Classes;
+
+namespace UpdateCheckSmoke
+{
+ internal static class Program
+ {
+ private static int Main(string[] args)
+ {
+ // args: baseUrl repo localVersion
+ var baseUrl = args.Length > 0 ? args[0] : "http://127.0.0.1:18765";
+ var repo = args.Length > 1 ? args[1] : "pharmdata/elfisa-pharmacy";
+ var local = args.Length > 2 ? args[2] : "1.0.3.0";
+
+ var result = UpdateChecker.CheckForUpdate(baseUrl, repo, null, local);
+ Console.WriteLine("CheckedOk=" + result.CheckedOk);
+ Console.WriteLine("UpdateRequired=" + result.UpdateRequired);
+ Console.WriteLine("Local=" + result.LocalVersion);
+ Console.WriteLine("Latest=" + result.LatestVersion);
+ Console.WriteLine("Download=" + result.DownloadUrl);
+ Console.WriteLine("Error=" + result.ErrorMessage);
+
+ if (!result.CheckedOk)
+ {
+ return 2;
+ }
+
+ return result.UpdateRequired ? 0 : 1;
+ }
+ }
+}