542 lines
18 KiB
C#
542 lines
18 KiB
C#
using EgwControlCenter.Core;
|
|
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Win32;
|
|
using NLog;
|
|
using System.Diagnostics;
|
|
using System.IO.Compression;
|
|
using System.Reflection;
|
|
|
|
namespace EgwControlCenter.App
|
|
{
|
|
public partial class BlazorForm : Form
|
|
{
|
|
#region Public Constructors
|
|
|
|
public BlazorForm()
|
|
{
|
|
InitializeComponent();
|
|
CheckUnzip();
|
|
ServiceInit();
|
|
CleanOldTrayIcons();
|
|
InitBlazorView();
|
|
StartTimer();
|
|
StartLastAsync();
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Private Fields
|
|
|
|
private static bool forceClose = false;
|
|
|
|
/// <summary>
|
|
/// Classe logger
|
|
/// </summary>
|
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
|
|
|
private Size minSize = new Size(676, 409);
|
|
|
|
/// <summary>
|
|
/// Periodo di blocco invio nuove notifiche se ci sono + update...
|
|
/// </summary>
|
|
private int VetoNewNotifySec = 15;
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Private Properties
|
|
|
|
private static AppControlService ACService { get; set; } = null!;
|
|
|
|
private string AppName => CurrAssembly.Name ?? "EgalWare ACC";
|
|
|
|
private System.Reflection.AssemblyName CurrAssembly { get; set; } = new System.Reflection.AssemblyName();
|
|
|
|
/// <summary>
|
|
/// Ultima visualizzazione messaggio...
|
|
/// </summary>
|
|
private DateTime lastMsqShown { get; set; } = DateTime.MinValue;
|
|
|
|
private Size lastSize { get; set; } = new Size(660, 480);
|
|
|
|
#endregion Private Properties
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Esecuzione del processo di restart
|
|
/// </summary>
|
|
private static void DoRestart(bool fullRestart)
|
|
{
|
|
// full restart usa sw esterno, altrimenti solo app che riparte SENZA check update esterno
|
|
if (fullRestart)
|
|
{
|
|
// uso restarter esterno...
|
|
Assembly assembly = Assembly.GetExecutingAssembly();
|
|
string startDir = Path.GetDirectoryName(assembly.Location)!;
|
|
string extPath = Path.Combine(startDir, "libs", "EgwAccRestarter.exe");
|
|
// uso processstartInfo x nascondere finestra
|
|
ProcessStartInfo startInfo = new ProcessStartInfo();
|
|
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
|
#if DEBUG
|
|
startInfo.WindowStyle = ProcessWindowStyle.Normal;
|
|
#endif
|
|
startInfo.CreateNoWindow = true;
|
|
startInfo.FileName = extPath;
|
|
ACService.SendRebooted(true);
|
|
Process.Start(startInfo);
|
|
}
|
|
else
|
|
{
|
|
// NON eseguo...
|
|
forceClose = true;
|
|
Application.Restart();
|
|
Environment.Exit(0);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Riavvio il timer...
|
|
/// </summary>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
private void ACService_EA_ConfigUpdated()
|
|
{
|
|
timerCheck.Stop();
|
|
timerTask.Stop();
|
|
StartTimer();
|
|
}
|
|
|
|
private void ACService_EA_ReloadRequested()
|
|
{
|
|
// effettua chiamata reload
|
|
DoRestart(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gestione evento restart applicazione
|
|
/// </summary>
|
|
private void ACService_EA_RestartRequested()
|
|
{
|
|
// effettua chiamata restart
|
|
DoRestart(true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica se ci siano update da mostrare come notifica in tray
|
|
/// </summary>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
private void ACService_EA_StatusUpdated()
|
|
{
|
|
// notifica ballontip se ho aggiornamenti...
|
|
DateTime adesso = DateTime.Now;
|
|
// mostro se non ne ho ricevuti altri da almeno 10 sec...
|
|
if (WindowState != FormWindowState.Normal && adesso > lastMsqShown.AddSeconds(VetoNewNotifySec))
|
|
{
|
|
// salvo che ho mostrato msg
|
|
lastMsqShown = adesso;
|
|
notifyIcon1.BalloonTipTitle = "EgalWare's App Control Center";
|
|
notifyIcon1.BalloonTipText = "Update found!";
|
|
notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
|
|
notifyIcon1.BalloonTipClicked += NotifyIcon1_BalloonTipClicked;
|
|
// mostro notifica... SE abilitata
|
|
if (ACService.EnableNotify)
|
|
{
|
|
notifyIcon1.ShowBalloonTip(200);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void BlazorForm_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
if (forceClose)
|
|
{
|
|
ACService.EA_StatusUpdated -= ACService_EA_StatusUpdated;
|
|
ACService.EA_ConfigUpdated -= ACService_EA_ConfigUpdated;
|
|
ACService.EA_RestartRequested -= ACService_EA_RestartRequested;
|
|
ACService.EA_ReloadRequested -= ACService_EA_ReloadRequested;
|
|
timerCheck.Stop();
|
|
timerCheck.Dispose();
|
|
timerTask.Stop();
|
|
timerTask.Dispose();
|
|
}
|
|
else
|
|
{
|
|
e.Cancel = true;
|
|
// reimposto size...
|
|
Size = lastSize;
|
|
SetPosition();
|
|
SendToTray();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Evento completamento caricamento app
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void BlazorForm_Load(object sender, EventArgs e)
|
|
{
|
|
SetPosition();
|
|
// aspetto e poi mando a tray...
|
|
await Task.Delay(500);
|
|
SendToTray();
|
|
// eseguo task preliminari tipo invio reset effettuato + elenco conf...
|
|
await Task.Delay(100);
|
|
await ACService.SendRebootedAsync(false);
|
|
// ora invio info licenza (SE disponibili)
|
|
await Task.Delay(100);
|
|
await ACService.SendLicInfo();
|
|
// infine invio info conf (x editing successivo)
|
|
await Task.Delay(100);
|
|
await ACService.SendConfTarget();
|
|
// invio stats avvio
|
|
await Task.Delay(100);
|
|
await ACService.SendStats();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Evento post resize
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void BlazorForm_Resize(object sender, EventArgs e)
|
|
{
|
|
CheckFormVisibility();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica stato windows (minimized/normal) e visibilità con tray...
|
|
/// </summary>
|
|
private void CheckFormVisibility()
|
|
{
|
|
// controllo cosa devo mostrare...
|
|
if (WindowState == FormWindowState.Minimized)
|
|
{
|
|
SendToTray();
|
|
}
|
|
notifyIcon1.Visible = true;
|
|
}
|
|
|
|
private void CleanOldTrayIcons()
|
|
{
|
|
Assembly assembly = Assembly.GetExecutingAssembly();
|
|
string startDir = Path.GetDirectoryName(assembly.Location)!;
|
|
string appPath = assembly.ManifestModule.FullyQualifiedName.Replace("dll", "exe");
|
|
RegistryKey? key = Registry.CurrentUser.OpenSubKey(@"Control Panel\NotifyIconSettings", true);
|
|
if (key != null)
|
|
{
|
|
foreach (string subKeyName in key.GetSubKeyNames())
|
|
{
|
|
RegistryKey? subKey = key.OpenSubKey(subKeyName);
|
|
if (subKey != null)
|
|
{
|
|
string executablePath = subKey.GetValue("ExecutablePath") as string ?? "";
|
|
// cerco solo le chiavi di EgwControlCenter.App.exe
|
|
if (!string.IsNullOrEmpty(executablePath))
|
|
{
|
|
if (executablePath.EndsWith("EgwControlCenter.App.exe") || executablePath.Contains("EgwControlCenter"))
|
|
{
|
|
// se il path NON E' quello da cui sta girando il software -->
|
|
// elimino chiave registro...
|
|
if (!executablePath.Equals(appPath))
|
|
{
|
|
key.DeleteSubKey(subKeyName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("NotifyIconSettings key not found.");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// crea menù tray x applicazione
|
|
/// </summary>
|
|
private void CreateTrayMenu()
|
|
{
|
|
// Fix testi menù tray...
|
|
trayMenu.Items.Clear();
|
|
// aggiungo azioni con tasto DX
|
|
trayMenu.Items.Add("Show EgalWare ACC");
|
|
trayMenu.Items.Add("Reload Config");
|
|
trayMenu.Items.Add("Restart And update");
|
|
trayMenu.Items.Add("Close EgalWare ACC");
|
|
}
|
|
|
|
private void DoDisplay()
|
|
{
|
|
Show();
|
|
WindowState = FormWindowState.Normal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chiamata controllo status update
|
|
/// </summary>
|
|
private async Task ForceReload()
|
|
{
|
|
await ACService.DoFullCheckAsync(true);
|
|
await ACService.DoTaskCheckAsync(true);
|
|
}
|
|
|
|
private void InitBlazorView()
|
|
{
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
#if false
|
|
CurrAssembly = Assembly.GetExecutingAssembly().GetName();
|
|
Log.Trace($"EgalWare's AppControlCenter Init, v.{CurrAssembly.Version}");
|
|
#endif
|
|
// sistemo grafica TRAY ICON
|
|
SetupTrayIcon();
|
|
CreateTrayMenu();
|
|
try
|
|
{
|
|
Log.Trace($"TrayMenu OK | {sw.ElapsedMilliseconds}ms");
|
|
var services = new ServiceCollection();
|
|
Log.Trace($"Add ServiceCollection | {sw.ElapsedMilliseconds}ms");
|
|
services.AddWindowsFormsBlazorWebView();
|
|
Log.Trace($"Add AddWindowsFormsBlazorWebView | {sw.ElapsedMilliseconds}ms");
|
|
services.AddSingleton<AppControlService>(ACService);
|
|
Log.Trace($"Add AppControlService | {sw.ElapsedMilliseconds}ms");
|
|
blazorWebView1.HostPage = "wwwroot\\index.html";
|
|
blazorWebView1.Services = services.BuildServiceProvider();
|
|
blazorWebView1.RootComponents.Add<MainBlazor>("#app");
|
|
Log.Trace($"Add MainBlazor | {sw.ElapsedMilliseconds}ms");
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Exception during setartup{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
|
|
private void NotifyIcon1_BalloonTipClicked(object? sender, EventArgs e)
|
|
{
|
|
DoDisplay();
|
|
}
|
|
|
|
/// <summary>
|
|
/// doppio click su tray icon
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void notifyIcon1_DoubleClick(object sender, EventArgs e)
|
|
{
|
|
if (WindowState == FormWindowState.Minimized)
|
|
{
|
|
DoDisplay();
|
|
}
|
|
else
|
|
{
|
|
SendToTray();
|
|
}
|
|
}
|
|
|
|
private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
|
|
{
|
|
if (e.Button != MouseButtons.Right)
|
|
{
|
|
try
|
|
{
|
|
if (WindowState == FormWindowState.Minimized)
|
|
{
|
|
DoDisplay();
|
|
}
|
|
else
|
|
{
|
|
SendToTray();
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Errore in notifyIcon1_MouseClick{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gestisce "andata nel tray" della form
|
|
/// </summary>
|
|
private void SendToTray()
|
|
{
|
|
// notifica ballontip se ho aggiornamenti...
|
|
DateTime adesso = DateTime.Now;
|
|
if (adesso > lastMsqShown.AddSeconds(VetoNewNotifySec))
|
|
{
|
|
// salvo che ho mostrato msg
|
|
lastMsqShown = adesso;
|
|
notifyIcon1.BalloonTipTitle = AppName;
|
|
notifyIcon1.BalloonTipText = $"{AppName} running on tray";
|
|
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
|
|
notifyIcon1.BalloonTipClicked += NotifyIcon1_BalloonTipClicked;
|
|
notifyIcon1.Visible = true;
|
|
// mostro notifica... SE abilitata
|
|
if (ACService != null && ACService.EnableNotify)
|
|
{
|
|
notifyIcon1.ShowBalloonTip(100);
|
|
}
|
|
}
|
|
WindowState = FormWindowState.Minimized;
|
|
Hide();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue eventuale unzip file risorse www
|
|
/// </summary>
|
|
private void CheckUnzip()
|
|
{
|
|
CurrAssembly = Assembly.GetExecutingAssembly().GetName();
|
|
Log.Info($"EgalWare's AppControlCenter Init, v.{CurrAssembly.Version}");
|
|
string exePath = Assembly.GetExecutingAssembly().Location;
|
|
string appDir = Path.GetDirectoryName(exePath) ?? "";
|
|
if (!string.IsNullOrEmpty(appDir))
|
|
{
|
|
string srcZip = Path.Combine(appDir, "wwwroot.zip");
|
|
if ((File.Exists(srcZip)))
|
|
{
|
|
Log.Info($"Zip file found");
|
|
// decomprimo
|
|
ZipFile.ExtractToDirectory(srcZip, appDir, true);
|
|
Log.Info($"Zip file extracted");
|
|
// elimino zip
|
|
File.Delete(srcZip);
|
|
Log.Info($"Zip file removed");
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ServiceInit()
|
|
{
|
|
//init preliminare servizio controllo
|
|
ACService = new AppControlService();
|
|
ACService.EA_StatusUpdated += ACService_EA_StatusUpdated;
|
|
ACService.EA_ConfigUpdated += ACService_EA_ConfigUpdated;
|
|
ACService.EA_RestartRequested += ACService_EA_RestartRequested;
|
|
ACService.EA_ReloadRequested += ACService_EA_ReloadRequested;
|
|
}
|
|
|
|
private void SetPosition()
|
|
{
|
|
// posiziono in basso a sx...
|
|
Rectangle workArea = Screen.GetWorkingArea(this);
|
|
this.Location = new Point(workArea.Right - lastSize.Width, workArea.Bottom - lastSize.Height);
|
|
}
|
|
|
|
private void SetupTrayIcon()
|
|
{
|
|
// fix icon!
|
|
notifyIcon1.Text = $"EgalWare's AppControlCenter | {CurrAssembly.Version}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// init ultime attività async
|
|
/// </summary>
|
|
private void StartLastAsync()
|
|
{
|
|
var pUpd = Task.Run(async () =>
|
|
{
|
|
await ForceReload();
|
|
});
|
|
pUpd.Wait();
|
|
}
|
|
|
|
private void StartTimer()
|
|
{
|
|
// timer controlli da conf
|
|
timerCheck.Interval = (ACService.RefreshPeriod * 1000);
|
|
// timer statistiche a 30 min fisso x ora
|
|
#if DEBUG
|
|
timerStats.Interval = 1000 * 60 * 5;
|
|
#else
|
|
timerStats.Interval = 1000 * 60 * 30;
|
|
#endif
|
|
// avvio timer
|
|
timerCheck.Start();
|
|
timerTask.Start();
|
|
timerStats.Start();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esecuzione task di verifica stato app
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void timerCheck_Tick(object sender, EventArgs e)
|
|
{
|
|
// fermo task...
|
|
timerCheck.Stop();
|
|
// esegue controllo locale ed eventualmente remoto se scaduto...
|
|
await ACService.DoFullCheckAsync(false);
|
|
// riavvio task x evitare sovrapposizioni in debug
|
|
timerCheck.Start();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gestione timer statistiche
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void timerStats_Tick(object sender, EventArgs e)
|
|
{
|
|
// fermo task...
|
|
timerStats.Stop();
|
|
// esegue controllo task
|
|
await ACService.SendStats();
|
|
await ACService.SendLicInfo();
|
|
await ACService.SendConfTarget();
|
|
// riavvio task x evitare sovrapposizioni in debug
|
|
timerStats.Start();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Timer task (1 sec base)
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void timerTask_Tick(object sender, EventArgs e)
|
|
{
|
|
// fermo task...
|
|
timerTask.Stop();
|
|
// esegue controllo task
|
|
await ACService.DoTaskCheckAsync(false);
|
|
// riavvio task x evitare sovrapposizioni in debug
|
|
timerTask.Start();
|
|
}
|
|
|
|
/// <summary>
|
|
/// click su menù contestuale in tray
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void trayMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
|
|
{
|
|
if (e != null && e.ClickedItem != null && !string.IsNullOrEmpty(e.ClickedItem.Text))
|
|
{
|
|
if (e.ClickedItem.Text.StartsWith("Close"))
|
|
{
|
|
// chiudo!
|
|
forceClose = true;
|
|
Close();
|
|
}
|
|
else if (e.ClickedItem.Text.StartsWith("Restart"))
|
|
{
|
|
DoRestart(true);
|
|
}
|
|
else if (e.ClickedItem.Text.StartsWith("Reload"))
|
|
{
|
|
DoRestart(false);
|
|
}
|
|
else if (e.ClickedItem.Text.StartsWith("Show"))
|
|
{
|
|
Show();
|
|
WindowState = FormWindowState.Normal;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
} |