appupdater

This commit is contained in:
2025-11-17 19:02:40 +01:00
parent 4e657469b3
commit 26a807c8be
12 changed files with 353 additions and 109 deletions

View File

@@ -272,47 +272,12 @@ public partial class MainForm : Window
AppConfig.Instance.LastMinecraftProfilePath = TextBoxMinecraftProfileFolder.Text?.Trim(); AppConfig.Instance.LastMinecraftProfilePath = TextBoxMinecraftProfileFolder.Text?.Trim();
} }
private async Task UpdateApp()
{
if (Debugger.IsAttached)
return;
var myAppPath = EnvironmentEx.ProcessPath!;
var updater = new UpdateClient(Program.UpdateUrl, Assembly.GetEntryAssembly()!.GetAppVersion(), AppChannel.Stable)
{
Distro = RuntimeInformationsEx.GetRuntimeIdentifier(),
};
if (await updater.CheckForUpdate() is {} packageToInstall
&& await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, MsgBoxLangRes.UpdateAvailable, ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowDialogAsync(this) == ButtonResult.Yes)
{
SetStatus(GeneralLangRes.DownloadProgramUpdate, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
IsEnabled = false;
if (await updater.DownloadPackageAsync(packageToInstall)
&& await updater.InstallPackageAsync(packageToInstall, myAppPath))
{
IsVisible = false;
await Process.Start(myAppPath).WaitForExitAsync();
Environment.Exit(0);
return;
}
IsEnabled = true;
}
}
private async void MainForm_Loaded(object? sender, RoutedEventArgs e) private async void MainForm_Loaded(object? sender, RoutedEventArgs e)
{ {
#if !DISABLE_UPDATE var updates = new AppUpdates(Program.UpdateUrl, this);
try updates.OnDownloadProgramUpdate += (o, args) => SetStatus(GeneralLangRes.DownloadProgramUpdate, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
{ await updates.UpdateApp();
await UpdateApp(); ClearStatus();
}
catch (Exception ex)
{
await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, string.Format(MsgBoxLangRes.UpdateAvailable, ex.Message), ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowAsync();
IsEnabled = true;
}
#endif
CheckStatusAndUpdate(true); CheckStatusAndUpdate(true);
} }

View File

@@ -51,7 +51,7 @@ internal static class SharedFunctions
api.Model.Progress.Set(i); api.Model.Progress.Set(i);
} }
api.Model.Progress.End(); api.Model.Progress.Stop();
} }
public static async Task<bool> CollectUpdates(IMainApi api, params InstallAction[] actions) public static async Task<bool> CollectUpdates(IMainApi api, params InstallAction[] actions)
@@ -122,7 +122,7 @@ internal static class SharedFunctions
api.Model.Progress.Set(i); api.Model.Progress.Set(i);
} }
api.Model.Progress.End(); api.Model.Progress.Stop();
} }
public static void ClearDirectLinks(IMainApi api, params MainWindowGridRow[] rows) public static void ClearDirectLinks(IMainApi api, params MainWindowGridRow[] rows)
@@ -138,7 +138,7 @@ internal static class SharedFunctions
api.Model.Progress.Set(i); api.Model.Progress.Set(i);
} }
api.Model.Progress.End(); api.Model.Progress.Stop();
} }
public static string GenerateChangelog(InstallInfos installInfos, UpdateInfo updateInfos) public static string GenerateChangelog(InstallInfos installInfos, UpdateInfo updateInfos)

View File

@@ -1,10 +1,9 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// Dieser Code wurde von einem Tool generiert. // This code was generated by a tool.
// Laufzeitversion:4.0.30319.42000
// //
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // Changes to this file may cause incorrect behavior and will be lost if
// der Code erneut generiert wird. // the code is regenerated.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -12,46 +11,32 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
using System; using System;
/// <summary> [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. [System.Diagnostics.DebuggerNonUserCodeAttribute()]
/// </summary> [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert public class MsgBoxLangRes {
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class MsgBoxLangRes {
private static global::System.Resources.ResourceManager resourceMan; private static System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal MsgBoxLangRes() { internal MsgBoxLangRes() {
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. public static System.Resources.ResourceManager ResourceManager {
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.Equals(null, resourceMan)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.MsgBoxLangRes", typeof(MsgBoxLangRes).Assembly); System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.MsgBoxLangRes", typeof(MsgBoxLangRes).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle public static System.Globalization.CultureInfo Culture {
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get { get {
return resourceCulture; return resourceCulture;
} }
@@ -60,76 +45,64 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
/// <summary> public static string ChangelogCopiedToClipboard {
/// Sucht eine lokalisierte Zeichenfolge, die The changelog for the selected version has been generated and copied to the clipboard. ähnelt.
/// </summary>
internal static string ChangelogCopiedToClipboard {
get { get {
return ResourceManager.GetString("ChangelogCopiedToClipboard", resourceCulture); return ResourceManager.GetString("ChangelogCopiedToClipboard", resourceCulture);
} }
} }
/// <summary> public static string ChangelogCopiedToClipboard_Title {
/// Sucht eine lokalisierte Zeichenfolge, die Changelog generated successfully ähnelt.
/// </summary>
internal static string ChangelogCopiedToClipboard_Title {
get { get {
return ResourceManager.GetString("ChangelogCopiedToClipboard_Title", resourceCulture); return ResourceManager.GetString("ChangelogCopiedToClipboard_Title", resourceCulture);
} }
} }
/// <summary> public static string ModlistCopiedToClipboard {
/// Sucht eine lokalisierte Zeichenfolge, die The modlist has been generated and copied to the clipboard. ähnelt.
/// </summary>
internal static string ModlistCopiedToClipboard {
get { get {
return ResourceManager.GetString("ModlistCopiedToClipboard", resourceCulture); return ResourceManager.GetString("ModlistCopiedToClipboard", resourceCulture);
} }
} }
/// <summary> public static string ModlistCopiedToClipboard_Title {
/// Sucht eine lokalisierte Zeichenfolge, die Modlist generated successfully ähnelt.
/// </summary>
internal static string ModlistCopiedToClipboard_Title {
get { get {
return ResourceManager.GetString("ModlistCopiedToClipboard_Title", resourceCulture); return ResourceManager.GetString("ModlistCopiedToClipboard_Title", resourceCulture);
} }
} }
/// <summary> public static string ModlistGenerated {
/// Sucht eine lokalisierte Zeichenfolge, die The modlist has been generated successfully and saved to the selected location. ähnelt.
/// </summary>
internal static string ModlistGenerated {
get { get {
return ResourceManager.GetString("ModlistGenerated", resourceCulture); return ResourceManager.GetString("ModlistGenerated", resourceCulture);
} }
} }
/// <summary> public static string ModlistGenerated_Title {
/// Sucht eine lokalisierte Zeichenfolge, die Modlist generated successfully ähnelt.
/// </summary>
internal static string ModlistGenerated_Title {
get { get {
return ResourceManager.GetString("ModlistGenerated_Title", resourceCulture); return ResourceManager.GetString("ModlistGenerated_Title", resourceCulture);
} }
} }
/// <summary> public static string RemoveUpdate {
/// Sucht eine lokalisierte Zeichenfolge, die Are you sure that you want to delete this update? ähnelt.
/// </summary>
internal static string RemoveUpdate {
get { get {
return ResourceManager.GetString("RemoveUpdate", resourceCulture); return ResourceManager.GetString("RemoveUpdate", resourceCulture);
} }
} }
/// <summary> public static string RemoveUpdate_Title {
/// Sucht eine lokalisierte Zeichenfolge, die Remove update ähnelt.
/// </summary>
internal static string RemoveUpdate_Title {
get { get {
return ResourceManager.GetString("RemoveUpdate_Title", resourceCulture); return ResourceManager.GetString("RemoveUpdate_Title", resourceCulture);
} }
} }
public static string UpdateAvailable {
get {
return ResourceManager.GetString("UpdateAvailable", resourceCulture);
}
}
public static string UpdateAvailable_Title {
get {
return ResourceManager.GetString("UpdateAvailable_Title", resourceCulture);
}
}
} }
} }

View File

@@ -141,4 +141,11 @@
<data name="RemoveUpdate_Title" xml:space="preserve"> <data name="RemoveUpdate_Title" xml:space="preserve">
<value>Remove update</value> <value>Remove update</value>
</data> </data>
<data name="UpdateAvailable" xml:space="preserve">
<value>A new version of this program is available! Install now?
If you confirm, the update will be installed automatically within a few seconds.</value>
</data>
<data name="UpdateAvailable_Title" xml:space="preserve">
<value>New program version available</value>
</data>
</root> </root>

View File

@@ -7,6 +7,8 @@ namespace ModpackUpdater.Apps.Manager;
public static class Program public static class Program
{ {
public const string UpdateUrl = "https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater/-/snippets/3/raw/main/updates-manager.json";
internal static readonly SettingsManager settingsManager; internal static readonly SettingsManager settingsManager;
public static ISettings Settings => settingsManager.Instance; public static ISettings Settings => settingsManager.Instance;

View File

@@ -7,8 +7,11 @@ using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Model; using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features; using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Settings; using ModpackUpdater.Apps.Manager.Settings;
using ModpackUpdater.Apps.Manager.Ui.Models.MainWindow; using ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Pilz.Extensions; using Pilz.Extensions;
using Pilz.Features; using Pilz.Features;
using Pilz.UI.AvaloniaUI.Features; using Pilz.UI.AvaloniaUI.Features;
@@ -91,7 +94,7 @@ public partial class MainWindow : Window, IMainApi
Model.Progress.Start(); Model.Progress.Start();
await ws.Save(); await ws.Save();
Model.Progress.End(); Model.Progress.Stop();
} }
private void LoadRecentWorkspaces() private void LoadRecentWorkspaces()
@@ -126,8 +129,13 @@ public partial class MainWindow : Window, IMainApi
settings.Workspaces.RemoveAt(20); settings.Workspaces.RemoveAt(20);
} }
private void Window_OnLoaded(object? sender, RoutedEventArgs e) private async void Window_OnLoaded(object? sender, RoutedEventArgs e)
{ {
var updater = new AppUpdates(Program.UpdateUrl, this);
updater.OnDownloadProgramUpdate += (o, args) => Model.Progress.Start();
await updater.UpdateApp();
Model.Progress.Stop();
LoadRecentWorkspaces(); LoadRecentWorkspaces();
} }

View File

@@ -40,7 +40,7 @@ public class ProgressInfos : INotifyPropertyChanged
Value += 1; Value += 1;
} }
public void End() public void Stop()
{ {
IsVisible = false; IsVisible = false;
IsGeneric = false; IsGeneric = false;

View File

@@ -42,7 +42,7 @@ public partial class UpdatesCollectorView : AvaloniaFlyoutBase
break; break;
} }
Model.Progress.End(); Model.Progress.Stop();
} }
protected override object GetResult() protected override object GetResult()

View File

@@ -0,0 +1,59 @@
using System.Diagnostics;
using System.Reflection;
using Avalonia.Controls;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Pilz;
using Pilz.Extensions;
using Pilz.Runtime;
using Pilz.Updating.Client;
namespace ModpackUpdater.Apps;
public class AppUpdates(string updateUrl, Window mainWindow)
{
public event EventHandler? OnDownloadProgramUpdate;
public async Task UpdateApp()
{
#if !DISABLE_UPDATE
try
{
await UpdateAppCore();
}
catch (Exception ex)
{
await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, string.Format(MsgBoxLangRes.UpdateAvailable, ex.Message), ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowAsync();
mainWindow.IsEnabled = true;
}
#endif
}
private async Task UpdateAppCore()
{
if (Debugger.IsAttached)
return;
var myAppPath = EnvironmentEx.ProcessPath!;
var updater = new UpdateClient(updateUrl, Assembly.GetEntryAssembly()!.GetAppVersion(), AppChannel.Stable)
{
Distro = RuntimeInformationsEx.GetRuntimeIdentifier(),
};
if (await updater.CheckForUpdate() is {} packageToInstall
&& await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, MsgBoxLangRes.UpdateAvailable, ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowDialogAsync(mainWindow) == ButtonResult.Yes)
{
OnDownloadProgramUpdate?.Invoke(this, EventArgs.Empty);
mainWindow.IsEnabled = false;
if (await updater.DownloadPackageAsync(packageToInstall)
&& await updater.InstallPackageAsync(packageToInstall, myAppPath))
{
mainWindow.IsVisible = false;
await Process.Start(myAppPath).WaitForExitAsync();
Environment.Exit(0);
return;
}
mainWindow.IsEnabled = true;
}
}
}

View File

@@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps {
using System;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class MsgBoxLangRes {
private static System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal MsgBoxLangRes() {
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
public static System.Resources.ResourceManager ResourceManager {
get {
if (object.Equals(null, resourceMan)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.LangRes.MsgBoxLangRes", typeof(MsgBoxLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
public static System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
public static string UpdateAvailable {
get {
return ResourceManager.GetString("UpdateAvailable", resourceCulture);
}
}
public static string UpdateAvailable_Title {
get {
return ResourceManager.GetString("UpdateAvailable_Title", resourceCulture);
}
}
public static string ErrorWhileUpdate_Title {
get {
return ResourceManager.GetString("ErrorWhileUpdate_Title", resourceCulture);
}
}
public static string ErrorWhileUpdate {
get {
return ResourceManager.GetString("ErrorWhileUpdate", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="UpdateAvailable" xml:space="preserve">
<value>A new version of this program is available! Install now?
If you confirm, the update will be installed automatically within a few seconds.</value>
</data>
<data name="UpdateAvailable_Title" xml:space="preserve">
<value>New program version available</value>
</data>
<data name="ErrorWhileUpdate_Title" xml:space="preserve">
<value>Error while updating</value>
</data>
<data name="ErrorWhileUpdate" xml:space="preserve">
<value>An error happened while updating the program. Error message:\n{0}</value>
</data>
</root>

View File

@@ -12,12 +12,17 @@
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Symbols\*.svg" /> <EmbeddedResource Include="Symbols\*.svg" />
<EmbeddedResource Update="LangRes\MsgBoxLangRes.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>MsgBoxLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Pilz" Version="2.6.1" /> <PackageReference Include="Pilz" Version="2.6.1" />
<PackageReference Include="Pilz.UI" Version="3.1.4" /> <PackageReference Include="Pilz.UI" Version="3.1.4" />
<PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.2.18" /> <PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.2.18" />
<PackageReference Include="MessageBox.Avalonia" Version="3.3.0" />
<PackageReference Include="Avalonia" Version="11.3.8" /> <PackageReference Include="Avalonia" Version="11.3.8" />
<PackageReference Include="Avalonia.Desktop" Version="11.3.8" /> <PackageReference Include="Avalonia.Desktop" Version="11.3.8" />
<PackageReference Include="Avalonia.Svg" Version="11.3.0" /> <PackageReference Include="Avalonia.Svg" Version="11.3.0" />
@@ -28,6 +33,26 @@
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets> <IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets> <PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Pilz.Updating" Version="4.3.5" />
<PackageReference Include="Pilz.Updating.Client" Version="4.4.6" />
</ItemGroup>
<ItemGroup>
<Compile Update="LangRes\GeneralLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>GeneralLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\MsgBoxLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>MsgBoxLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\MsgBoxLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>MsgBoxLangRes.resx</DependentUpon>
</Compile>
</ItemGroup> </ItemGroup>
</Project> </Project>