diff --git a/README.md b/README.md
index dea0ca1..31be994 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ Documentation will come in the near future, take a look at the book [Boriel Basi
Have fun!
-## Credits
+## ZX Basic Studio Team
- Development team:
- El Dr. Gusman
- Boriel
@@ -19,6 +19,13 @@ Have fun!
- AdolFITO
- HashIron
- SirRickster
+- Testers:
+ - AbenZaX
+ - Pedro Tomás (Pere)
+ - Jose Daniel Fernandez Santos (Fenix)
+ - Yoruguaman
+
+## Credits
- Icons from [SVG REPO](https://www.svgrepo.com/):
- Blivesta in MIT License
- Dazzle Ui in CC Attribution License
@@ -35,3 +42,8 @@ Have fun!
- Zest in MIT License
- Neuicons in MIT License via
- Dazzle Ui in CC Attribution License
+ - Siemens in MIT License
+ - Zest in MIT License
+ - Ananthanath A X Kalaiism in PD License
+
+
diff --git a/ZXBSInstaller.Log/ServiceLayer.cs b/ZXBSInstaller.Log/ServiceLayer.cs
index 174a25a..b3cbc07 100644
--- a/ZXBSInstaller.Log/ServiceLayer.cs
+++ b/ZXBSInstaller.Log/ServiceLayer.cs
@@ -22,15 +22,52 @@ namespace ZXBSInstaller.Log
///
public static class ServiceLayer
{
+ ///
+ /// Application configuration. It is stored in %AppData%\ZXBasicStudio\ZXBSInstallerOptions.json
+ ///
public static Config GeneralConfig = null;
+ ///
+ /// List of external tools.
+ ///
public static ExternalTool[] ExternalTools = null;
+ ///
+ /// Current operating system
+ ///
public static OperatingSystems CurrentOperatingSystem = OperatingSystems.All;
+ ///
+ /// True if the computer is a Mac
+ ///
+ public static bool IsMac=false;
+ ///
+ /// Used to cancel the current operation. It is set to true when the user clicks the cancel button and it is checked in all long operations to stop them if it is true.
+ ///
+ public static bool Cancel = false;
+
+ // Callbacks to update the UI from the service layer
+ ///
+ /// Show the status panel with a message. The message is used to inform the user about the current operation being performed. It is called from the service layer to update the UI.
+ ///
private static Action ShowStatusPanel = null;
+ ///
+ /// Update the status message and progress. It is called from the service layer to update the UI. The message is used to inform the user about the current operation being performed and the progress is a value between 0 and 100 that indicates the progress of the current operation.
+ ///
private static Action UpdateStatus = null;
+ ///
+ /// Hide the status panel. It is called from the service layer to update the UI when the current operation is finished or cancelled.
+ ///
private static Action HideStatusPanel = null;
+ ///
+ /// Refresh the list of external tools. It is called from the service layer to update the UI when the list of external tools is updated, for example, after installing or updating a tool.
+ ///
private static Action RefreshTools = null;
+ ///
+ /// Show a message in a dialog window. It is called from the service layer to show error messages or any other information that needs to be shown to the user.
+ ///
private static Action ShowMessage = null;
+ ///
+ /// Exit the application. It is called from the service layer to exit the application when launching ZXBasicStudio.
+ ///
private static Action ExitApp = null;
@@ -48,46 +85,64 @@ public static bool Initialize(
Action callBackShowMessage,
Action callBackExitApp)
{
- ShowStatusPanel = callBackShowStatusPanel;
- UpdateStatus = callBackUpdateStatus;
- HideStatusPanel = callBackHideStatusPanel;
- RefreshTools = callBackGetExternalTools;
- ShowMessage = callBackShowMessage;
- ExitApp = callBackExitApp;
+ try
+ {
+ // Set callbacks
+ ShowStatusPanel = callBackShowStatusPanel;
+ UpdateStatus = callBackUpdateStatus;
+ HideStatusPanel = callBackHideStatusPanel;
+ RefreshTools = callBackGetExternalTools;
+ ShowMessage = callBackShowMessage;
+ ExitApp = callBackExitApp;
- GetConfig();
+ // Retrive the configuration
+ GetConfig();
- if (OperatingSystem.IsWindows())
- {
- CurrentOperatingSystem = OperatingSystems.Windows;
- }
- else if (OperatingSystem.IsLinux())
- {
- CurrentOperatingSystem = OperatingSystems.Linux;
- }
- else if (OperatingSystem.IsMacOS())
- {
- if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+ // Set current operating system
+ if (OperatingSystem.IsWindows())
{
- CurrentOperatingSystem = OperatingSystems.MacOS_arm64;
+ CurrentOperatingSystem = OperatingSystems.Windows;
}
- else if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
+ else if (OperatingSystem.IsLinux())
{
- CurrentOperatingSystem = OperatingSystems.MacOS_x64;
+ CurrentOperatingSystem = OperatingSystems.Linux;
+ }
+ else if (OperatingSystem.IsMacOS())
+ {
+ IsMac = true;
+ if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+ {
+ CurrentOperatingSystem = OperatingSystems.MacOS_arm64;
+ }
+ else if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
+ {
+ CurrentOperatingSystem = OperatingSystems.MacOS_x64;
+ }
}
- }
- return true;
+ return true;
+ }
+ catch (Exception ex)
+ {
+ ShowMessage($"Error initializing.\r\n{ex.Message}{ex.StackTrace}");
+ return false;
+ }
}
- public static Config GetConfig()
+ ///
+ /// Get the config from file or create a new one if it doesn't exist. The config file is stored in %AppData%\ZXBasicStudio\ZXBSInstallerOptions.json and it contains the configuration for the installer, such as the URL to retrieve the external tools list, the base path to install the tools, etc.
+ ///
+ /// Config data. ServiceLayer.GeneralConfig is set
+ private static Config GetConfig()
{
try
{
+ // Build filePath
var filePath = Path.Combine(Environment.GetFolderPath(SpecialFolder.ApplicationData), "ZXBasicStudio", "ZXBSInstallerOptions.json");
if (File.Exists(filePath))
{
+ // Read config from file
var jsonString = File.ReadAllText(filePath);
var cfg = JsonSerializer.Deserialize(jsonString);
@@ -97,60 +152,83 @@ public static Config GetConfig()
}
else
{
+ // Create default config and save it to file
GeneralConfig = CreateConfig();
SaveConfig(GeneralConfig);
}
return GeneralConfig;
-
}
catch (Exception ex)
{
+ ShowMessage($"Error retrieving configuration.\r\n{ex.Message}{ex.StackTrace}");
return null;
}
}
- public static Config CreateConfig()
+ ///
+ /// Create the default config
+ ///
+ /// Config object with the default config
+ private static Config CreateConfig()
{
- List toolsPaths = null;
- var cfg = ServiceLayer.GeneralConfig;
- if (cfg == null)
+ try
{
- cfg = new Config()
+ List toolsPaths = null;
+ var cfg = ServiceLayer.GeneralConfig;
+ if (cfg == null)
{
- BasePath = Directory.GetParent(Directory.GetCurrentDirectory()).FullName,
- OnlyStableVersions = true,
- SetZXBSConfig = true,
- ToolsListURL = "https://zx.duefectucorp.com/zxbsinstaller.json"
- };
- }
+ // Create base config
+ cfg = new Config()
+ {
+ BasePath = Directory.GetParent(Directory.GetCurrentDirectory()).FullName,
+ OnlyStableVersions = true,
+ SetZXBSConfig = true,
+ ToolsListURL = "https://zx.duefectucorp.com/zxbsinstaller.json"
+ };
+ }
- if (cfg.ExternalTools_Paths == null)
- {
- cfg.ExternalTools_Paths = new List();
+ // Fill paths
+ if (cfg.ExternalTools_Paths == null)
+ {
+ cfg.ExternalTools_Paths = new List();
+ }
+ if (cfg.ExternalTools_Paths.Count == 0)
+ {
+ cfg.ExternalTools_Paths.Add(new ExternalTools_Path()
+ {
+ Id = "zxbsinstaller",
+ LocalPath = Directory.GetCurrentDirectory()
+ });
+ }
+ return cfg;
}
- if (cfg.ExternalTools_Paths.Count == 0)
+ catch (Exception ex)
{
- cfg.ExternalTools_Paths.Add(new ExternalTools_Path()
- {
- Id = "zxbsinstaller",
- LocalPath = Directory.GetCurrentDirectory()
- });
+ ShowMessage($"Error creating default configuration.\r\n{ex.Message}{ex.StackTrace}");
+ return null;
}
- return cfg;
}
+ ///
+ /// Save config to file. The config file is stored in %AppData%\ZXBasicStudio\ZXBSInstallerOptions.json and it contains the configuration for the installer, such as the URL to retrieve the external tools list, the base path to install the tools, etc. ServiceLayer.GeneralConfig is updated with the new config data.
+ ///
+ /// Config to store
+ /// Config with the current configuration
public static Config SaveConfig(Config config)
{
try
{
+ // Build dir and file path
var dir = Path.Combine(Environment.GetFolderPath(SpecialFolder.ApplicationData), "ZXBasicStudio");
var fileName = Path.Combine(dir, "ZXBSInstallerOptions.json");
if (!Directory.Exists(dir))
{
+ // Create directory if it doesn't exist
Directory.CreateDirectory(dir);
}
+ // Save config to file
var jsonString = JsonSerializer.Serialize(config, new JsonSerializerOptions() { WriteIndented = true });
File.WriteAllText(fileName, jsonString);
GeneralConfig = config;
@@ -159,8 +237,10 @@ public static Config SaveConfig(Config config)
}
catch (Exception ex)
{
+ ShowMessage($"Error saving configuration.\r\n{ex.Message}{ex.StackTrace}");
return null;
}
+
}
@@ -188,6 +268,10 @@ private static int ToInteger(object value)
}
+ ///
+ /// Open an url in the default browser. It is used to open the site and license urls of the external tools. It is called from the service layer when the user clicks on the site or license buttons of an external tool.
+ ///
+ /// Url to open
public static void OpenUrlInBrowser(string url)
{
try
@@ -211,6 +295,7 @@ public static void OpenUrlInBrowser(string url)
}
catch (Exception ex)
{
+ ShowMessage($"Error opening {url}.\r\n{ex.Message}{ex.StackTrace}");
}
}
@@ -221,50 +306,82 @@ public static void OpenUrlInBrowser(string url)
///
/// Retrieves all external tools configured for use with the application.
- /// The data is stored in https://raw.githubusercontent.com/boriel-basic/ZXBasicStudio/refs/heads/master/externaltools.json
///
+ /// Json string with the external tools information
/// An array of objects representing the available external tools. The array is empty
/// if no external tools are configured or can download the config file.
- public static ExternalTool[] GetExternalTools()
+ public static ExternalTool[] SetExternalTools(string json)
{
try
{
UpdateStatus?.Invoke("Retrieving external tools information...", 5);
- using var httpClient = new HttpClient();
- string json = httpClient.GetStringAsync(GeneralConfig.ToolsListURL).GetAwaiter().GetResult();
var tools = JsonSerializer.Deserialize(json);
+ if (tools == null)
+ {
+ ShowMessage("ERROR, unable to obtain the list of external tools. Download and install a new version of ZXBSInstaller.");
+ return null;
+ }
int max = tools.Length;
int prg = 10;
for (int n = 0; n < max; n++)
{
+ // Cancel?
+ if (Cancel)
+ {
+ return null;
+ }
+ // Update status
var tool = tools[n];
prg = (n * 90) / max;
UpdateStatus?.Invoke($"Retrieving versions for {tool.Name}...", prg + 10);
+ // Get available versions for tool
tool.Versions = GetAvailableToolVersion(tool);
if (tool.Versions == null)
{
tool.Versions = new ExternalTools_Version[0];
}
+ // Get installed version
tool.InstalledVersion = GetToolVersion(tool.Id);
// Set latest version
if (GeneralConfig.OnlyStableVersions)
{
- tool.LatestVersion = tool.Versions.
- Where(d => d.OperatingSystem == CurrentOperatingSystem &&
- d.BetaNumber == 0).
- OrderByDescending(d => d.VersionNumber).
- FirstOrDefault();
+ if (tool.Id == "zxbasic" && IsMac)
+ {
+ tool.LatestVersion = tool.Versions.
+ Where(d => d.OperatingSystem == OperatingSystems.MacOS &&
+ d.BetaNumber == 0).
+ OrderByDescending(d => d.VersionNumber).
+ FirstOrDefault();
+ }
+ else
+ {
+ tool.LatestVersion = tool.Versions.
+ Where(d => d.OperatingSystem == CurrentOperatingSystem &&
+ d.BetaNumber == 0).
+ OrderByDescending(d => d.VersionNumber).
+ FirstOrDefault();
+ }
}
if (tool.LatestVersion == null || !GeneralConfig.OnlyStableVersions)
{
- tool.LatestVersion = tool.Versions.
- Where(d => d.OperatingSystem == CurrentOperatingSystem).
- OrderByDescending(d => d.VersionNumber).
- FirstOrDefault();
+ if (tool.Id == "zxbasic" && IsMac)
+ {
+ tool.LatestVersion = tool.Versions.
+ Where(d => d.OperatingSystem == OperatingSystems.MacOS).
+ OrderByDescending(d => d.VersionNumber).
+ FirstOrDefault();
+ }
+ else
+ {
+ tool.LatestVersion = tool.Versions.
+ Where(d => d.OperatingSystem == CurrentOperatingSystem).
+ OrderByDescending(d => d.VersionNumber).
+ FirstOrDefault();
+ }
}
// Path for first versions of ZXBSInstalller
@@ -288,259 +405,92 @@ public static ExternalTool[] GetExternalTools()
}
}
}
-
+ // Set tool local path
tool.LocalPath = Path.Combine(GeneralConfig.BasePath, tool.Id);
}
- //GetPaths(ref tools);
-
+ // order tools by order property
ExternalTools = tools.OrderBy(d => d.Order).ToArray();
-
return ExternalTools;
}
catch (Exception ex)
{
+ ShowMessage($"Error retrieving external tools information. Please check your internet connection and try again.\r\n{ex.Message}{ex.StackTrace}");
return null;
}
-#if GENERATE_JSON
- var lst = new List();
- // Compiler
- {
- UpdateStatus?.Invoke(null, 10);
- var tool = new ExternalTool()
- {
- Id = "zxbasic",
- Enabled = true,
- Name = "Boriel ZX Basic Compiler",
- Author = "Boriel",
- Description = "ZXBCompiler is a ZX Spectrum BASIC cross compiler that translates ZX Spectrum BASIC code into optimized machine code, enabling faster execution and enhanced performance on ZX Spectrum systems. This tool is required to run and debug programs.",
- DirectUpdate = true,
- SupportedOperatingSystems = new OperatingSystems[] { OperatingSystems.Windows, OperatingSystems.Linux, OperatingSystems.MacOS },
- SiteUrl = "https://boriel-basic.net",
- LicenceUrl = "https://raw.githubusercontent.com/boriel-basic/zxbasic/refs/heads/main/LICENSE.txt",
- LicenseType = "GNU Affero General Public License v3.0",
- VersionsUrl = "https://boriel.com/files/zxb/",
- Order = 1
- };
- UpdateStatus?.Invoke(null, 15);
- tool.Versions = GetBorielBasicVersions(tool.VersionsUrl);
- lst.Add(tool);
- UpdateStatus?.Invoke(null, 20);
- }
-
- // ZXBasic Studio IDE
- {
- UpdateStatus?.Invoke(null, 20);
- var tool = new ExternalTool()
- {
- Id = "zxbs",
- Enabled = true,
- Name = "ZX Basic Studio",
- Author = "Dr.Gusman, Boriel, Duefectu, AdolFITO, Hash6Iron and SirRickster",
- Description = "IDE (Integrated Development Environment) with Boriel Basic code editor, Assembler, UDGs, fonts, sprites, .tap editor, debugger, emulator, etc. This tool is optional but highly recommended.",
- DirectUpdate = true,
- SupportedOperatingSystems = new OperatingSystems[] { OperatingSystems.Windows, OperatingSystems.Linux, OperatingSystems.MacOS },
- SiteUrl = "https://github.com/boriel-basic/ZXBasicStudio",
- LicenceUrl = "https://raw.githubusercontent.com/boriel-basic/ZXBasicStudio/refs/heads/master/LICENSE.txt",
- LicenseType = "MIT License",
- VersionsUrl = "https://github.com/boriel-basic/ZXBasicStudio/releases/",
- Order=2
- };
- UpdateStatus?.Invoke(null, 25);
- // Versions
- var versions = new List();
- versions.Add(new ExternalTools_Version()
- {
- Version = "1.6.0-beta5",
- BetaNumber = 5,
- VersionNumber = 1006005,
- DownloadUrl = "https://github.com/boriel-basic/ZXBasicStudio/releases/download/v1.6/ZXBasicStudio-linux-x64.v1.6.0-beta5.zip",
- OperatingSystem = OperatingSystems.Linux,
- });
- versions.Add(new ExternalTools_Version()
- {
- Version = "1.6.0-beta5",
- BetaNumber = 5,
- VersionNumber = 1006005,
- DownloadUrl = "https://github.com/boriel-basic/ZXBasicStudio/releases/download/v1.6/ZXBasicStudio-osx-x64.v1.6.0-beta5.zip",
- OperatingSystem = OperatingSystems.MacOS,
- });
- versions.Add(new ExternalTools_Version()
- {
- Version = "1.6.0-beta5",
- BetaNumber = 5,
- VersionNumber = 1006005,
- DownloadUrl = "https://github.com/boriel-basic/ZXBasicStudio/releases/download/v1.6/ZXBasicStudio-win-x64.v1.6.0-beta5.zip",
- OperatingSystem = OperatingSystems.Windows,
- });
- tool.Versions = versions.ToArray();
- lst.Add(tool);
- UpdateStatus?.Invoke(null, 30);
- }
- // Get tools paths from ZXBS config file
- GetPaths(ref lst);
-
-
- // ZXBasic Studio Installer
- {
- UpdateStatus?.Invoke(null, 30);
- var tool = new ExternalTool()
- {
- Id = "zxbsinstaller",
- Enabled = true,
- Name = "ZX Basic Studio Installer",
- Author = "Duefectu",
- Description = "This program, and it is used to download, install and keep all external tools and ZX Basic Studio itself up to date.",
- DirectUpdate = true,
- SupportedOperatingSystems = new OperatingSystems[] { OperatingSystems.Windows, OperatingSystems.Linux, OperatingSystems.MacOS },
- SiteUrl = "https://github.com/boriel-basic/ZXBasicStudio",
- LicenceUrl = "https://raw.githubusercontent.com/boriel-basic/ZXBasicStudio/refs/heads/master/LICENSE.txt",
- LicenseType = "MIT License",
- VersionsUrl = "https://github.com/boriel-basic/ZXBasicStudio/releases/",
- Order = 0
- };
- UpdateStatus?.Invoke(null, 35);
- // Versions
- var versions = new List();
- versions.Add(new ExternalTools_Version()
- {
- Version = "0.0.1-beta1",
- BetaNumber = 1,
- VersionNumber = 1001,
- DownloadUrl = "https://github.com/boriel-basic/ZXBasicStudio/releases/download/v1.6/ZXBasicStudio-linux-x64.v1.6.0-beta5.zip",
- OperatingSystem = OperatingSystems.Linux,
- });
- versions.Add(new ExternalTools_Version()
- {
- Version = "0.0.1-beta1",
- BetaNumber = 1,
- VersionNumber = 1001,
- DownloadUrl = "https://github.com/boriel-basic/ZXBasicStudio/releases/download/v1.6/ZXBasicStudio-osx-x64.v1.6.0-beta5.zip",
- OperatingSystem = OperatingSystems.MacOS,
- });
- versions.Add(new ExternalTools_Version()
- {
- Version = "0.0.1-beta1",
- BetaNumber = 1,
- VersionNumber = 1001,
- DownloadUrl = "https://github.com/boriel-basic/ZXBasicStudio/releases/download/v1.6/ZXBasicStudio-win-x64.v1.6.0-beta5.zip",
- OperatingSystem = OperatingSystems.Windows,
- });
- tool.Versions = versions.ToArray();
- lst.Add(tool);
- UpdateStatus?.Invoke(null, 40);
- }
- // Get tools paths from ZXBS config file
- GetPaths(ref lst);
-
- externalTools = lst.OrderBy(d=>d.Order).ToArray();
-
- var test=JsonSerializer.Serialize(externalTools);
- File.WriteAllText(@"c:\temp\zxbsinstaller.json",test);
-
- return externalTools;
-#endif
}
-
- public static void GetPaths(ref ExternalTool[] tools)
+ ///
+ /// Get version numeric value and beta value from version string.
+ /// Four values are used, the last one identifying the beta version number. If it is 0, it is the stable version.
+ /// 1.2.3.0 = version 1.2.3 stable
+ /// 1.2.3.4 = version 1.2.3 beta 4
+ /// Values are multiplied by 1000 to get a single integer value that can be compared easily. For example:
+ /// 1.2.3.0 = 1*1000*1000*1000 + 2*1000*1000 + 3*1000 + 0 = 1002003000
+ /// 1.2.3.4 = 1*1000*1000*1000 + 2*1000*1000 + 3*1000 + 4 = 1002003004
+ ///
+ /// Version string
+ /// Item1 = version number, Item2 = beta number
+ private static (int, int) GetVersionNumber(string versionString)
{
- var filePath = Path.Combine(Environment.GetFolderPath(SpecialFolder.ApplicationData), "ZXBasicStudio", "ZXBasicStudioOptions.json");
- if (!File.Exists(filePath))
- {
- return;
- }
- var jsonString = File.ReadAllText(filePath);
- using JsonDocument doc = JsonDocument.Parse(jsonString);
- JsonElement root = doc.RootElement;
-
- UpdatePath("zxbasic", "ZxbcPath", root, ref tools);
- // ZX Basic Studio
+ try
{
- var tool = tools.FirstOrDefault(t => t.Id == "zxbs");
- if (tool != null)
- {
- tool.LocalPath = Directory.GetCurrentDirectory();
+ int number = 0;
+ int betaNumber = 0;
+ string version = versionString;
+ // If it is a beta version, replace the -beta with . and add the beta number as the fourth value.
+ if (version.Contains("-beta"))
+ {
+ var mv = Regex.Match(version, @"beta(\d+)(?:[-\.]|$)", RegexOptions.IgnoreCase);
+ if (mv.Success)
+ {
+ version = version.Replace("-beta", ".");
+ }
}
- }
- // ZX Basic Studio Installer
- {
- var tool = tools.FirstOrDefault(t => t.Id == "zxbsinstaller");
- if (tool != null)
+ else
{
- tool.LocalPath = Directory.GetCurrentDirectory();
+ version += ".0";
}
- }
- }
-
-
- private static void UpdatePath(string toolId, string property, JsonElement root, ref ExternalTool[] tools)
- {
- var tool = tools.FirstOrDefault(t => t.Id == toolId);
- if (tool == null)
- {
- return;
- }
- if (root.TryGetProperty(property, out JsonElement element))
- {
- string value = element.GetString();
- tool.FullLocalPath = value;
- var fn = Path.GetFileName(value);
- value = value.Replace(fn, "");
- tool.LocalPath = value;
- }
- }
-
- private static (int, int) GetVersionNumber(string versionString)
- {
- int number = 0;
- int betaNumber = 0;
- string version = versionString;
- if (version.Contains("-beta"))
- {
- var mv = Regex.Match(version, @"beta(\d+)(?:[-\.]|$)", RegexOptions.IgnoreCase);
- if (mv.Success)
+ // Split version string
+ var versionParts = version.Split(".");
+ if (versionParts.Length == 5)
{
- version = version.Replace("-beta", ".");
+ versionParts[3] += versionParts[4];
}
- }
- else
- {
- version += ".0";
- }
-
- var versionParts = version.Split(".");
- if (versionParts.Length == 5)
- {
- versionParts[3] += versionParts[4];
- }
- for (int n = 0; n < 4; n++)
- {
- number *= 1000;
- if (n < versionParts.Length)
+ // Get value for each part of the version string
+ for (int n = 0; n < 4; n++)
{
- int v = ToInteger(versionParts[n]);
- if (n == 3)
+ number *= 1000;
+ if (n < versionParts.Length)
{
- betaNumber = v;
- if (betaNumber == 0)
+ int v = ToInteger(versionParts[n]);
+ if (n == 3)
{
- number += 999;
+ betaNumber = v;
+ if (betaNumber == 0)
+ {
+ number += 999;
+ }
+ else
+ {
+ number += betaNumber;
+ }
}
else
{
- number += betaNumber;
+ number += v;
}
}
- else
- {
- number += v;
- }
}
+ return (number, betaNumber);
+ }
+ catch (Exception ex)
+ {
+ ShowMessage($"Error parsing version number.\r\n{ex.Message}{ex.StackTrace}");
+ return (0, 0);
}
- return (number, betaNumber);
}
#endregion
@@ -548,21 +498,39 @@ private static (int, int) GetVersionNumber(string versionString)
#region External tools versions retrieval
+ ///
+ /// Get the versions available for the specified tool.
+ /// The versions are retrieved from the tool's VersionsUrl property, which is configured in the external tools list.
+ /// The method parses the HTML of the VersionsUrl page to extract the available versions and their download URLs.
+ /// The parsing is specific for each tool, depending on how the versions are listed in the page.
+ /// The method returns an array of ExternalTools_Version objects that contain the version information, such as version number, beta number, download URL and operating system.
+ /// If there is an error retrieving or parsing the versions, it returns null and shows an error message to the user.
+ ///
+ ///
+ ///
private static ExternalTools_Version[] GetAvailableToolVersion(ExternalTool tool)
{
- switch (tool.Id)
+ try
{
- case "zxbasic":
- return GetBorielBasicVersions(tool.VersionsUrl);
+ switch (tool.Id)
+ {
+ case "zxbasic":
+ return GetBorielBasicVersions(tool.VersionsUrl);
- case "zxbs":
- return GetBorielZXBSVersions(tool.VersionsUrl, false);
+ case "zxbs":
+ return GetBorielZXBSVersions(tool.VersionsUrl, false);
- case "zxbsinstaller":
- return GetBorielZXBSVersions(tool.VersionsUrl, true);
+ case "zxbsinstaller":
+ return GetBorielZXBSVersions(tool.VersionsUrl, true);
- default:
- return null;
+ default:
+ return null;
+ }
+ }
+ catch (Exception ex)
+ {
+ ShowMessage($"Error getting available versions.\r\n{ex.Message}{ex.StackTrace}");
+ return null;
}
}
@@ -570,14 +538,20 @@ private static ExternalTools_Version[] GetAvailableToolVersion(ExternalTool tool
///
/// Get versions data for Boriel Basic Compiler
///
- ///
- ///
+ /// Repository URL
+ /// Array of versions
private static ExternalTools_Version[] GetBorielBasicVersions(string versionsUrl)
{
try
{
+ // Get all hrefs in the page according to the pattern.
+ // The pattern is specific for the Boriel Basic repository page, which contains links to the versions in the format zxbasic-v1.2.3-win.zip
var links = GetAllLinks(versionsUrl, @"]*href\s*=\s*[""']([^""']+)[""']");
-
+ if (links == null)
+ {
+ ShowMessage("The Boriel Basic repository could not be accessed. Please check your internet connection or try again later.");
+ return null;
+ }
// Parse links extracting versions data
var lst = new List();
Regex _regex = new Regex(
@@ -628,6 +602,7 @@ private static ExternalTools_Version[] GetBorielBasicVersions(string versionsUrl
}
catch (Exception ex)
{
+ ShowMessage($"Error retrieving Boriel Basic versions.\r\n{ex.Message}{ex.StackTrace}");
return null;
}
}
@@ -636,23 +611,43 @@ private static ExternalTools_Version[] GetBorielBasicVersions(string versionsUrl
///
/// Get versions data for ZX Basic Studio Compiler
///
- ///
- ///
+ /// Repository URL
+ /// True to get installer versions or false to get ZXBS versions
+ /// Array of versions
private static ExternalTools_Version[] GetBorielZXBSVersions(string versionsUrl, bool installer)
{
try
{
// Get all hrefs
var links = GetAllLinks(versionsUrl, @"href=""([^""]+)""");
+ if (links == null)
+ {
+ ShowMessage("The ZX Basic Studio repository could not be accessed. Please check your internet connection or try again later.");
+ return null;
+ }
+
// Get only releases
links = links.Where(d => d.Contains("/boriel-basic/ZXBasicStudio/releases/tag/")).ToArray();
+ // Process all links
var versions = new List();
foreach (var link in links)
{
var url = link.Replace("/boriel-basic/ZXBasicStudio/releases/tag/", "");
url = $"https://github.com/boriel-basic/ZXBasicStudio/releases/expanded_assets/{url}";
var filesLinks = GetAllLinks(url, @"href=""([^""]+)""");
+ if (filesLinks == null)
+ {
+ if (installer)
+ {
+ ShowMessage("The ZXBSInstaller repository could not be accessed. Please check your internet connection or try again later.");
+ }
+ else
+ {
+ ShowMessage("The ZX Basic Studio repository could not be accessed. Please check your internet connection or try again later.");
+ }
+ return null;
+ }
foreach (var fl in filesLinks)
{
if (fl.Contains("download"))
@@ -683,11 +678,17 @@ private static ExternalTools_Version[] GetBorielZXBSVersions(string versionsUrl,
}
catch (Exception ex)
{
+ ShowMessage($"Error retrieving ZXBS/Installer versions.\r\n{ex.Message}{ex.StackTrace}");
return null;
}
}
+ ///
+ /// Get version based on the link for ZXBS and ZXBSInstaller.
+ ///
+ /// Link of the version
+ /// Version info
private static ExternalTools_Version GetGitHubZXBSVersion(string fileLink)
{
try
@@ -747,42 +748,75 @@ private static ExternalTools_Version GetGitHubZXBSVersion(string fileLink)
}
catch (Exception ex)
{
+ ShowMessage($"Error parsing ZXBS version.\r\n{ex.Message}{ex.StackTrace}");
return null;
}
}
+ ///
+ /// Get all links of an url based on a regex pattern.
+ /// It is used to parse the HTML of the versions page of the tools to extract the links of the versions.
+ /// The pattern is specific for each tool, depending on how the versions are listed in the page.
+ ///
+ /// Url to retrive
+ /// Regex patter for the urls
+ /// Array of links in string format
private static string[] GetAllLinks(string url, string pattern)
{
- // Get html file
- string html;
- var handler = new HttpClientHandler
- {
- AllowAutoRedirect = true
- };
- using (HttpClient client = new HttpClient(handler))
+ try
{
- html = client.GetStringAsync(url).GetAwaiter().GetResult();
+ // Get html file
+ string html = "";
+ var handler = new HttpClientHandler
+ {
+ AllowAutoRedirect = true
+ };
+ // Download page with retries in case of network errors or timeouts
+ int retries = 5;
+ while (retries-- > 0)
+ {
+ try
+ {
+ using (HttpClient client = new HttpClient(handler))
+ {
+ client.Timeout = TimeSpan.FromSeconds(20);
+ html = client.GetStringAsync(url).GetAwaiter().GetResult();
+ }
+ }
+ catch { }
+ if (!string.IsNullOrEmpty(html))
+ {
+ break;
+ }
+ Thread.Sleep(1000);
+ }
+ if (string.IsNullOrEmpty(html))
+ {
+ return null;
+ }
+
+ // Get links
+ var links = new List();
+ {
+ var regex = new Regex(
+ pattern,
+ RegexOptions.IgnoreCase);
+ var matches = regex.Matches(html);
+ foreach (Match match in matches)
+ {
+ links.Add(match.Groups[1].Value);
+ }
+ }
+
+ return links.ToArray();
}
- if (string.IsNullOrEmpty(html))
+ catch (Exception ex)
{
+ ShowMessage($"Error getting links.\r\n{ex.Message}{ex.StackTrace}");
return null;
}
- //File.WriteAllText("c:/temp/html.text", html);
- // Get links
- var links = new List();
- {
- var regex = new Regex(
- pattern,
- RegexOptions.IgnoreCase);
- var matches = regex.Matches(html);
- foreach (Match match in matches)
- {
- links.Add(match.Groups[1].Value);
- }
- }
- return links.ToArray();
}
#endregion
@@ -790,6 +824,11 @@ private static string[] GetAllLinks(string url, string pattern)
#region Local tools versions
+ ///
+ /// Get local version of one external tool
+ ///
+ /// Tool id
+ /// Installed version
public static ExternalTools_Version GetToolVersion(string id)
{
try
@@ -805,29 +844,119 @@ public static ExternalTools_Version GetToolVersion(string id)
case "zxbsinstaller":
return GetZXBSInstallerVersion(dir);
}
- return null;
}
catch (Exception ex)
{
- return null;
+ ShowMessage($"Error retrieving local version for {id}.\r\n{ex.Message}{ex.StackTrace}");
}
+ return null;
}
+ ///
+ /// Get installed Boriel ZX Basic Compiler version
+ ///
+ /// Path of the tool
+ /// Version info
private static ExternalTools_Version GetBorielBasicVersion(string exePath)
{
try
{
+ // Windows fileName
var fileName = Path.Combine(exePath, "zxbc.exe");
if (!File.Exists(fileName))
{
- fileName = Path.Combine(exePath, "zxbc");
+ // If not exist, try Linux/Mac fileName
+ fileName = Path.Combine(exePath, "zxbc.py");
}
if (!File.Exists(fileName))
{
+ // Not found
return null;
}
- // Launch "zxbc.exe --version"
+ // Retrieve version executing with --version parameter
+ return GetVersionFromParameter(fileName);
+ }
+ catch (Exception ex)
+ {
+ ShowMessage($"Error getting local Boriel Basic version.\r\n{ex.Message}{ex.StackTrace}");
+ return null;
+ }
+ }
+
+
+ ///
+ /// Get intalled ZX Basic Studio version.
+ /// The version is stored in version.txt file in ZXBS folder
+ ///
+ /// ZXBS path
+ /// Version info
+ private static ExternalTools_Version GetZXBSVersion(string exePath)
+ {
+ try
+ {
+ var fileName = Path.Combine(exePath, "version.txt");
+ if (!File.Exists(fileName))
+ {
+ // no version.txt file
+ if (File.Exists(Path.Combine(exePath, "ZXBasicStudio.exe"))
+ || File.Exists(Path.Combine(exePath, "ZXBasicStudio")))
+ {
+ // return "OLD version"
+ return new ExternalTools_Version()
+ {
+ DownloadUrl = "",
+ BetaNumber = 0,
+ OperatingSystem = OperatingSystems.All,
+ Version = "OLD version",
+ VersionNumber = 0
+ };
+ }
+ return null;
+ }
+ // Read version from file
+ var txt = File.ReadAllText(fileName);
+ var v = GetVersionNumber(txt);
+
+ // Is an stable version (ends with .0)
+ var parts = txt.Split(".");
+ if (parts.Length == 4 && parts[3] == "0")
+ {
+ txt = $"{parts[0]}.{parts[1]}.{parts[2]}";
+ }
+
+ var version = new ExternalTools_Version()
+ {
+ DownloadUrl = "",
+ BetaNumber = v.Item2,
+ OperatingSystem = OperatingSystems.All,
+ Version = txt,
+ VersionNumber = v.Item1
+ };
+ return version;
+ }
+ catch (Exception ex)
+ {
+ ShowMessage($"Error getting local ZXBS version.\r\n{ex.Message}{ex.StackTrace}");
+ return null;
+ }
+ }
+
+
+ ///
+ /// Get version from file using --version parameter
+ ///
+ /// Executable filename
+ /// ExternalTools_Version with the version info
+ private static ExternalTools_Version GetVersionFromParameter(string fileName)
+ {
+ try
+ {
+ if (!File.Exists(fileName))
+ {
+ return null;
+ }
+
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = fileName,
@@ -863,63 +992,22 @@ private static ExternalTools_Version GetBorielBasicVersion(string exePath)
}
catch (Exception ex)
{
+ ShowMessage($"Error getting local Boriel Basic version.\r\n{ex.Message}{ex.StackTrace}");
return null;
}
}
- private static ExternalTools_Version GetZXBSVersion(string exePath)
- {
- try
- {
- var fileName = Path.Combine(exePath, "ZXBasicStudio.exe");
- if (!File.Exists(fileName))
- {
- fileName = Path.Combine(exePath, "ZXBasicStudio");
- }
- if (!File.Exists(fileName))
- {
- return null;
- }
-
- var fvi = FileVersionInfo.GetVersionInfo(fileName);
- if (fvi != null)
- {
- // Major, minor, Build, private
- var version = $"{fvi.ProductMajorPart}.{fvi.ProductMinorPart}.{fvi.ProductBuildPart}";
- if (fvi.ProductPrivatePart > 0)
- {
- version += $"-beta{fvi.ProductPrivatePart}";
- }
- if (version == "1.0.0")
- {
- version = "1.6.0-beta6.3";
- }
- var v = GetVersionNumber(version);
- var versionNumber = v.Item1;
- var beta = v.Item2;
- return new ExternalTools_Version()
- {
- DownloadUrl = "",
- BetaNumber = beta,
- OperatingSystem = OperatingSystems.All,
- Version = version,
- VersionNumber = versionNumber
- };
- }
- return null;
- }
- catch (Exception ex)
- {
- return null;
- }
- }
-
-
+ ///
+ /// Gewt own version
+ ///
+ /// Not needed
+ /// Version info
public static ExternalTools_Version GetZXBSInstallerVersion(string exePath)
{
try
{
+ // Get assembly version
var assemblyVersion = Assembly.GetEntryAssembly()?.GetName().Version?.ToString();
var parts = assemblyVersion.Split('.');
if (parts.Length < 4)
@@ -928,6 +1016,7 @@ public static ExternalTools_Version GetZXBSInstallerVersion(string exePath)
}
;
var version = $"{parts[0]}.{parts[1]}.{parts[2]}";
+ // It's a beta?
var beta = ToInteger(parts[3]);
if (beta > 0)
{
@@ -945,6 +1034,7 @@ public static ExternalTools_Version GetZXBSInstallerVersion(string exePath)
}
catch (Exception ex)
{
+ ShowMessage($"Error getting local ZXBSInstaller version.\r\n{ex.Message}{ex.StackTrace}");
return null;
}
}
@@ -954,26 +1044,56 @@ public static ExternalTools_Version GetZXBSInstallerVersion(string exePath)
#region Install external tool
+ ///
+ /// Download and install al selected tools
+ ///
public static void DownloadAndInstallTools()
{
- ShowStatusPanel($"Working...");
- foreach (var tool in ExternalTools)
+ try
{
- if (tool.IsSelected)
+ ShowStatusPanel($"Working...");
+ foreach (var tool in ExternalTools)
{
- DownloadAndInstallTool(tool, tool.LatestVersion);
+ if (Cancel)
+ {
+ break;
+ }
+ if (tool.IsSelected)
+ {
+ DownloadAndInstallTool(tool, tool.LatestVersion);
+ }
}
+ HideStatusPanel();
+ RefreshTools();
+ }
+ catch (Exception ex)
+ {
+ ShowMessage($"Error installing.\r\n{ex.Message}{ex.StackTrace}");
}
- HideStatusPanel();
- RefreshTools();
}
+ ///
+ /// Download and install one tool
+ ///
+ /// Tool to install
+ /// Version info to install
public static void DownloadAndInstallTool(ExternalTool tool, ExternalTools_Version version)
{
+ // For debug
string step = "";
try
{
+ if (tool == null || version == null)
+ {
+ return;
+ }
+
+ if(tool.Id == "zxbsinstaller")
+ {
+ ShowStatusPanel($"After installing or updating ZXBSInstaller, run this program from {tool.LocalPath}.");
+ }
+
ShowStatusPanel($"Downloading {tool.Name} version {version.Version}...");
// Download path
@@ -1048,6 +1168,13 @@ public static void DownloadAndInstallTool(ExternalTool tool, ExternalTools_Versi
}
+ ///
+ /// Install ZXBSInstaller...
+ /// Generate a batch/bash file to expand .zip, decompress and launch ZXBSInstaller
+ ///
+ /// Tool info for ZXBSInstaller
+ /// Local path of the downloaded .zip file with the new version of ZXBSInstaller
+ /// Installation destination path
private static void InstallInstaller(ExternalTool tool, string tempFile, string installationPath)
{
try
@@ -1057,6 +1184,7 @@ private static void InstallInstaller(ExternalTool tool, string tempFile, string
string bashFile = "";
if (CurrentOperatingSystem == OperatingSystems.Windows)
{
+ // Windows
bashFile = Path.Combine(GeneralConfig.BasePath, "downloads", "zxbsinstall.bat");
bash = @"
@echo off
@@ -1070,40 +1198,71 @@ echo on
}
else
{
+ // Linux and Mac
bashFile = Path.Combine(GeneralConfig.BasePath, "downloads", "zxbsinstall.sh");
bash = @"
-#!/bin/bash
+# !/bin/bash
+set -e
echo ""Updating installer...""
sleep 5
-set -x
-tar -xf ""{tempFile}"" -C ""{installationPath}""
-rm -f ""{tempFile}""
-cd ""{installationPath}"" || exit 1
-
-# Ejecutar sin esperar (en segundo plano)
-./ZXBSInstaller.exe &";
+ZIP_FILE=""{tempFile}""
+DEST_DIR=""{installationPath}""
+
+extract_zip() {
+ if command -v unzip >/dev/null 2>&1; then
+ echo ""Using unzip...""
+ unzip -o ""$ZIP_FILE"" -d ""$DEST_DIR""
+ elif command -v tar >/dev/null 2>&1; then
+ echo ""Using tar...""
+ tar -xf ""$ZIP_FILE"" -C ""$DEST_DIR""
+ else
+ echo ""Error: Neither unzip nor tar is installed.""
+ exit 1
+ fi
+}
+
+extract_zip
+
+rm -f ""$ZIP_FILE""
+cd ""$DEST_DIR"" || exit 1
+
+# Ejecutar sin esperar
+./ZXBSInstaller &
+";
}
bash = bash.Replace("{tempFile}", tempFile).Replace("{installationPath}", installationPath);
File.WriteAllText(bashFile, bash);
- // Set execute attr in Linux/Mac
if (CurrentOperatingSystem != OperatingSystems.Windows)
{
- var process = new Process();
- process.StartInfo.FileName = "chmod";
- process.StartInfo.ArgumentList.Add("+x");
- process.StartInfo.ArgumentList.Add(bashFile);
- process.StartInfo.RedirectStandardOutput = true;
- process.StartInfo.RedirectStandardError = true;
- process.StartInfo.UseShellExecute = false;
- process.Start();
- process.WaitForExit();
+ // Set execute attr in Linux/Mac
+ {
+ var process = new Process();
+ process.StartInfo.FileName = "chmod";
+ process.StartInfo.ArgumentList.Add("+x");
+ process.StartInfo.ArgumentList.Add(bashFile);
+ process.StartInfo.RedirectStandardOutput = true;
+ process.StartInfo.RedirectStandardError = true;
+ process.StartInfo.UseShellExecute = false;
+ process.Start();
+ process.WaitForExit();
+ }
+ // Launch .sh file
+ ProcessStartInfo psi = new ProcessStartInfo
+ {
+ FileName = "bash",
+ Arguments = bashFile,
+ WorkingDirectory = Path.Combine(GeneralConfig.BasePath, "downloads"),
+ UseShellExecute = true,
+ };
+ var p = new Process { StartInfo = psi };
+ p.Start();
}
-
- // Run batch/bash file
+ else
{
+ // Launch .bat file
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = bashFile,
@@ -1126,49 +1285,68 @@ sleep 5
}
+ ///
+ /// Extract file
+ ///
+ /// Path of the .zip file
+ /// Destination folder
private static void ExtractFile(string archive, string destination)
{
- if (archive.ToLower().EndsWith(".zip"))
- {
- System.IO.Compression.ZipFile.ExtractToDirectory(archive, destination, true);
- }
- else if (CurrentOperatingSystem != OperatingSystems.Windows)
+ try
{
- Directory.CreateDirectory(destination);
-
- var psi = new ProcessStartInfo
+ if (archive.ToLower().EndsWith(".zip"))
{
- FileName = "tar",
- Arguments = $"-xzf \"{archive}\" -C \"{destination}\"",
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- UseShellExecute = false,
- CreateNoWindow = true
- };
+ // Extract .zip file
+ System.IO.Compression.ZipFile.ExtractToDirectory(archive, destination, true);
+ }
+ else if (CurrentOperatingSystem != OperatingSystems.Windows)
+ {
+ // Extract .tar file on Linux and Mac
+ Directory.CreateDirectory(destination);
- using var process = Process.Start(psi)!;
+ var psi = new ProcessStartInfo
+ {
+ FileName = "tar",
+ Arguments = $"-xzf \"{archive}\" -C \"{destination}\"",
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
- string stdout = process.StandardOutput.ReadToEnd();
- string stderr = process.StandardError.ReadToEnd();
+ using var process = Process.Start(psi)!;
- process.WaitForExit();
+ string stdout = process.StandardOutput.ReadToEnd();
+ string stderr = process.StandardError.ReadToEnd();
- if (process.ExitCode != 0)
- {
- ShowMessage($"Error unpacking file {archive}\r\n{stderr}");
- return;
+ process.WaitForExit();
+
+ if (process.ExitCode != 0)
+ {
+ ShowMessage($"Error unpacking file {archive}\r\n{stderr}");
+ return;
+ }
}
}
+ catch (Exception ex)
+ {
+ ShowMessage($"Error unpacking file {archive} on {destination}.\r\n{ex.Message}{ex.StackTrace}");
+ }
}
+ ///
+ /// Update ZX Basic Studio config with the tools path for "zxbc" and "zxbasm"
+ ///
private static void SetZXBSConfig()
{
try
{
+ // Build path for ZX Basic Studio configuration file
var filePath = Path.Combine(Environment.GetFolderPath(SpecialFolder.ApplicationData), "ZXBasicStudio", "ZXBasicStudioOptions.json");
if (!File.Exists(filePath))
{
+ // Create a default config if not exists
string data = @"{
""ZxbasmPath"": """",
""ZxbcPath"": """",
@@ -1186,10 +1364,12 @@ private static void SetZXBSConfig()
File.WriteAllText(filePath, data);
}
+ // Open config file
var sb = new StringBuilder();
var sr = new StreamReader(filePath);
while (!sr.EndOfStream)
{
+ // Read one line
var line = sr.ReadLine();
// Set values
if (line.Contains("ZxbasmPath"))
@@ -1220,7 +1400,7 @@ private static void SetZXBSConfig()
}
catch (Exception ex)
{
- //ShowMessage($"Error updating ZX Basic Studio options.\r\n{ex.Message}\r\n{ex.StackTrace}");
+ ShowMessage($"Error updating ZX Basic Studio options.\r\n{ex.Message}\r\n{ex.StackTrace}");
}
}
@@ -1228,6 +1408,10 @@ private static void SetZXBSConfig()
#endregion
+ ///
+ /// Launch ZX Basic Studio
+ ///
+ /// True if correct or false if error
public static bool RunZXBasicStudio()
{
try
@@ -1252,10 +1436,9 @@ public static bool RunZXBasicStudio()
}
catch (Exception ex)
{
- ServiceLayer.ShowMessage("Error launching ZX Basic Studio. Please check the installation.");
+ ServiceLayer.ShowMessage($"Error launching ZX Basic Studio. Please check the installation.\r\n{ex.Message}{ex.StackTrace}");
return false;
}
}
-
}
}
\ No newline at end of file
diff --git a/ZXBSInstaller/App.axaml.cs b/ZXBSInstaller/App.axaml.cs
index 022a205..97f2c25 100644
--- a/ZXBSInstaller/App.axaml.cs
+++ b/ZXBSInstaller/App.axaml.cs
@@ -1,4 +1,5 @@
using Avalonia;
+using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
@@ -15,6 +16,7 @@ public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
+ desktop.ShutdownMode = ShutdownMode.OnMainWindowClose;
desktop.MainWindow = new MainWindow();
}
diff --git a/ZXBSInstaller/Assets/cancel.svg b/ZXBSInstaller/Assets/cancel.svg
new file mode 100644
index 0000000..eb114de
--- /dev/null
+++ b/ZXBSInstaller/Assets/cancel.svg
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/ZXBSInstaller/Assets/history.svg b/ZXBSInstaller/Assets/history.svg
new file mode 100644
index 0000000..11c4484
--- /dev/null
+++ b/ZXBSInstaller/Assets/history.svg
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/ZXBSInstaller/Assets/internet.svg b/ZXBSInstaller/Assets/internet.svg
new file mode 100644
index 0000000..e25dda7
--- /dev/null
+++ b/ZXBSInstaller/Assets/internet.svg
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/ZXBSInstaller/Controls/MainControl.axaml b/ZXBSInstaller/Controls/MainControl.axaml
index c31b41e..765e229 100644
--- a/ZXBSInstaller/Controls/MainControl.axaml
+++ b/ZXBSInstaller/Controls/MainControl.axaml
@@ -33,7 +33,7 @@
-
+
@@ -49,7 +49,7 @@
@@ -69,14 +69,36 @@
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ZXBSInstaller/Controls/MainControl.axaml.cs b/ZXBSInstaller/Controls/MainControl.axaml.cs
index 2cd52f0..87c1805 100644
--- a/ZXBSInstaller/Controls/MainControl.axaml.cs
+++ b/ZXBSInstaller/Controls/MainControl.axaml.cs
@@ -6,9 +6,6 @@
using Avalonia.Media;
using Avalonia.Threading;
using Avalonia.VisualTree;
-using MsBox.Avalonia;
-using MsBox.Avalonia.Dto;
-using MsBox.Avalonia.Enums;
using System;
using System.Collections.Generic;
using System.Data;
@@ -21,31 +18,56 @@
namespace ZXBSInstaller.Controls;
+///
+/// Main window
+///
public partial class MainControl : UserControl
{
+ ///
+ /// List of ToolItemControl created items
+ ///
private List toolItemControls = new List();
+ ///
+ /// Yellow color for labels
+ ///
private static Brush Yellow = new SolidColorBrush(Colors.Yellow);
+
+ ///
+ /// Main constructor
+ ///
public MainControl()
{
InitializeComponent();
+ // Set events
this.Loaded += MainControl_Loaded;
txtBasePath.TextChanged += TxtBasePath_TextChanged;
chkOnlyStableVersions.IsCheckedChanged += ChkOnlyStableVersions_IsCheckedChanged;
chkSetZXBSOptions.IsCheckedChanged += ChkSetZXBSOptions_IsCheckedChanged;
}
+
+ ///
+ /// Initialize in a new Thread when loaded
+ ///
+ ///
+ ///
private void MainControl_Loaded(object? sender, RoutedEventArgs e)
{
new Thread(Initialize).Start();
}
+ ///
+ /// Initialize
+ ///
private void Initialize()
{
+ // Initialize ServiceLayer
ServiceLayer.Initialize(ShowStatusPanel, UpdateStatus, HideStatusPanel, GetExternalTools, ShowMessage, ExitApp);
+ // Set config fields in UIThread
Dispatcher.UIThread.Post(() =>
{
txtBasePath.Text = ServiceLayer.GeneralConfig.BasePath;
@@ -53,84 +75,86 @@ private void Initialize()
chkSetZXBSOptions.IsChecked = ServiceLayer.GeneralConfig.SetZXBSConfig;
});
+ // Get external tools list
GetExternalTools();
}
+ ///
+ /// Show a message into a dialog box
+ ///
+ /// Message to display
private void ShowMessage(string message)
{
Dispatcher.UIThread.Post(() =>
{
- pnlStatus.IsVisible = false;
- var box = MessageBoxManager.GetMessageBoxStandard(new MessageBoxStandardParams
- {
- ButtonDefinitions = ButtonEnum.Ok,
- ContentTitle = "ZX Basic Studio Installer",
- ContentMessage = message,
- Icon = MsBox.Avalonia.Enums.Icon.Info,
- WindowIcon = ((Window)this.VisualRoot).Icon,
- WindowStartupLocation = WindowStartupLocation.CenterOwner
- });
- box.ShowAsPopupAsync(this);
+ HideStatusPanel();
+ txtModalMessage.Text = message;
+ pnlModal.IsVisible = true;
});
}
+ ///
+ /// Get list of external tools and local versions
+ ///
private void GetExternalTools()
{
+ // Set UI...
Dispatcher.UIThread.Post(() =>
{
mainVersions.IsVisible = false;
mainTools.IsVisible = true;
-
- txtStatus.Text = "Working...";
- progressBar.Value = 0;
- pnlStatus.IsVisible = true;
+ ShowStatusPanel("Working...");
});
- var tools = ServiceLayer.GetExternalTools();
+ // Get tools
+ var json = UITools.GetTextResource("ExternalTools.json");
+ var tools = ServiceLayer.SetExternalTools(json);
- Dispatcher.UIThread.Post(() =>
+ HideStatusPanel();
+ if (tools == null)
{
- pnlStatus.IsVisible = false;
- if (tools == null)
- {
- var box = MessageBoxManager.GetMessageBoxStandard(new MessageBoxStandardParams
- {
- ButtonDefinitions = ButtonEnum.Ok,
- ContentTitle = "ERROR",
- ContentMessage = "Error retrieving the list of tools, please check your Internet connection.\r\nIt may be a temporary server error, report the error to duefectucorp@gmail.com and try again later.",
- Icon = MsBox.Avalonia.Enums.Icon.Error,
- WindowIcon = ((Window)this.VisualRoot).Icon,
- WindowStartupLocation = WindowStartupLocation.CenterOwner
- });
- box.ShowAsPopupAsync(this);
-
- }
- else
- {
- ShowData();
- }
- });
+ // No tools, no way!
+ ExitApp();
+ }
+ else
+ {
+ // Show tools
+ ShowData();
+ }
}
+ ///
+ /// Show tools info
+ ///
private void ShowData()
{
- toolItemControls.Clear();
- var tools = ServiceLayer.ExternalTools;
-
- pnlTools.Children.Clear();
- foreach (var tool in tools)
+ Dispatcher.UIThread.Post(() =>
{
- var control = new ToolItemControl(tool, Command_Received);
- toolItemControls.Add(control);
- pnlTools.Children.Add(control);
- }
- UpdateSummary();
+ toolItemControls.Clear();
+ var tools = ServiceLayer.ExternalTools;
+
+ pnlTools.Children.Clear();
+ foreach (var tool in tools)
+ {
+ // Create on ToolItemControl foreach tool
+ var control = new ToolItemControl(tool, Command_Received);
+ toolItemControls.Add(control);
+ pnlTools.Children.Add(control);
+ }
+ // Update summary area
+ UpdateSummary();
+ });
}
+ ///
+ /// Command received from sub-controls
+ ///
+ /// Tool id
+ /// Command
private void Command_Received(string id, string command)
{
switch (command)
@@ -148,6 +172,9 @@ private void Command_Received(string id, string command)
}
+ ///
+ /// Show Summary panel
+ ///
private void UpdateSummary()
{
Dispatcher.UIThread.Post(() =>
@@ -159,6 +186,7 @@ private void UpdateSummary()
{
if (tool.IsSelected)
{
+ // Data for selected tools
var tb = new TextBlock();
tb.TextWrapping = Avalonia.Media.TextWrapping.Wrap;
if (tool.ExternalTool.InstalledVersion == null)
@@ -175,6 +203,7 @@ private void UpdateSummary()
}
if (allUpToDate)
{
+ // Nothing to update
var tb = new TextBlock();
tb.TextWrapping = Avalonia.Media.TextWrapping.Wrap;
tb.Text = "All tools are up to date.";
@@ -190,7 +219,7 @@ private void UpdateSummary()
pnlSummary.Children.Add(separator);
}
- // Show tools tree
+ // Show base path
{
pnlSummary.Children.Add(new TextBlock()
{
@@ -200,9 +229,11 @@ private void UpdateSummary()
pnlSummary.Children.Add(new TextBlock()
{
Text = ServiceLayer.GeneralConfig.BasePath,
- Margin = new Thickness(10, 4, 0, 0)
+ Margin = new Thickness(10, 4, 0, 0),
+ TextWrapping = TextWrapping.Wrap
});
}
+ // Show tools installation paths
foreach (var tool in toolItemControls)
{
var tb = new TextBlock();
@@ -213,12 +244,14 @@ private void UpdateSummary()
{
Text = tool.ExternalTool.Name + ":",
Margin = new Thickness(0, 8, 0, 0),
- Foreground = Yellow
+ Foreground = Yellow,
+ TextWrapping = TextWrapping.Wrap
});
pnlSummary.Children.Add(new TextBlock()
{
Text = System.IO.Path.Combine(ServiceLayer.GeneralConfig.BasePath, tool.ExternalTool.Id),
- Margin = new Thickness(10, 4, 0, 0)
+ Margin = new Thickness(10, 4, 0, 0),
+ TextWrapping = TextWrapping.Wrap
});
}
}
@@ -226,22 +259,40 @@ private void UpdateSummary()
}
+ ///
+ /// Show status panel
+ ///
+ /// Message to display
private void ShowStatusPanel(string message)
{
Dispatcher.UIThread.Post(() =>
{
+ ServiceLayer.Cancel = false;
txtStatus.Text = message;
progressBar.Value = 0;
pnlStatus.IsVisible = true;
+
+ btnInstall.IsEnabled = false;
+ btnPlayZXBS.IsEnabled = false;
+ btnRefresh.IsEnabled = false;
+ btnSelectPath.IsEnabled = false;
});
}
+ ///
+ /// Hide status panel
+ ///
private void HideStatusPanel()
{
Dispatcher.UIThread.Post(() =>
{
pnlStatus.IsVisible = false;
+
+ btnInstall.IsEnabled = true;
+ btnPlayZXBS.IsEnabled = true;
+ btnRefresh.IsEnabled = true;
+ btnSelectPath.IsEnabled = true;
});
}
@@ -266,6 +317,12 @@ private void UpdateStatus(string message, int progress)
});
}
+
+ ///
+ /// Button select path
+ ///
+ ///
+ ///
private void btnSelectPath_Click(object? sender, RoutedEventArgs e)
{
var dlg = new OpenFolderDialog()
@@ -287,12 +344,23 @@ private void btnSelectPath_Click(object? sender, RoutedEventArgs e)
}
+
+ ///
+ /// Button install components
+ ///
+ ///
+ ///
private void btnInstall_Click(object? sender, RoutedEventArgs e)
{
new Thread(ServiceLayer.DownloadAndInstallTools).Start();
}
+ ///
+ /// chkSetZXBSOptions checked changed
+ ///
+ ///
+ ///
private void ChkSetZXBSOptions_IsCheckedChanged(object? sender, RoutedEventArgs e)
{
ServiceLayer.GeneralConfig.SetZXBSConfig = chkSetZXBSOptions.IsChecked == true;
@@ -300,6 +368,11 @@ private void ChkSetZXBSOptions_IsCheckedChanged(object? sender, RoutedEventArgs
}
+ ///
+ /// chkOnlyStableVersions checked changed
+ ///
+ ///
+ ///
private void ChkOnlyStableVersions_IsCheckedChanged(object? sender, RoutedEventArgs e)
{
ServiceLayer.GeneralConfig.OnlyStableVersions = chkOnlyStableVersions.IsChecked == true;
@@ -307,6 +380,11 @@ private void ChkOnlyStableVersions_IsCheckedChanged(object? sender, RoutedEventA
}
+ ///
+ /// Base path changed
+ ///
+ ///
+ ///
private void TxtBasePath_TextChanged(object? sender, TextChangedEventArgs e)
{
ServiceLayer.GeneralConfig.BasePath = txtBasePath.Text;
@@ -314,6 +392,10 @@ private void TxtBasePath_TextChanged(object? sender, TextChangedEventArgs e)
}
+ ///
+ /// Show version info for a tool
+ ///
+ /// Tool id
private void ShowVersions(string id)
{
Dispatcher.UIThread.Post(() =>
@@ -321,8 +403,10 @@ private void ShowVersions(string id)
mainTools.IsVisible = false;
mainVersions.IsVisible = true;
pnlVersions.Children.Clear();
+
var tool = ServiceLayer.ExternalTools.FirstOrDefault(d => d.Id == id);
+ // Close button
{
var btn = new Button()
{
@@ -334,10 +418,12 @@ private void ShowVersions(string id)
pnlVersions.Children.Add(btn);
}
+ // Header
var versionControlHeader = new VersionControl(null, null, Command_Received);
pnlVersions.Children.Add(versionControlHeader);
foreach (var version in tool.Versions)
{
+ // Version line
if (ServiceLayer.GeneralConfig.OnlyStableVersions && version.BetaNumber > 0)
{
continue;
@@ -346,6 +432,7 @@ private void ShowVersions(string id)
pnlVersions.Children.Add(versionControl);
}
+ // Anothe Close button at the bottom of the list
{
var btn = new Button()
{
@@ -361,6 +448,11 @@ private void ShowVersions(string id)
}
+ ///
+ /// Versions button
+ ///
+ ///
+ ///
private void Versions_Close(object? sender, RoutedEventArgs e)
{
Dispatcher.UIThread.Post(() =>
@@ -370,12 +462,22 @@ private void Versions_Close(object? sender, RoutedEventArgs e)
});
}
+
+ ///
+ /// Run ZXBS button
+ ///
+ ///
+ ///
private void btnPlayZXBS_Click(object? sender, RoutedEventArgs e)
{
+ ServiceLayer.RunZXBasicStudio();
ExitApp();
}
+ ///
+ /// Exit application
+ ///
private void ExitApp()
{
Dispatcher.UIThread.Post(() =>
@@ -389,8 +491,29 @@ private void ExitApp()
}
+ ///
+ /// Refresh button
+ ///
+ ///
+ ///
private void btnRefresh_Click(object? sender, RoutedEventArgs e)
{
new Thread(GetExternalTools).Start();
}
+
+
+ ///
+ /// Cacel button
+ ///
+ ///
+ ///
+ private void btnCancel_Click(object? sender, RoutedEventArgs e)
+ {
+ ServiceLayer.Cancel = true;
+ }
+
+ private void btnModalClose_Click(object? sender, RoutedEventArgs e)
+ {
+ pnlModal.IsVisible = false;
+ }
}
\ No newline at end of file
diff --git a/ZXBSInstaller/Controls/ToolItemControl.axaml b/ZXBSInstaller/Controls/ToolItemControl.axaml
index e7ca840..cc46644 100644
--- a/ZXBSInstaller/Controls/ToolItemControl.axaml
+++ b/ZXBSInstaller/Controls/ToolItemControl.axaml
@@ -2,23 +2,39 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- Width="360" Height="150"
+ xmlns:svg="using:Avalonia.Svg.Skia"
+ Width="360" Height="180"
x:Class="ZXBSInstaller.Controls.ToolItemControl"
FontSize="12">
Name
- Description
-
+
+
+
+
+ Description
+
+
+
- Path
+ Path
Installed version:
Latest version:
-
+
+
+
+
diff --git a/ZXBSInstaller/Controls/ToolItemControl.axaml.cs b/ZXBSInstaller/Controls/ToolItemControl.axaml.cs
index 392cbcb..3fb33b0 100644
--- a/ZXBSInstaller/Controls/ToolItemControl.axaml.cs
+++ b/ZXBSInstaller/Controls/ToolItemControl.axaml.cs
@@ -3,37 +3,62 @@
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using System;
+using ZXBSInstaller.Log;
using ZXBSInstaller.Log.Neg;
namespace ZXBSInstaller.Controls;
+
+///
+/// Box with the tool information
+///
public partial class ToolItemControl : UserControl
{
+ ///
+ /// External tool for the box
+ ///
public ExternalTool ExternalTool = null;
+ ///
+ /// Tool selected for installation?
+ ///
public bool IsSelected = false;
+ // Colors
public static SolidColorBrush colorRed = new SolidColorBrush(Colors.Red);
public static SolidColorBrush colorGreen = new SolidColorBrush(Colors.LightGreen);
+ ///
+ /// Command callBack
+ ///
private static Action Command = null;
+ ///
+ /// Constructor
+ ///
+ /// External tool to display
+ /// Command delagate
public ToolItemControl(ExternalTool tool, Action callBackCommand)
{
InitializeComponent();
+ // Set fileds
ExternalTool = tool;
Command = callBackCommand;
+ // Show tool image and data
UITools.ShowImage($"{ExternalTool.Id}.png", imgIcon);
txtName.Text = tool.Name;
txtDescription.Text = tool.Description;
txtPath.Text = "Path: " + tool.LocalPath;
-
+ txtLicense.Text = "Licence: " + tool.LicenseType;
+ txtAuthor.Text = "Author(s): " + tool.Author;
+ // Set chkSelect status
IsSelected = tool.UpdateNeeded;
tool.IsSelected = IsSelected;
chkSelect.IsChecked = IsSelected;
+ // Display installed version
if (tool.InstalledVersion == null)
{
txtActual.Text = $"Installed version: None";
@@ -52,6 +77,7 @@ public ToolItemControl(ExternalTool tool, Action callBackCommand
}
}
+ // Display latest version
if (tool.LatestVersion == null)
{
txtLatest.Text = $"Latest version: Unknow";
@@ -62,6 +88,12 @@ public ToolItemControl(ExternalTool tool, Action callBackCommand
}
}
+
+ ///
+ /// ChkSelected changes
+ ///
+ ///
+ ///
private void chkSelect_IsCheckedChanged(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
IsSelected = chkSelect.IsChecked == true;
@@ -69,8 +101,19 @@ private void chkSelect_IsCheckedChanged(object? sender, Avalonia.Interactivity.R
Command(ExternalTool.Id, "CHECKED");
}
+
+ ///
+ /// Versions button
+ ///
+ ///
+ ///
private void btnAllVersions_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
Command(ExternalTool.Id, "VERSIONS");
}
+
+ private void btnViewSite_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
+ {
+ ServiceLayer.OpenUrlInBrowser(ExternalTool.SiteUrl);
+ }
}
\ No newline at end of file
diff --git a/ZXBSInstaller/Controls/VersionControl.axaml.cs b/ZXBSInstaller/Controls/VersionControl.axaml.cs
index bbbda14..e99cb19 100644
--- a/ZXBSInstaller/Controls/VersionControl.axaml.cs
+++ b/ZXBSInstaller/Controls/VersionControl.axaml.cs
@@ -12,35 +12,58 @@ namespace ZXBSInstaller.Controls;
public partial class VersionControl : UserControl
{
+ ///
+ /// External tool of the item
+ ///
public ExternalTool Tool { get; set; }
+ ///
+ /// Version info of the item
+ ///
public ExternalTools_Version ToolVersion = null;
+ ///
+ /// Pair or odd row
+ ///
private bool IsPair = false;
-
private static bool IsPairGlobal = false;
+ ///
+ /// Colours
+ ///
private static SolidColorBrush ColorPair= new SolidColorBrush(Color.FromRgb(20, 20, 20));
private static SolidColorBrush ColorNormal= new SolidColorBrush(Colors.Black);
private static SolidColorBrush ColorHover = new SolidColorBrush(Colors.DarkBlue);
private static SolidColorBrush ColorGreen = new SolidColorBrush(Colors.LightGreen);
+ ///
+ /// CallBack Command
+ ///
private static Action Command = null;
+ ///
+ /// Constructor
+ ///
+ /// ExternalTool of the item
+ /// Version info of the tool
+ /// CallBack command
public VersionControl(ExternalTool tool, ExternalTools_Version toolVersion, Action callBackCommand)
{
InitializeComponent();
+ // Set fields
Tool= tool;
ToolVersion = toolVersion;
Command = callBackCommand;
if (tool == null)
{
+ // tool = null for a header
pnlHeader.IsVisible = true;
pnlRow.IsVisible = false;
IsPair = true;
}
else
{
+ // Display version data
pnlHeader.IsVisible = false;
pnlRow.IsVisible = true;
txtPlatform.Text = ToolVersion.OperatingSystem.ToString();
@@ -53,6 +76,7 @@ public VersionControl(ExternalTool tool, ExternalTools_Version toolVersion, Acti
}
IsPairGlobal = !IsPairGlobal;
+ // Colour based on version operating system
if (toolVersion.OperatingSystem == ServiceLayer.CurrentOperatingSystem)
{
btnDownload.Foreground = ColorGreen;
@@ -76,6 +100,13 @@ public VersionControl(ExternalTool tool, ExternalTools_Version toolVersion, Acti
}
}
+
+
+ ///
+ /// Download button
+ ///
+ ///
+ ///
private void btnDownload_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
new Thread(() =>
@@ -85,11 +116,23 @@ private void btnDownload_Click(object? sender, Avalonia.Interactivity.RoutedEven
}).Start();
}
+
+ ///
+ /// Change color when mouse is over
+ ///
+ ///
+ ///
private void pnlRow_PointerEntered(object? sender, Avalonia.Input.PointerEventArgs e)
{
pnlRow.Background = ColorHover;
}
+
+ ///
+ /// Restore color when mouse is out
+ ///
+ ///
+ ///
private void pnlRow_PointerExited(object? sender, Avalonia.Input.PointerEventArgs e)
{
if (IsPair)
diff --git a/ZXBSInstaller/ExternalTools.json b/ZXBSInstaller/ExternalTools.json
new file mode 100644
index 0000000..45ffa91
--- /dev/null
+++ b/ZXBSInstaller/ExternalTools.json
@@ -0,0 +1,62 @@
+[
+ {
+ "Id": "zxbsinstaller",
+ "Enabled": true,
+ "Name": "ZX Basic Studio Installer",
+ "Author": "Duefectu",
+ "Description": "This program, and it is used to download, install and keep all external tools and ZX Basic Studio itself up to date.",
+ "SupportedOperatingSystems": [
+ 1,
+ 2,
+ 3
+ ],
+ "SiteUrl": "https://github.com/boriel-basic/ZXBasicStudio",
+ "LicenseType": "MIT License",
+ "LicenceUrl": "https://raw.githubusercontent.com/boriel-basic/ZXBasicStudio/refs/heads/master/LICENSE.txt",
+ "VersionsUrl": "https://github.com/boriel-basic/ZXBasicStudio/releases/",
+ "LocalPath": "",
+ "FullLocalPath": null,
+ "DirectUpdate": true,
+ "Order": 0
+ },
+ {
+ "Id": "zxbasic",
+ "Enabled": true,
+ "Name": "Boriel ZX Basic Compiler",
+ "Author": "Boriel",
+ "Description": "ZXBCompiler is a BORIEL BASIC cross compiler tool. It's a required tool.'",
+ "SupportedOperatingSystems": [
+ 1,
+ 2,
+ 3
+ ],
+ "SiteUrl": "https://boriel-basic.net",
+ "LicenseType": "GNU Affero General Public License v3.0",
+ "LicenceUrl": "https://raw.githubusercontent.com/boriel-basic/zxbasic/refs/heads/main/LICENSE.txt",
+ "VersionsUrl": "https://boriel.com/files/zxb/",
+ "LocalPath": "",
+ "FullLocalPath": "C:\\ZXNext\\zxbasic\\zxbc.exe",
+ "DirectUpdate": true,
+ "Order": 1
+ },
+ {
+ "Id": "zxbs",
+ "Enabled": true,
+ "Name": "ZX Basic Studio",
+ "Author": "Dr.Gusman, Boriel, Duefectu, AdolFITO, Hash6Iron and SirRickster",
+ "Description": "IDE (Integrated Development Environment) with code editor, Assembler, UDGs, fonts, sprites, .tap editor, debugger, emulator, etc.",
+ "SupportedOperatingSystems": [
+ 1,
+ 2,
+ 3
+ ],
+ "SiteUrl": "https://github.com/boriel-basic/ZXBasicStudio",
+ "LicenseType": "MIT License",
+ "LicenceUrl": "https://raw.githubusercontent.com/boriel-basic/ZXBasicStudio/refs/heads/master/LICENSE.txt",
+ "VersionsUrl": "https://github.com/boriel-basic/ZXBasicStudio/releases/",
+ "LocalPath": "",
+ "FullLocalPath": null,
+ "DirectUpdate": true,
+ "Order": 2
+ }
+]
\ No newline at end of file
diff --git a/ZXBSInstaller/MainWindow.axaml.cs b/ZXBSInstaller/MainWindow.axaml.cs
index 867ac60..9d236a9 100644
--- a/ZXBSInstaller/MainWindow.axaml.cs
+++ b/ZXBSInstaller/MainWindow.axaml.cs
@@ -2,9 +2,6 @@
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Interactivity;
using Avalonia.Threading;
-using MsBox.Avalonia;
-using MsBox.Avalonia.Dto;
-using MsBox.Avalonia.Enums;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -18,7 +15,9 @@ namespace ZXBSInstaller
public partial class MainWindow : Window
{
-
+ ///
+ /// Set Controls.MainControl as content
+ ///
public MainWindow()
{
InitializeComponent();
diff --git a/ZXBSInstaller/Program.cs b/ZXBSInstaller/Program.cs
index 16f6385..7adff00 100644
--- a/ZXBSInstaller/Program.cs
+++ b/ZXBSInstaller/Program.cs
@@ -1,16 +1,23 @@
using Avalonia;
+using Avalonia.OpenGL;
using System;
+using System.IO;
+using System.Linq;
namespace ZXBSInstaller
{
internal class Program
{
+ public static string Version = "";
+
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
- public static void Main(string[] args) => BuildAvaloniaApp()
- .StartWithClassicDesktopLifetime(args);
+ public static void Main(string[] args)
+ {
+ BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
+ }
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
diff --git a/ZXBSInstaller/Properties/launchSettings.json b/ZXBSInstaller/Properties/launchSettings.json
new file mode 100644
index 0000000..dbd81c7
--- /dev/null
+++ b/ZXBSInstaller/Properties/launchSettings.json
@@ -0,0 +1,11 @@
+{
+ "profiles": {
+ "ZXBSInstaller": {
+ "commandName": "Project"
+ },
+ "WSL": {
+ "commandName": "WSL2",
+ "distributionName": ""
+ }
+ }
+}
\ No newline at end of file
diff --git a/ZXBSInstaller/UITools.cs b/ZXBSInstaller/UITools.cs
index becc9ae..e8b75ca 100644
--- a/ZXBSInstaller/UITools.cs
+++ b/ZXBSInstaller/UITools.cs
@@ -12,6 +12,12 @@ namespace ZXBSInstaller
{
internal static class UITools
{
+ ///
+ /// Load and show an image from embded resource into an Image control
+ /// File must be "AvaloniaResource"
+ ///
+ /// File name
+ ///
public static void ShowImage(string fileName, Image imgControl)
{
try
@@ -25,5 +31,26 @@ public static void ShowImage(string fileName, Image imgControl)
{
}
}
+
+
+ ///
+ /// Read a text file from embedded resource and return the content as string
+ ///
+ /// FileName
+ ///
+ public static string GetTextResource(string fileName)
+ {
+ try
+ {
+ var uri = new Uri($"avares://ZXBSInstaller/{fileName}");
+ var asset = AssetLoader.Open(uri);
+ var txt= new StreamReader(asset).ReadToEnd();
+ return txt;
+ }
+ catch (Exception ex)
+ {
+ return null;
+ }
+ }
}
}
diff --git a/ZXBSInstaller/ZXBSInstaller.csproj b/ZXBSInstaller/ZXBSInstaller.csproj
index 008c57a..fa2d5ea 100644
--- a/ZXBSInstaller/ZXBSInstaller.csproj
+++ b/ZXBSInstaller/ZXBSInstaller.csproj
@@ -6,15 +6,23 @@
app.manifest
true
zxbs.ico
- 1.0.0.1
+ 1.0.0.0
+
+
+
+
+
+
+
+
@@ -29,6 +37,9 @@
PreserveNewest
+
+
+
@@ -46,7 +57,12 @@
-
+
+
+
+ PreserveNewest
+
+
diff --git a/ZXBSInstaller/version.txt b/ZXBSInstaller/version.txt
new file mode 100644
index 0000000..bd2666a
--- /dev/null
+++ b/ZXBSInstaller/version.txt
@@ -0,0 +1 @@
+1.0.0.0
\ No newline at end of file
diff --git a/ZXBStudio/Program.cs b/ZXBStudio/Program.cs
index 15c8f84..a25ee63 100644
--- a/ZXBStudio/Program.cs
+++ b/ZXBStudio/Program.cs
@@ -3,6 +3,7 @@
using Newtonsoft.Json;
using System;
using System.Diagnostics;
+using System.Linq;
namespace ZXBasicStudio
{
@@ -39,13 +40,20 @@ public static string VersionDate { get
[STAThread]
public static void Main(string[] args)
{
+ SetVersion();
+
+ if (args.Contains("--version"))
+ {
+ Console.WriteLine($"{Version}");
+ return;
+ }
+
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
Formatting= Formatting.Indented,
TypeNameHandling = TypeNameHandling.Auto,
};
- SetVersion();
BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
diff --git a/ZXBStudio/ZXBasicStudio.csproj b/ZXBStudio/ZXBasicStudio.csproj
index d3fb0ec..0edf91e 100644
--- a/ZXBStudio/ZXBasicStudio.csproj
+++ b/ZXBStudio/ZXBasicStudio.csproj
@@ -285,6 +285,7 @@
+
@@ -555,6 +556,9 @@
PreserveNewest
+
+ PreserveNewest
+
diff --git a/ZXBStudio/version.txt b/ZXBStudio/version.txt
new file mode 100644
index 0000000..1f0cf6b
--- /dev/null
+++ b/ZXBStudio/version.txt
@@ -0,0 +1 @@
+1.7.0.0
\ No newline at end of file