Merge branch 'release/AddVersOnLimanAndACC'

This commit is contained in:
Samuele Locatelli
2024-09-19 10:48:24 +02:00
28 changed files with 1124 additions and 136 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ namespace Core
{
// classi utilità x cache REDIS dati DB
public const string redisBaseAddr = "MagManUi";
public const string redisBaseAddr = "LiMan:Ui";
public const string rKeyConfig = $"{redisBaseAddr}:Cache";
}
}
+21
View File
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EgwControlCenter.Core
{
public class CoreEnum
{
public enum AppType
{
None,
Cli,
Machine,
WebApp,
WinApp
}
}
}
@@ -6,4 +6,10 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.3.4" />
<PackageReference Include="RestSharp" Version="112.0.0" />
</ItemGroup>
</Project>
-16
View File
@@ -1,16 +0,0 @@
namespace EgwControlCenter.Core
{
public class Enum
{
/// <summary>
/// Elenco tipi app ammessi
/// </summary>
public static Dictionary<string, string> AppType = new Dictionary<string, string>{
{ "", "---Selezionare---" },
{ "Cli", "Cli (Console)" },
{ "Machine", "Machine" },
{ "WebApp", "WebApp" },
{ "WinApp", "WinApp" }
};
}
}
+13 -2
View File
@@ -1,8 +1,10 @@
using System;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace EgwControlCenter.Core.Models
@@ -11,7 +13,16 @@ namespace EgwControlCenter.Core.Models
{
[Key]
public int Idx { get; set; } = 0;
public string ObjType { get; set; } = "";
/// <summary>
/// Tipo applicazione da monitorare
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public CoreEnum.AppType ApplicationType{ get; set; } = CoreEnum.AppType.None;
/// <summary>
/// Path di base da monitorare
/// </summary>
public string BasePath { get; set; } = "";
}
}
@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EgwControlCenter.Core.Models
{
public class ReleaseDTO
{
/// <summary>
/// Codice/Nome applicativo
/// </summary>
public string CodApp { get; set; } = "";
/// <summary>
/// Versione applicativo formato semver numerico 4 blocchi
/// </summary>
public string VersNum { get; set; } = "0.0.0.0";
/// <summary>
/// Versione applicativo, formato testuale libero, può essere uguale a VersNum
/// </summary>
public string VersText { get; set; } = "a.b";
/// <summary>
/// Oggetto versione calcolato da VersNum
/// </summary>
public Version VersVal
{
get
{
Version answ = new Version();
try
{
// solo se è una versione valida: SemVer = 2/3 punti
int numPunti = VersNum.Length - VersNum.Replace(".", "").Length;
if (numPunti >= 2 && numPunti <= 3)
{
answ = !string.IsNullOrEmpty(VersNum) ? new Version(VersNum) : new Version();
}
}
catch { }
return answ;
}
}
/// <summary>
/// Verifica se sia permessa la versione quando viene valutata la versione massima consentita
/// </summary>
public bool IsPermitted { get; set; } = false;
/// <summary>
/// Data di release
/// </summary>
public DateTime ReleaseDate { get; set; } = DateTime.Today.AddYears(100);
/// <summary>
/// Tag associati a versione, comma separated
/// </summary>
public string RelTags { get; set; } = "";
/// <summary>
/// Url pagina web di changelog (traduzione gestita sul sito target) - calcolato da CodApp + vers
/// </summary>
public string UrlChangelog { get; set; } = "http://releases.egalware.com";
/// <summary>
/// Url pagina web di changelog estesa (traduzione gestita sul sito target) - calcolato da CodApp + vers
/// </summary>
public string UrlChangelogExt { get; set; } = "http://releases.egalware.com";
/// <summary>
/// Attivo/Pubblico (qui calcolato, attivo se la data di release è passata, poi potrebbe essere gestito a parte da DB)
/// </summary>
public bool IsActive { get; set; } = false;
}
}
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace EgwControlCenter.Core.Models
{
public class TargetStatus
{
#region Public Properties
/// <summary>
/// Nome applicazione
/// </summary>
public string CodApp { get; set; } = "";
/// <summary>
/// Release locale (es Macchine: come letta da file *.mlde)
/// </summary>
public ReleaseDTO CurrLocal { get; set; } = new ReleaseDTO();
/// <summary>
/// DataOra ultima verifica locale
/// </summary>
public DateTime LastUpdateLoc { get; set; } = DateTime.Now;
/// <summary>
/// DataOra ultima verifica remota
/// </summary>
public DateTime LastUpdateRem { get; set; } = DateTime.Now;
/// <summary>
/// Elenco release remote da REST service
/// </summary>
public List<ReleaseDTO> ListRemote { get; set; } = new List<ReleaseDTO>();
#endregion Public Properties
#region Public Methods
public ReleaseDTO CurrRemote
{
get
{
ReleaseDTO answ = new ReleaseDTO();
if (ListRemote != null && ListRemote.Count() > 0)
{
answ = ListRemote
.OrderByDescending(x => x.VersVal)
.ThenByDescending(x => x.ReleaseDate)
.FirstOrDefault() ?? new ReleaseDTO();
}
return answ;
}
}
/// <summary>
/// Calcolo condizione "ci sono update":
/// - almeno 1 rel remota
/// - la rel remota "+ recente" / + alta &gt; rel locale
/// </summary>
/// <returns></returns>
public bool HasUpdate()
{
bool answ = false;
if (ListRemote != null && ListRemote.Count > 0)
{
// prendo max release
var lastRemote = ListRemote.OrderByDescending(x => x.VersVal).FirstOrDefault();
//devo averla trovata...
if (lastRemote != null)
{
answ = lastRemote.VersVal > CurrLocal.VersVal;
}
}
return answ;
}
#endregion Public Methods
}
}
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace EgwControlCenter.Core.Models
{
public class VersStatusDTO
{
#region Public Properties
/// <summary>
/// Nome applicazione
/// </summary>
public string CodApp { get; set; } = "";
/// <summary>
/// Versione applicativo corrente
/// </summary>
public string VersNumCurr { get; set; } = "0.0.0.0";
/// <summary>
/// Versione applicativo LAST disponibile
/// </summary>
public string VersNumLast { get; set; } = "0.0.0.0";
/// <summary>
/// Tag associati a ultima versione disponibile, comma separated
/// </summary>
public string RelTagsLast { get; set; } = "";
#endregion Public Properties
}
}
+14
View File
@@ -0,0 +1,14 @@
using EgwControlCenter.Core.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EgwControlCenter.Core
{
public class PatrolSettings
{
public List<ControlTarget> TargetList { get; set; } = new List<ControlTarget>();
}
}
+426
View File
@@ -0,0 +1,426 @@
using EgwControlCenter.Core.Models;
using Newtonsoft.Json;
using NLog;
using RestSharp;
using RestSharp.Serializers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EgwControlCenter.Core
{
public class ReleaseChecker
{
#region Public Fields
/// <summary>
/// Classe logger
/// </summary>
public static Logger Log = LogManager.GetCurrentClassLogger();
#endregion Public Fields
#region Public Constructors
public ReleaseChecker(string baseDir, string currConfig)
{
AppDir = baseDir;
ConfName = currConfig;
// verifico path...
if (string.IsNullOrEmpty(AppDir))
{
AppDir = AppDomain.CurrentDomain.BaseDirectory;
}
if (File.Exists(ConfPath))
{
var rawData = File.ReadAllText(ConfPath);
if (!string.IsNullOrEmpty(rawData))
{
CurrPatrolCont = JsonConvert.DeserializeObject<PatrolSettings>(rawData) ?? new PatrolSettings();
}
}
// cerco se presente file status precedente e lo ricarico...
if (File.Exists(StatusPath))
{
var rawData = File.ReadAllText(StatusPath);
if (!string.IsNullOrEmpty(rawData))
{
ListStatus = JsonConvert.DeserializeObject<List<TargetStatus>>(rawData) ?? new List<TargetStatus>();
}
}
}
#endregion Public Constructors
#region Public Properties
/// <summary>
/// DataOra ultimo check locale
/// </summary>
public DateTime LastChecked()
{
DateTime answ = new DateTime(DateTime.Today.Year, 1, 1);
//se ho record locali cerco il + recente
if (ListStatus != null && ListStatus.Count > 0)
{
var primo = ListStatus
.OrderByDescending(x => x.LastUpdateLoc)
.FirstOrDefault();
if (primo != null)
{
answ = primo.LastUpdateLoc;
}
}
return answ;
}
public bool HasUpdate()
{
bool answ = false;
//se ho record locali cerco il + recente
if (ListStatus != null && ListStatus.Count > 0)
{
foreach (var item in ListStatus)
{
answ = item.HasUpdate();
if (answ)
{
break;
}
}
}
return answ;
}
/// <summary>
/// Elenco degli oggetti stato dei programmi monitorati
/// </summary>
protected List<TargetStatus> ListStatus { get; set; } = new List<TargetStatus>();
/// <summary>
/// Elenco degli oggetti stato dei programmi monitorati
/// </summary>
public List<VersStatusDTO> ListAppStatus { get; set; } = new List<VersStatusDTO>();
#endregion Public Properties
#region Public Methods
/// <summary>
/// Esegue verifica remota versioni x i sw tracciati
/// </summary>
/// <returns></returns>
public bool CheckRemoteReleases()
{
bool fatto = false;
try
{
// ciclo x ogni item da controllare
foreach (var item in ListStatus)
{
if (item.CurrLocal != null)
{
// verifico release da remoto aggiorno obj
var ListRem = GetRemoteRel(item.CodApp, item.CurrLocal.VersNum);
if (ListRem != null)
{
item.ListRemote = ListRem;
item.LastUpdateRem = DateTime.Now;
}
}
}
// salvo status...
SaveStatus();
fatto = true;
}
catch (Exception exc)
{
Log.Error($"Errore in CheckRemoteReleases{Environment.NewLine}{exc}");
}
return fatto;
}
/// <summary>
/// Aggiorna (se necessario) lo stato degli oggetti da monitorare
/// </summary>
/// <param name="doRefresh"></param>
/// <returns></returns>
public bool UpdateLocalStatus(bool doRefresh)
{
bool fatto = false;
// se non forzato verifico file dello status salvato x necessità refresh
if (!doRefresh)
{
doRefresh = checkScaduto();
}
// verifico se procedere...
if (doRefresh)
{
// nuovo obj controlli
List<TargetStatus> newListStatus = new List<TargetStatus>();
// ciclo x ogni item da controllare
foreach (var item in CurrPatrolCont.TargetList)
{
// verifico contenuto secondo tipo
if (item != null)
{
switch (item.ApplicationType)
{
case CoreEnum.AppType.None:
break;
case CoreEnum.AppType.Cli:
break;
case CoreEnum.AppType.Machine:
// processo la folder indicata e cerco tutte le macchine contenute
if (Directory.Exists(item.BasePath))
{
// recupero elenco sottodirectory = macchine
var dirList = Directory.GetDirectories(item.BasePath);
// ciclo e cerco i file mlde...
foreach (var currDir in dirList)
{
// cerco se ci sia un file mlde...
var fileFound = Directory.GetFiles(currDir, "*.mlde");
if (fileFound != null && fileFound.Count() > 0)
{
// prendo il primo...
var tgtFile = fileFound.FirstOrDefault() ?? "";
var currRelDto = MldeGetRelease(tgtFile);
if (currRelDto != null)
{
string codApp = Path.GetFileName(currDir);
newListStatus.Add(new TargetStatus()
{
CodApp = codApp,
CurrLocal = currRelDto,
LastUpdateLoc = DateTime.Now
});
}
}
}
}
break;
case CoreEnum.AppType.WebApp:
break;
case CoreEnum.AppType.WinApp:
break;
default:
break;
}
}
// aggiungo oggetto TargetStatus
}
// aggiorno obj...
ListStatus = newListStatus;
// salvo status...
SaveStatus();
fatto = true;
}
return fatto;
}
#endregion Public Methods
#region Protected Fields
protected static string apiUrl = "https://liman.egalware.com/ELM.Api/";
#endregion Protected Fields
#region Protected Properties
/// <summary>
/// Configurazione degli oggetti da monitorare
/// </summary>
protected PatrolSettings CurrPatrolCont { get; set; } = new PatrolSettings();
#endregion Protected Properties
#region Private Properties
private string AppDir { get; set; } = "";
/// <summary>
/// Periodo minimo per autorefresh versioni default 1 gg) protected TimeSpan AutoRefreshVeto
/// { get; set; } = TimeSpan.FromDays(1);
/// </summary>
private TimeSpan AutoRefreshVeto { get; set; } = TimeSpan.FromSeconds(30);
private string ConfName { get; set; } = "";
/// <summary>
/// Path file di conf check
/// </summary>
private string ConfPath
{
get => Path.Combine(AppDir, ConfName);
}
private string StatusName { get; set; } = "LastStatus.json";
/// <summary>
/// Path file salvataggio status
/// </summary>
private string StatusPath
{
get => Path.Combine(AppDir, StatusName);
}
#endregion Private Properties
#region Private Methods
private static List<ReleaseDTO> GetRemoteRel(string CodApp, string CurrVers)
{
List<ReleaseDTO> answ = new List<ReleaseDTO>();
try
{
// client chiamate rest
var client = new RestClient(apiUrl);
string rawData = "";
// Chiamo il metodo!
var checkRel = new RestRequest($"/api/Release/filt/{CodApp}?VersMin={CurrVers}", Method.Get);
// effettuo vera chiamata
var pUpd = Task.Run(async () =>
{
var currResp = await client.GetAsync(checkRel);
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
{
var currList = JsonConvert.DeserializeObject<List<ReleaseDTO>>(currResp.Content);
if (currList != null)
{
answ = currList;
}
}
});
pUpd.Wait();
}
catch (Exception exc)
{
Log.Error($"Eccezione in fase gestione REST services{Environment.NewLine}{exc}");
}
return answ;
}
/// <summary>
/// Verifica se il check sia scaduto rispetto ad AutoRefreshVeto
/// </summary>
/// <returns></returns>
private bool checkScaduto()
{
bool answ = false;
DateTime adesso = DateTime.Now;
// ciclo per ogni oggetto della lista...
foreach (var item in ListStatus)
{
if (item.LastUpdateLoc.Add(AutoRefreshVeto) < adesso)
{
answ = true;
// esco!
break;
}
}
return answ;
}
/// <summary>
/// Recupera oggetto releaseDTO da file indicato
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
private ReleaseDTO? MldeGetRelease(string filePath)
{
ReleaseDTO? answ = null;
if (File.Exists(filePath))
{
string versNum = "";
string versTxt = "";
string codApp = "";
// leggo una riga alla volta e cerco le chaivi
using (StreamReader reader = new StreamReader(filePath))
{
string? line;
bool stop = false;
while ((line = reader.ReadLine()) != null && !stop)
{
if (line.StartsWith("PP_VER"))
{
// splitto e prendo secondo
var splitTxt = line.Split("=");
if (splitTxt.Length > 1)
{
versTxt = splitTxt[1].Trim().Replace("'", "").Trim();
}
}
else if (line.StartsWith("PP_NVER"))
{
// splitto e prendo secondo
var splitTxt = line.Split("=");
if (splitTxt.Length > 1)
{
versNum = splitTxt[1].Trim().Replace("'", "").Trim();
}
}
else if (line.StartsWith("MACH_NAME"))
{
// splitto e prendo secondo
var splitTxt = line.Split("=");
if (splitTxt.Length > 1)
{
codApp = splitTxt[1].Trim().Replace("'", "").Trim();
}
}
// se ho trovato tutto esco!
stop = !string.IsNullOrEmpty(versNum) && !string.IsNullOrEmpty(versTxt) && !string.IsNullOrEmpty(codApp);
}
}
// creo OBJ e lo restituisco...
answ = new ReleaseDTO()
{
CodApp = codApp,
ReleaseDate = DateTime.Now,
VersNum = versNum,
VersText = versTxt
};
}
return answ;
}
/// <summary>
/// Effettua salvataggio obj status
/// </summary>
private void SaveStatus()
{
var rawData = JsonConvert.SerializeObject(ListStatus, Formatting.Indented);
if (rawData != null && rawData.Length > 2)
{
File.WriteAllText(StatusPath, rawData);
}
// aggiorno obj calcolato versioni...
ListAppStatus = ListStatus
.Where(x => x.HasUpdate())
.Select(x => new VersStatusDTO
{
CodApp = x.CodApp,
VersNumCurr = x.CurrLocal.VersNum,
VersNumLast = x.CurrRemote.VersNum,
RelTagsLast = x.CurrRemote.RelTags
})
.ToList();
}
#endregion Private Methods
}
}
+10
View File
@@ -25,5 +25,15 @@ namespace EgwControlCenter
/// </summary>
UPD = 2
}
/// <summary>
/// Elenco tipi app ammessi
/// </summary>
public static Dictionary<string, string> AppType = new Dictionary<string, string>{
{ "", "---Selezionare---" },
{ "Cli", "Cli (Console)" },
{ "Machine", "Machine" },
{ "WebApp", "WebApp" },
{ "WinApp", "WinApp" }
};
}
}
+2 -2
View File
@@ -46,7 +46,7 @@
<!--Definizione avvio Adapter-->
<add key="autoLoadConf" value="true" />
<add key="autoStartOnLoad" value="true" />
<add key="startMinimized" value="false" />
<add key="startMinimized" value="true" />
<add key="windowCanMax" value="true" />
<add key="trayClose" value="true" />
<add key="autoSaveSec" value="60" />
@@ -56,7 +56,7 @@
<add key="vetoSeconds" value="5" />
<!--conf file-->
<add key="dataPath" value="DATA" />
<add key="dataConfPath" value="DATA\CONF" />
<add key="dataConfPath" value="Conf" />
<add key="dataDatPath" value="DATA\DAT" />
<add key="resxPath" value="Resources" />
<add key="mainConfFile" value="MAIN.ini" />
+1
View File
@@ -0,0 +1 @@

+9
View File
@@ -0,0 +1,9 @@
{
"TargetList": [
{
"Idx": 1,
"ApplicationType": "Machine",
"BasePath": "C:\\Testing\\Machine"
}
]
}
+99 -29
View File
@@ -31,44 +31,34 @@
components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ControlCenter));
label1 = new Label();
label2 = new Label();
label3 = new Label();
trayMenu = new ContextMenuStrip(components);
notifyIcon1 = new NotifyIcon(components);
btnSetup = new Button();
btnUpdate = new Button();
lblOut = new Label();
timerCheck = new System.Windows.Forms.Timer(components);
statusStrip1 = new StatusStrip();
tsLabelVers = new ToolStripStatusLabel();
tsLabelOut = new ToolStripStatusLabel();
dgView = new DataGridView();
statusStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dgView).BeginInit();
SuspendLayout();
//
// label1
//
label1.AutoSize = true;
label1.Font = new Font("Roboto", 24F, FontStyle.Regular, GraphicsUnit.Point, 0);
label1.Location = new Point(193, 9);
label1.Font = new Font("Roboto", 16F, FontStyle.Regular, GraphicsUnit.Point, 0);
label1.Location = new Point(70, 9);
label1.Name = "label1";
label1.Size = new Size(429, 38);
label1.Size = new Size(293, 27);
label1.TabIndex = 0;
label1.Text = "EgalWare App Control Center";
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(53, 83);
label2.Name = "label2";
label2.Size = new Size(152, 15);
label2.TabIndex = 1;
label2.Text = "Elenco App (list? webview?)";
//
// label3
//
label3.AutoSize = true;
label3.Location = new Point(484, 83);
label3.Name = "label3";
label3.Size = new Size(156, 15);
label3.TabIndex = 2;
label3.Text = "Btn setup app da controllare";
//
// trayMenu
//
trayMenu.Name = "trayMenu";
trayMenu.Size = new Size(181, 26);
trayMenu.Size = new Size(61, 4);
trayMenu.ItemClicked += trayMenu_ItemClicked;
//
// notifyIcon1
@@ -79,20 +69,94 @@
notifyIcon1.Visible = true;
notifyIcon1.DoubleClick += notifyIcon1_DoubleClick;
//
// btnSetup
//
btnSetup.Anchor = AnchorStyles.Top | AnchorStyles.Right;
btnSetup.Location = new Point(385, 13);
btnSetup.Name = "btnSetup";
btnSetup.Size = new Size(27, 23);
btnSetup.TabIndex = 3;
btnSetup.Text = "...";
btnSetup.UseVisualStyleBackColor = true;
btnSetup.Click += btnSetup_Click;
//
// btnUpdate
//
btnUpdate.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
btnUpdate.Location = new Point(314, 223);
btnUpdate.Name = "btnUpdate";
btnUpdate.Size = new Size(98, 23);
btnUpdate.TabIndex = 4;
btnUpdate.Text = "Check Now";
btnUpdate.UseVisualStyleBackColor = true;
btnUpdate.Click += btnUpdate_Click;
//
// lblOut
//
lblOut.AutoSize = true;
lblOut.Location = new Point(44, 117);
lblOut.Name = "lblOut";
lblOut.Size = new Size(12, 15);
lblOut.TabIndex = 5;
lblOut.Text = "-";
//
// timerCheck
//
timerCheck.Interval = 1000;
timerCheck.Tick += timerCheck_Tick;
//
// statusStrip1
//
statusStrip1.Items.AddRange(new ToolStripItem[] { tsLabelVers, tsLabelOut });
statusStrip1.Location = new Point(0, 249);
statusStrip1.Name = "statusStrip1";
statusStrip1.Size = new Size(421, 22);
statusStrip1.TabIndex = 6;
statusStrip1.Text = "statusStrip1";
//
// tsLabelVers
//
tsLabelVers.Name = "tsLabelVers";
tsLabelVers.Size = new Size(49, 17);
tsLabelVers.Text = "v.0.0.0.0";
tsLabelVers.TextImageRelation = TextImageRelation.Overlay;
//
// tsLabelOut
//
tsLabelOut.Name = "tsLabelOut";
tsLabelOut.Size = new Size(16, 17);
tsLabelOut.Text = "...";
//
// dgView
//
dgView.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
dgView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dgView.Location = new Point(12, 56);
dgView.Name = "dgView";
dgView.Size = new Size(397, 161);
dgView.TabIndex = 7;
//
// ControlCenter
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(label3);
Controls.Add(label2);
ClientSize = new Size(421, 271);
Controls.Add(dgView);
Controls.Add(statusStrip1);
Controls.Add(lblOut);
Controls.Add(btnUpdate);
Controls.Add(btnSetup);
Controls.Add(label1);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "ControlCenter";
Text = "Egalware Control Center";
FormClosing += ControlCenter_FormClosing;
Load += ControlCenter_Load;
Shown += ControlCenter_Shown;
Resize += ControlCenter_Resize;
statusStrip1.ResumeLayout(false);
statusStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)dgView).EndInit();
ResumeLayout(false);
PerformLayout();
}
@@ -100,9 +164,15 @@
#endregion
private Label label1;
private Label label2;
private Label label3;
private ContextMenuStrip trayMenu;
private NotifyIcon notifyIcon1;
private Button btnSetup;
private Button btnUpdate;
private Label lblOut;
private System.Windows.Forms.Timer timerCheck;
private StatusStrip statusStrip1;
private ToolStripStatusLabel tsLabelVers;
private DataGridView dgView;
private ToolStripStatusLabel tsLabelOut;
}
}
+198 -76
View File
@@ -1,5 +1,12 @@
using System.Windows.Forms;
using static EgwControlCenter.AccEnum;
using Microsoft.VisualBasic;
using EgwControlCenter.Core;
using System.Diagnostics;
using Newtonsoft.Json;
using System.Text;
using System.ComponentModel;
using EgwControlCenter.Core.Models;
namespace EgwControlCenter
{
@@ -10,8 +17,7 @@ namespace EgwControlCenter
public ControlCenter()
{
InitializeComponent();
setupTrayIcon();
createTrayMenu();
InitObjects();
}
#endregion Public Constructors
@@ -25,12 +31,55 @@ namespace EgwControlCenter
#endregion Protected Fields
#region Private Properties
private ReleaseChecker CurrCheck { get; set; } = new ReleaseChecker("", "");
private bool locCheckOk { get; set; } = false;
private bool remCheckOk { get; set; } = false;
#endregion Private Properties
#region Private Methods
private void btnSetup_Click(object sender, EventArgs e)
{
string authPwd = Interaction.InputBox("Prego inserire pwd per abilitare lo sblocco", "Verifica Utente", "", 10, 10);
//verifico passphrase
if (authPwd == "24068Seriate")
{
TargetSetup tgtForm = new TargetSetup();
tgtForm.Show();
}
else
{
string message = "La passphrase inserita non è corretta. Impossibile procedere";
string caption = "Auth Error";
MessageBoxButtons buttons = MessageBoxButtons.OK;
DialogResult result;
result = MessageBox.Show(message, caption, buttons);
}
}
private void btnUpdate_Click(object sender, EventArgs e)
{
Stopwatch sw = new Stopwatch();
sw.Start();
// effettua un refresh del controllo status...
locCheckOk = CurrCheck.UpdateLocalStatus(true);
if (locCheckOk)
{
remCheckOk = CurrCheck.CheckRemoteReleases();
}
sw.Stop();
DisplayCheckResult(sw.Elapsed);
}
/// <summary>
/// Verifica stato windows (minimized/normal) e visibilità con tray...
/// </summary>
private void checkFormVisibility()
private void CheckFormVisibility()
{
// se non può massimizzare imposto COMUNQUE a minimized...
if (!AccUtils.CRB("windowCanMax"))
@@ -55,47 +104,6 @@ namespace EgwControlCenter
{
notifyIcon1.Visible = false;
}
#if false
// fix child!
this.LayoutMdi(MdiLayout.TileHorizontal);
#endif
}
/// <summary>
/// crea menù tray x applicazione
/// </summary>
private void createTrayMenu()
{
// Fix testi menù tray...
trayMenu.Items.Clear();
// SE permessa massimizzazione...
trayMenu.Items.Add("Show EgalWare ACC");
// se è permesso chiudere
trayMenu.Items.Add("Close EgalWare ACC");
}
/// <summary>
/// Gestisce "andata nel tray" della form
/// </summary>
private void sendToTray()
{
if (!notifyIcon1.Visible)
{
notifyIcon1.BalloonTipTitle = AccUtils.CRS("appName");
notifyIcon1.BalloonTipText = $"{AccUtils.CRS("appName")} running on tray";
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(100);
}
Hide();
}
private void setupTrayIcon()
{
// fix icon!
var currObj = System.Reflection.Assembly.GetExecutingAssembly().GetName();
notifyIcon1.Text = $"EgalWare's AppControlCenter | {currObj.Version}";
//Icon = Icon.ExtractAssociatedIcon(AccUtils.defIconFilePath);
//notifyIcon1.Icon = Icon.ExtractAssociatedIcon(AccUtils.defIconFilePath);
}
/// <summary>
@@ -105,39 +113,15 @@ namespace EgwControlCenter
/// <param name="e"></param>
private void ControlCenter_FormClosing(object sender, FormClosingEventArgs e)
{
#if false
closeAllChild();
#endif
timerCheck.Stop();
timerCheck.Dispose();
}
/// <summary>
/// click su menù contestuale in tray
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void trayMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
private void ControlCenter_Load(object sender, EventArgs e)
{
if (e != null && e.ClickedItem != null && !string.IsNullOrEmpty(e.ClickedItem.Text))
{
if (e.ClickedItem.Text.StartsWith("Close"))
{
#if false
// stop child adapters...
closeAllChild();
#endif
// chiudo!
Close();
}
else if (e.ClickedItem.Text.StartsWith("Show"))
{
if (AccUtils.CRB("windowCanMax"))
{
Show();
WindowState = FormWindowState.Normal;
}
}
}
// posiziono in basso a sx...
Rectangle workArea = Screen.GetWorkingArea(this);
this.Location = new Point(workArea.Right - Size.Width, workArea.Bottom - Size.Height);
}
/// <summary>
@@ -147,7 +131,7 @@ namespace EgwControlCenter
/// <param name="e"></param>
private void ControlCenter_Resize(object sender, EventArgs e)
{
checkFormVisibility();
CheckFormVisibility();
}
/// <summary>
@@ -167,9 +151,72 @@ namespace EgwControlCenter
sendToTray();
}
}
}
/// <summary>
/// crea menù tray x applicazione
/// </summary>
private void CreateTrayMenu()
{
// Fix testi menù tray...
trayMenu.Items.Clear();
// SE permessa massimizzazione...
trayMenu.Items.Add("Show EgalWare ACC");
// se è permesso chiudere
trayMenu.Items.Add("Close EgalWare ACC");
}
/// <summary>
/// Mostra i risultati dell'esito del controllo release
/// </summary>
/// <param name="elapsed"></param>
private void DisplayCheckResult(TimeSpan elapsed)
{
var list = new BindingList<VersStatusDTO>(CurrCheck.ListAppStatus);
dgView.DataSource = list;
#if false
displayTaskAndLog("Main Form SHOWN (MDI)");
StringBuilder sb = new StringBuilder();
sb.AppendLine("---------------------");
sb.AppendLine($"{DateTime.Now:HH:mm:ss}");
sb.AppendLine("---------------------");
sb.AppendLine();
if (locCheckOk && remCheckOk)
{
string rawConf = JsonConvert.SerializeObject(CurrCheck, Formatting.Indented);
sb.Append(rawConf);
}
sb.AppendLine();
sb.AppendLine("---------------------");
sb.AppendLine($"Eseguito refresh | Loc: {locCheckOk} | Rem: {remCheckOk} | {elapsed.TotalMilliseconds:N0} ms");
lblOut.Text = sb.ToString();
#endif
tsLabelOut.Text = $"Last Check: {CurrCheck.LastChecked():yyyy-MM-dd HH:mm:ss}";
// notifica ballontip se ho aggiornamenti...
if (CurrCheck.HasUpdate() && WindowState != FormWindowState.Normal)
{
notifyIcon1.BalloonTipTitle = "EgalWare's App Control Center";
notifyIcon1.BalloonTipText = "Update found!";
notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning;
notifyIcon1.BalloonTipClicked += NotifyIcon1_BalloonTipClicked;
notifyIcon1.ShowBalloonTip(1000);
}
}
private void InitObjects()
{
SetupTrayIcon();
CreateTrayMenu();
// init obj gestione check...
CurrCheck = new ReleaseChecker(AccUtils.confDir, "ConfPatrol.json");
tsLabelVers.Text = $"EACC v.{CurrAssembly.Version}";
tsLabelOut.Text = $"Last Check: {CurrCheck.LastChecked():yyyy-MM-dd HH:mm:ss}";
timerCheck.Start();
}
private void NotifyIcon1_BalloonTipClicked(object? sender, EventArgs e)
{
Show();
WindowState = FormWindowState.Normal;
}
/// <summary>
@@ -187,6 +234,81 @@ namespace EgwControlCenter
}
}
/// <summary>
/// Gestisce "andata nel tray" della form
/// </summary>
private void sendToTray()
{
if (!notifyIcon1.Visible)
{
notifyIcon1.BalloonTipTitle = AccUtils.CRS("appName");
notifyIcon1.BalloonTipText = $"{AccUtils.CRS("appName")} running on tray";
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
notifyIcon1.BalloonTipClicked += NotifyIcon1_BalloonTipClicked;
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(100);
}
WindowState = FormWindowState.Minimized;
Hide();
}
private System.Reflection.AssemblyName CurrAssembly { get; set; } = new System.Reflection.AssemblyName();
private void SetupTrayIcon()
{
// fix icon!
CurrAssembly = System.Reflection.Assembly.GetExecutingAssembly().GetName();
notifyIcon1.Text = $"EgalWare's AppControlCenter | {CurrAssembly.Version}";
//Icon = Icon.ExtractAssociatedIcon(AccUtils.defIconFilePath);
//notifyIcon1.Icon = Icon.ExtractAssociatedIcon(AccUtils.defIconFilePath);
}
private void timerCheck_Tick(object sender, EventArgs e)
{
Stopwatch sw = new Stopwatch();
sw.Start();
// esegue controllo locale ed eventualmente remoto se scaduto...
locCheckOk = CurrCheck.UpdateLocalStatus(false);
if (locCheckOk)
{
remCheckOk = CurrCheck.CheckRemoteReleases();
}
sw.Stop();
if (locCheckOk)
{
DisplayCheckResult(sw.Elapsed);
}
}
/// <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"))
{
#if false
// stop child adapters...
closeAllChild();
#endif
// chiudo!
Close();
}
else if (e.ClickedItem.Text.StartsWith("Show"))
{
if (AccUtils.CRB("windowCanMax"))
{
Show();
WindowState = FormWindowState.Normal;
}
}
}
}
#endregion Private Methods
}
}
+6
View File
@@ -290,6 +290,12 @@
AAA=
</value>
</data>
<metadata name="timerCheck.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>236, 17</value>
</metadata>
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>351, 17</value>
</metadata>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAMDAAAAEAIACoJQAAFgAAACgAAAAwAAAAYAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+9
View File
@@ -12,4 +12,13 @@
<ProjectReference Include="..\EgwControlCenter.Core\EgwControlCenter.Core.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Conf\.placeholder">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Conf\ConfPatrol.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>License Manager</i>
<h4>Versione: 1.1.2409.1807</h4>
<h4>Versione: 1.1.2409.1910</h4>
<br />
Note di rilascio:
<ul>
+1 -1
View File
@@ -1 +1 @@
1.1.2409.1807
1.1.2409.1910
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.1.2409.1807</version>
<version>1.1.2409.1910</version>
<url>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/LiMan.Transfer.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>
+8 -1
View File
@@ -62,6 +62,7 @@
{
<th>Tipo</th>
<th class="text-right">Descrizione</th>
<th class="text-right">Rel.</th>
<th class="text-right">Db ConnString</th>
<th></th>
}
@@ -100,7 +101,13 @@
<td class="text-right">
<div>@record.Descrizione</div>
</td>
<td class="text-right small text-nowrap">
<td class="text-right">
@if (CurrVersNum(record.CodApp) != "0.0.0.0")
{
<b>@CurrVersNum(record.CodApp)</b>
}
</td>
<td class="text-right small text-truncate" style="max-width:30rem;">
@if (UserHasClaim("Admin"))
{
<div>@record.TplConnString</div>
@@ -182,6 +182,17 @@ namespace LiMan.UI.Components
#region Private Fields
private string CurrVersNum(string CodApp)
{
string answ = "";
var pUpd = Task.Run(async () =>
{
answ = await DataService.ReleaseLastGetByApp(CodApp);
});
pUpd.Wait();
return answ;
}
private string gridKey = "ListApplicazioni";
private List<ApplicativoModel> ListRecords;
+82 -2
View File
@@ -12,6 +12,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NLog;
using Org.BouncyCastle.Asn1.Pkcs;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
@@ -287,7 +288,6 @@ namespace LiMan.UI.Data
{
Log.Error($"Error during AuthClaimByUserID:{Environment.NewLine}{exc}");
}
//return await Task.FromResult(dbResult);
return dbResult;
}
@@ -934,6 +934,54 @@ namespace LiMan.UI.Data
/// <returns></returns>
public async Task<List<ReleaseModel>> ReleaseGetByApp(string CodApp)
{
string source = "DB";
List<ReleaseModel>? dbResult = new List<ReleaseModel>();
try
{
string currKey = $"{Const.rKeyConfig}:App:AllRel:{CodApp}";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string? rawData = await redisDb.StringGetAsync(currKey);
if (!string.IsNullOrEmpty(rawData))
{
source = "REDIS";
var tempResult = JsonConvert.DeserializeObject<List<ReleaseModel>>(rawData);
if (tempResult == null)
{
dbResult = new List<ReleaseModel>();
}
else
{
dbResult = tempResult;
}
}
else
{
dbResult = dbControllerNext.ReleaseGetByApp(CodApp);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
// per evitare loopback uso deserialize...
var tempResult = JsonConvert.DeserializeObject<List<ReleaseModel>>(rawData);
if (tempResult != null)
{
dbResult = tempResult;
}
}
if (dbResult == null)
{
dbResult = new List<ReleaseModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"ReleaseGetByApp | {source} in: {ts.TotalMilliseconds} ms");
}
catch (Exception exc)
{
Log.Error($"Error during ReleaseGetByApp:{Environment.NewLine}{exc}");
}
return dbResult;
#if false
await Task.Delay(1);
List<ReleaseModel> dbResult = new List<ReleaseModel>();
Stopwatch stopWatch = new Stopwatch();
@@ -942,7 +990,39 @@ namespace LiMan.UI.Data
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per ReleaseGetByApp | {CodApp} | {ts.TotalMilliseconds} ms");
return dbResult;
return dbResult;
#endif
}
/// <summary>
/// Ultima Release dato Applicativo
/// </summary>
/// <param name="CodApp">Codice Applicazione</param>
/// <returns></returns>
public async Task<string> ReleaseLastGetByApp(string CodApp)
{
string answ = "";
RedisKey currKey = $"{Const.rKeyConfig}:App:CurrRel";
var rawVal = await redisDb.HashGetAsync(currKey, CodApp);
if (rawVal.HasValue)
{
answ = $"{rawVal}";
}
else
{
var rawList = await ReleaseGetByApp(CodApp);
if (rawList != null)
{
var lastRel = rawList
.OrderByDescending(x => x.VersVal)
.ThenByDescending(x => x.ReleaseDate)
.FirstOrDefault() ?? new ReleaseModel() { CodApp = CodApp };
answ = lastRel.VersNum;
// salvo su redis tab...
await redisDb.HashSetAsync(currKey, CodApp, answ);
}
}
return answ;
}
/// <summary>
+1 -1
View File
@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>1.1.2409.1807</Version>
<Version>1.1.2409.1910</Version>
<RootNamespace>LiMan.UI</RootNamespace>
<AssemblyName>LiMan.UI</AssemblyName>
</PropertyGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>License Manager</i>
<h4>Versione: 1.1.2409.1807</h4>
<h4>Versione: 1.1.2409.1910</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
1.1.2409.1807
1.1.2409.1910
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.1.2409.1807</version>
<version>1.1.2409.1910</version>
<url>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/LiMan.UI.zip</url>
<changelog>https://nexus.steamware.net/repository/SWS/LiMan/stable/LAST/ChangeLog.html</changelog>
<mandatory>false</mandatory>