From 6229ca8a03fe80484f545bd9f59a305843a61762 Mon Sep 17 00:00:00 2001 From: Alex Bezdieniezhnykh Date: Sun, 6 Jul 2025 23:22:21 +0300 Subject: [PATCH] rework autoupdate to script only zoom fix --- Azaion.Common/Controls/CanvasEditor.cs | 28 ++++++++---- Azaion.Common/DTO/ApiCredentials.cs | 12 +++++- Azaion.Common/DTO/DirectoriesConfig.cs | 3 +- Azaion.Common/Security.cs | 59 ++++++++++++++++++++++++++ Azaion.Inference/azaion-inference.spec | 2 +- Azaion.LoaderUI/App.xaml.cs | 6 --- Azaion.LoaderUI/Azaion.LoaderUI.csproj | 9 +++- Azaion.LoaderUI/Login.xaml.cs | 50 ++++++++++------------ Azaion.LoaderUI/updater.cmd | 39 +++++++++++++++++ Azaion.Suite/App.xaml.cs | 43 +++++++------------ build/build_dotnet.cmd | 4 +- build/publish.cmd | 4 +- 12 files changed, 179 insertions(+), 80 deletions(-) create mode 100644 Azaion.Common/Security.cs create mode 100644 Azaion.LoaderUI/updater.cmd diff --git a/Azaion.Common/Controls/CanvasEditor.cs b/Azaion.Common/Controls/CanvasEditor.cs index 3d93002..c2dd310 100644 --- a/Azaion.Common/Controls/CanvasEditor.cs +++ b/Azaion.Common/Controls/CanvasEditor.cs @@ -126,9 +126,26 @@ public class CanvasEditor : Canvas public void SetImageSource(ImageSource? source) { + SetZoom(); _backgroundImage.Source = source; } + private void SetZoom(Matrix? matrix = null) + { + if (matrix == null) + { + _matrixTransform.Matrix = Matrix.Identity; + _isZoomedIn = false; + } + else + { + _matrixTransform.Matrix = matrix.Value; + _isZoomedIn = true; + } + foreach (var detection in CurrentDetections) + detection.UpdateAdornerScale(scale: _matrixTransform.Matrix.M11); + } + private void CanvasWheel(object sender, MouseWheelEventArgs e) { if (Keyboard.Modifiers != ModifierKeys.Control) @@ -139,19 +156,12 @@ public class CanvasEditor : Canvas var matrix = _matrixTransform.Matrix; if (scale < 1 && matrix.M11 * scale < 1.0) - { - _matrixTransform.Matrix = Matrix.Identity; - _isZoomedIn = false; - } + SetZoom(); else { matrix.ScaleAt(scale, scale, mousePos.X, mousePos.Y); - _matrixTransform.Matrix = matrix; - _isZoomedIn = true; + SetZoom(matrix); } - - foreach (var detection in CurrentDetections) - detection.UpdateAdornerScale(scale: _matrixTransform.Matrix.M11); } private void Init(object sender, RoutedEventArgs e) diff --git a/Azaion.Common/DTO/ApiCredentials.cs b/Azaion.Common/DTO/ApiCredentials.cs index d11ab90..7978e40 100644 --- a/Azaion.Common/DTO/ApiCredentials.cs +++ b/Azaion.Common/DTO/ApiCredentials.cs @@ -4,7 +4,8 @@ using MessagePack; namespace Azaion.Common.DTO; [MessagePackObject] -public class ApiCredentials : EventArgs +[Verb("credsManual", HelpText = "Manual Credentials")] +public class ApiCredentials { [Key(nameof(Email))] [Option('e', "email", Required = true, HelpText = "User Email")] @@ -13,4 +14,11 @@ public class ApiCredentials : EventArgs [Key(nameof(Password))] [Option('p', "pass", Required = true, HelpText = "User Password")] public string Password { get; set; } = null!; -} \ No newline at end of file +} + +[Verb("credsEncrypted", isDefault: true, HelpText = "Encrypted Credentials")] +public class ApiCredentialsEncrypted +{ + [Option('c', "creds", Group = "auto", HelpText = "Encrypted Creds")] + public string Creds { get; set; } = null!; +} diff --git a/Azaion.Common/DTO/DirectoriesConfig.cs b/Azaion.Common/DTO/DirectoriesConfig.cs index c4d6f73..5d8a5b8 100644 --- a/Azaion.Common/DTO/DirectoriesConfig.cs +++ b/Azaion.Common/DTO/DirectoriesConfig.cs @@ -1,9 +1,8 @@ namespace Azaion.Common.DTO; public class DirectoriesConfig - { - public string ApiResourcesDirectory { get; set; } = null!; + public string? ApiResourcesDirectory { get; set; } = null!; public string VideosDirectory { get; set; } = null!; public string LabelsDirectory { get; set; } = null!; diff --git a/Azaion.Common/Security.cs b/Azaion.Common/Security.cs new file mode 100644 index 0000000..02980fc --- /dev/null +++ b/Azaion.Common/Security.cs @@ -0,0 +1,59 @@ +using System.Security.Cryptography; +using System.Text; +using Newtonsoft.Json; + +namespace Azaion.Common; + +public class Security +{ + private static string GenDefaultKey() + { + var date = DateTime.UtcNow; + return $"sAzaion_default_dfvkjhg_{date:yyyy}-{date:MM}_{date:dd}_{date:HH}_key"; + } + + public static string Encrypt(T model, string? key = null) where T : class + { + var json = JsonConvert.SerializeObject(model); + var inputBytes = Encoding.UTF8.GetBytes(json); + + var keyBytes = SHA256.HashData(Encoding.UTF8.GetBytes(key ?? GenDefaultKey())); + var iv = RandomNumberGenerator.GetBytes(16); + + using var aes = Aes.Create(); + aes.Key = keyBytes; + aes.IV = iv; + aes.Mode = CipherMode.CFB; + aes.Padding = PaddingMode.ISO10126; + + using var encryptor = aes.CreateEncryptor(); + var ciphertext = encryptor.TransformFinalBlock(inputBytes, 0, inputBytes.Length); + + var result = new byte[iv.Length + ciphertext.Length]; + iv.CopyTo(result, 0); + ciphertext.CopyTo(result, iv.Length); + + return Convert.ToBase64String(result); + } + + public static T Decrypt(string encryptedData, string? key = null) where T : class + { + var ciphertextWithIv = Convert.FromBase64String(encryptedData); + var keyBytes = SHA256.HashData(Encoding.UTF8.GetBytes(key ?? GenDefaultKey())); + + var iv = ciphertextWithIv[..16]; + var ciphertext = ciphertextWithIv[16..]; + + using var aes = Aes.Create(); + aes.Key = keyBytes; + aes.IV = iv; + aes.Mode = CipherMode.CFB; + aes.Padding = PaddingMode.ISO10126; + + using var decryptor = aes.CreateDecryptor(); + var plaintext = decryptor.TransformFinalBlock(ciphertext, 0, ciphertext.Length); + + var json = Encoding.UTF8.GetString(plaintext); + return JsonConvert.DeserializeObject(json)!; + } +} \ No newline at end of file diff --git a/Azaion.Inference/azaion-inference.spec b/Azaion.Inference/azaion-inference.spec index 7ae365f..b2ed95d 100644 --- a/Azaion.Inference/azaion-inference.spec +++ b/Azaion.Inference/azaion-inference.spec @@ -4,7 +4,7 @@ from PyInstaller.utils.hooks import collect_all datas = [('venv\\Lib\\site-packages\\cv2', 'cv2')] binaries = [] -hiddenimports = ['constants_inf', 'file_data', 'remote_command_inf', 'remote_command_handler_inf', 'annotation', 'loader_client', 'ai_config', 'tensorrt_engine', 'onnx_engine', 'inference_engine', 'inference', 'main-inf'] +hiddenimports = ['constants_inf', 'file_data', 'remote_command_inf', 'remote_command_handler_inf', 'annotation', 'loader_client', 'ai_config', 'tensorrt_engine', 'onnx_engine', 'inference_engine', 'inference'] hiddenimports += collect_submodules('cv2') tmp_ret = collect_all('psutil') datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] diff --git a/Azaion.LoaderUI/App.xaml.cs b/Azaion.LoaderUI/App.xaml.cs index d879953..ff41625 100644 --- a/Azaion.LoaderUI/App.xaml.cs +++ b/Azaion.LoaderUI/App.xaml.cs @@ -46,11 +46,5 @@ public partial class App host.Services.GetRequiredService().Show(); } - - - - //AFter: - //_loaderClient.Login(credentials); - //_loaderClient.Dispose(); } diff --git a/Azaion.LoaderUI/Azaion.LoaderUI.csproj b/Azaion.LoaderUI/Azaion.LoaderUI.csproj index 7d83672..a61de0e 100644 --- a/Azaion.LoaderUI/Azaion.LoaderUI.csproj +++ b/Azaion.LoaderUI/Azaion.LoaderUI.csproj @@ -24,7 +24,6 @@ - @@ -37,6 +36,14 @@ PreserveNewest + + + PreserveNewest + + + + + diff --git a/Azaion.LoaderUI/Login.xaml.cs b/Azaion.LoaderUI/Login.xaml.cs index dfb0539..f42bdf0 100644 --- a/Azaion.LoaderUI/Login.xaml.cs +++ b/Azaion.LoaderUI/Login.xaml.cs @@ -6,6 +6,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; +using Azaion.Common; using MessagePack; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -57,22 +58,34 @@ public partial class Login TbStatus.Foreground = Brushes.Black; var installerVersion = await GetInstallerVer(); var localVersion = GetLocalVer(); + var credsEncrypted = Security.Encrypt(creds); if (installerVersion > localVersion) { TbStatus.Text = $"Updating from {localVersion} to {installerVersion}..."; - await DownloadAndRunInstaller(); - TbStatus.Text = $"Installed {installerVersion}!"; + var (installerName, stream) = await _azaionApi.DownloadInstaller(_dirConfig?.SuiteInstallerDirectory ?? ""); + var localFileStream = new FileStream(installerName, FileMode.Create, FileAccess.Write); + await stream.CopyToAsync(localFileStream); + localFileStream.Close(); + stream.Close(); + Process.Start(new ProcessStartInfo + { + FileName = "cmd.exe", + Arguments = $"/c updater.cmd {Process.GetCurrentProcess().Id} {installerName} {Constants.AZAION_SUITE_EXE} \"{credsEncrypted}\"" + }); } else + { TbStatus.Text = "Your version is up to date!"; - Process.Start(Constants.AZAION_SUITE_EXE, $"-e {creds.Email} -p {creds.Password}"); - await Task.Delay(800); - TbStatus.Text = "Loading..."; - while (!Process.GetProcessesByName(Constants.INFERENCE_EXE).Any()) - await Task.Delay(500); - await Task.Delay(1500); + Process.Start(Constants.AZAION_SUITE_EXE, $"-c {credsEncrypted}"); + await Task.Delay(800); + TbStatus.Text = "Loading..."; + while (!Process.GetProcessesByName(Constants.INFERENCE_EXE).Any()) + await Task.Delay(500); + await Task.Delay(1500); + } + Close(); } catch (Exception exception) @@ -146,26 +159,7 @@ public partial class Login throw; } } - - - private async Task DownloadAndRunInstaller() - { - var (installerName, stream) = await _azaionApi.DownloadInstaller(_dirConfig?.SuiteInstallerDirectory ?? ""); - var localFileStream = new FileStream(installerName, FileMode.Create, FileAccess.Write); - await stream.CopyToAsync(localFileStream); - localFileStream.Close(); - stream.Close(); - var processInfo = new ProcessStartInfo(installerName) - { - UseShellExecute = true, - Arguments = "/VERYSILENT" - }; - - var process = Process.Start(processInfo); - await process!.WaitForExitAsync(); - File.Delete(installerName); - } - + private async Task GetInstallerVer() { TbStatus.Text = "Checking for the newer version..."; diff --git a/Azaion.LoaderUI/updater.cmd b/Azaion.LoaderUI/updater.cmd new file mode 100644 index 0000000..464a1a9 --- /dev/null +++ b/Azaion.LoaderUI/updater.cmd @@ -0,0 +1,39 @@ +@echo off +setlocal + +REM Verify that all four arguments were provided +if "%~4"=="" ( + echo Error: Missing arguments. + echo Usage: %0 ^ ^ ^ ^ + exit /b 1 +) + +set "PARENT_PID=%1" +set "INSTALLER_PATH=%2" +set "MAIN_APP_PATH=%3" +set "CREDS=%~4" + +:WAIT_FOR_PARENT_EXIT +echo Waiting for parent process (PID: %PARENT_PID%) to close... +tasklist /fi "pid eq %PARENT_PID%" | find "%PARENT_PID%" >nul +if %errorlevel% == 0 ( + timeout /t 1 /nobreak >nul + goto WAIT_FOR_PARENT_EXIT +) + +start "" /wait "%INSTALLER_PATH%" /VERYSILENT + +del "%INSTALLER_PATH%" +echo Installed new version %INSTALLER_PATH% + +start "" "%MAIN_APP_PATH%" -c "%CREDS%" + +echo Loading... +:WAIT_FOR_APP_START +timeout /t 1 /nobreak >nul +tasklist /fi "imagename eq azaion-inference.exe" | find "azaion-inference.exe" >nul +if %errorlevel% neq 0 goto WAIT_FOR_APP_START + +timeout /t 5 /nobreak >nul +echo Process started. +endlocal \ No newline at end of file diff --git a/Azaion.Suite/App.xaml.cs b/Azaion.Suite/App.xaml.cs index d392ea8..d5dfc5f 100644 --- a/Azaion.Suite/App.xaml.cs +++ b/Azaion.Suite/App.xaml.cs @@ -54,11 +54,12 @@ public partial class App rollingInterval: RollingInterval.Day) .CreateLogger(); - Parser.Default.ParseArguments(e.Args) - .WithParsed(Start) + Parser.Default.ParseArguments(e.Args) + .WithParsed(Start) + .WithParsed(StartEncrypted) .WithNotParsed(ErrorHandling); } - + private void ErrorHandling(IEnumerable obj) { Log.Fatal($"Error happened: {string.Join(",", obj.Select(x => @@ -70,30 +71,11 @@ public partial class App Current.Shutdown(); } - private Stream GetSystemConfig(LoaderClient loaderClient, string apiDir) + private Stream GetConfig(LoaderClient loaderClient, string filename, string? apiDir) { try { - return loaderClient.LoadFile("config.system.json", apiDir); - } - catch (Exception e) - { - Log.Logger.Error(e, e.Message); - return new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new - { - AnnotationConfig = Constants.DefaultAnnotationConfig, - AIRecognitionConfig = Constants.DefaultAIRecognitionConfig, - GpsDeniedConfig = Constants.DefaultGpsDeniedConfig, - ThumbnailConfig = Constants.DefaultThumbnailConfig, - }))); - } - } - - private Stream GetSecuredConfig(LoaderClient loaderClient, string apiDir) - { - try - { - return loaderClient.LoadFile("config.secured.json", apiDir); + return loaderClient.LoadFile(filename, apiDir ?? ""); } catch (Exception e) { @@ -102,6 +84,13 @@ public partial class App } } + private void StartEncrypted(ApiCredentialsEncrypted credsEncrypted) + { + Log.Logger.Information(credsEncrypted.Creds); + Start(Security.Decrypt(credsEncrypted.Creds)); + } + + private void Start(ApiCredentials credentials) { try @@ -109,8 +98,8 @@ public partial class App new ConfigUpdater().CheckConfig(); var initConfig = Constants.ReadInitConfig(Log.Logger); var apiDir = initConfig.DirectoriesConfig.ApiResourcesDirectory; + _loaderClient = new LoaderClient(initConfig.LoaderClientConfig, Log.Logger, _mainCTokenSource.Token); - _loaderClient.StartClient(); _loaderClient.Connect(); _loaderClient.Login(credentials); @@ -121,8 +110,8 @@ public partial class App .ConfigureAppConfiguration((_, config) => config .AddCommandLine(Environment.GetCommandLineArgs()) .AddJsonFile(Constants.CONFIG_PATH, optional: true, reloadOnChange: true) - .AddJsonStream(GetSystemConfig(_loaderClient, apiDir)) - .AddJsonStream(GetSecuredConfig(_loaderClient, apiDir))) + .AddJsonStream(GetConfig(_loaderClient, "config.system.json", apiDir)) + .AddJsonStream(GetConfig(_loaderClient, "config.secured.json", apiDir))) .UseSerilog() .ConfigureServices((context, services) => { diff --git a/build/build_dotnet.cmd b/build/build_dotnet.cmd index 2da085a..9384501 100644 --- a/build/build_dotnet.cmd +++ b/build/build_dotnet.cmd @@ -13,8 +13,8 @@ del dist\config.json robocopy "dist" "dist-azaion" "Azaion.Annotator.dll" "Azaion.Dataset.dll" "Azaion.Common.dll" "Azaion.CommonSecurity.dll" /MOV robocopy "dist" "dist-azaion" "Azaion.Suite.dll" "Azaion.Suite.exe" "Azaion.Suite.runtimeconfig.json" "Azaion.Suite.deps.json" "logo.png" /MOV -robocopy "Azaion.LoaderUI\bin\Release\net8.0-windows\win-x64\publish" "dist-dlls" "Azaion.LoaderUI.dll" "Azaion.LoaderUI.exe" "Azaion.LoaderUI.runtimeconfig.json" ^ - "Azaion.LoaderUI.deps.json" "loaderconfig.json" +robocopy "Azaion.LoaderUI\bin\Release\net8.0-windows\win-x64\publish" "dist-azaion" "Azaion.LoaderUI.dll" "Azaion.LoaderUI.exe" "Azaion.LoaderUI.runtimeconfig.json" "Azaion.LoaderUI.deps.json" "loaderconfig.json" /MOV +robocopy "Azaion.LoaderUI\bin\Release\net8.0-windows\win-x64\publish" "dist-dlls" "updater.cmd" /MOV move dist\config.production.json dist-azaion\config_updated.json diff --git a/build/publish.cmd b/build/publish.cmd index ce16cb0..4831551 100644 --- a/build/publish.cmd +++ b/build/publish.cmd @@ -19,8 +19,8 @@ echo building and upload iterative installer... iscc build\installer.iterative.iss call build\upload.cmd "suite-dev" -echo building full installer -iscc build\installer.full.iss +@rem echo building full installer +@rem iscc build\installer.full.iss cd /d %CURRENT_DIR% echo Done! \ No newline at end of file