Files
mapo-iob-man/IOB-MAN.Core/Services/AppControlService.cs
T
2025-06-17 09:15:06 +02:00

1080 lines
36 KiB
C#

using EgwCoreLib.Utils;
using IOB_MAN.Core.Config;
using IOB_MAN.Core.Data;
using IOB_MAN.Core.DTO;
using IOB_MAN.Core.Models;
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Reflection;
using static IOB_MAN.Core.CoreEnum;
namespace IOB_MAN.Core.Services
{
public class AppControlService : IAppControlService, IDisposable
{
#region Public Constructors
/// <summary>
/// Init classe
/// </summary>
/// <param name="startProc">Se True avvia i processi gestiti</param>
public AppControlService(bool startProc)
{
LoadConfAndStart(startProc);
}
#endregion Public Constructors
#region Public Events
/// <summary>
/// Evento update configurazione
/// </summary>
public event Action EA_ConfigUpdated = null!;
/// <summary>
/// Evento richiesta reload applicazione
/// </summary>
public event Action EA_ReloadRequested = null!;
/// <summary>
/// Evento richiesta update applicazione (con check update app)
/// </summary>
public event Action EA_RestartRequested = null!;
/// <summary>
/// Evento update status controlli
/// </summary>
public event Action EA_StatusUpdated = null!;
#endregion Public Events
#region Public Properties
/// <summary>
/// Abilitazione autorestart
/// </summary>
public bool AutoRestartEnabled { get; set; } = true;
public int CheckRestartPeriod
{
get => currAppConf.TaskData.TimerCheckMSec;
set => currAppConf.TaskData.TimerCheckMSec = value;
}
public string ConfDirIob
{
get => confDirIob;
set => confDirIob = value;
}
/// <summary>
/// Configurazione IOB in sola lettura
/// </summary>
public IobManConfig CurrIobConf
{
get => currIobConf;
}
public List<string> CurrIobType
{
get => currIobType;
}
/// <summary>
/// ABilitazione glocale notifiche da conf
/// </summary>
public bool EnableNotify
{
get => currAppConf.EnableNotify;
}
public List<IobAdapt> ListIobAdapters { get; set; } = new List<IobAdapt>();
public LogLevelIob LogLevel
{
get => logLevel;
set
{
if (logLevel != value)
{
logLevel = value;
SetIobLogLevel($"{value}");
}
}
}
/// <summary>
/// Totale processi avviati
/// </summary>
public int NumProcConfig
{
get => numProcConfig;
}
/// <summary>
/// Totale processi running
/// </summary>
public int NumProcRunning
{
get => numProcRunning;
}
/// <summary>
/// Totale processi avviati
/// </summary>
public int NumProcStarted
{
get => numProcStarted;
}
/// <summary>
/// Totale processi avviati
/// </summary>
public int NumTypeConfig
{
get => numTypeConfig;
}
public int RefreshPeriod
{
get => currAppConf.TaskData.TimerFastMSec;
set
{
if (currAppConf.TaskData.TimerFastMSec != value)
{
// verifico ammissibilità
currAppConf.TaskData.TimerFastMSec = value < refPMin ? refPMin : value > refPMax ? refPMax : value;
ReportConfigUpd();
}
}
}
/// <summary>
/// Dataora prox controlloriavvio automatico
/// </summary>
public DateTime VetoAutoCheck
{
get => _VetoAutoCheck;
}
#endregion Public Properties
#region Public Methods
public void DelayRestart(bool doReset)
{
_VetoAutoCheck = _VetoAutoCheck < DateTime.Now || doReset ? DateTime.Now : VetoAutoCheck;
_VetoAutoCheck = _VetoAutoCheck.AddMinutes(minDelayrestart);
ReportConfigUpd();
}
public void Dispose()
{
DoCloseAll(true);
}
/// <summary>
/// Se abilitato esegue riavvio e report processi variati
/// </summary>
/// <param name="doForce">se true esegue anche prima della scadenza veto</param>
public void DoAutoRestart(bool doForce)
{
if (AutoRestartEnabled || doForce)
{
DoReopenClosed();
}
}
/// <summary>
/// Chiude tutti i child
/// </summary>
/// <param name="doReset">resetta elenco</param>
public void DoCloseAll(bool doReset)
{
isBusy = true;
CheckRunningchild();
// provo a chiudere tutti 1:1 per pID
var listPID = ListIobAdapters
.Where(x => x.isRunning)
.Select(x => x.pID)
.ToList();
#if true
Parallel.ForEach(listPID, pID =>
{
ForceKillByPID(pID);
});
#else
foreach(var pID in listPID)
{
ForceKillByPID(pID);
}
#endif
// chiudo per nome SE rimasti
var listNames = currIobConf
.ListTarget
.Select(x => x.Value.ExeName)
.Where(x => !string.IsNullOrEmpty(x))
.Distinct().ToList();
Parallel.ForEach(listNames, prgName =>
{
ForceKillByName(prgName);
});
// aspetto 100ms
// verifico nuovamente i processi
CheckRunningchild();
var stillRunList = ListIobAdapters
.Where(x => x.isRunning)
.ToList();
// eventuale chiusura
if (stillRunList != null && stillRunList.Count > 0)
{
foreach (var item in stillRunList)
{
ForceKillByPID(item.pID);
ForceKillByName(item.ExeName);
}
#if false
Parallel.ForEach(stillRunList, item =>
{
ForceKillByPID(item.pID);
ForceKillByName(item.ExeName);
});
#endif
}
// verifico se resettare
if (doReset)
{
// resetto elenco!
ListIobAdapters.Clear();
numProcStarted = 0;
}
// resetto
item2rem.Clear();
numProcRunning = 0;
isBusy = false;
}
/// <summary>
/// Apre il child selezionato
/// </summary>
public void DoCloseChild(IobAdapt childReq)
{
isBusy = true;
ForceKillByPID(childReq.pID);
CheckRunningchild();
ReportStatusUpd();
isBusy = false;
}
/// <summary>
/// Apre tutti i processi child e li registra...
/// </summary>
public void DoOpenAllChild()
{
isBusy = true;
// preventivamente CHIUDO TUTTO per i programmi configurati...
var listNames = currIobConf
.ListTarget
.Select(x => x.Value.ExeName)
.Where(x => !string.IsNullOrEmpty(x))
.Distinct().ToList();
Parallel.ForEach(listNames, prgName =>
{
ForceKillByName(prgName);
});
Thread.Sleep(100);
// avvio i child
//Parallel.ForEach(currIobConf.ListIOB, item =>
//{
// startChildProc(item.Value, item.Key);
//});
foreach (var item in currIobConf.ListIOB)
{
startChildProc(item.Value, item.Key);
// attesa tra ogni avvio..
Thread.Sleep(100);
}
UpdateCounters();
ReportStatusUpd();
isBusy = false;
}
/// <summary>
/// Apre il child selezionato
/// </summary>
public void DoOpenChildSel(IobAdapt childReq)
{
isBusy = true;
startChildProc(childReq.TgtName, childReq.CodIOB);
UpdateCounters();
ReportStatusUpd();
isBusy = false;
}
/// <summary>
/// Legge il file di configurazione APP e poi quello degli IobAdaptConf
/// </summary>
public void DoReloadConfig()
{
ConfPathApp = Path.Combine(ConfDirBase, AppConfName);
if (File.Exists(ConfPathApp))
{
string rawData = File.ReadAllText(ConfPathApp);
if (!string.IsNullOrEmpty(rawData))
{
try
{
currAppConf = JsonConvert.DeserializeObject<AppSettings>(rawData) ?? new AppSettings();
}
catch { }
}
}
// sistemo conf IobAdaptConf da gestire
if (currAppConf.IobAdapt != null && !string.IsNullOrEmpty(currAppConf.IobAdapt.ConfFile))
{
ConfDirIob = Path.Combine(ConfDirBase, currAppConf.IobAdapt.ConfDir);
ConfPathIob = Path.Combine(ConfDirIob, currAppConf.IobAdapt.ConfFile);
if (File.Exists(ConfPathIob))
{
string rawData = File.ReadAllText(ConfPathIob);
if (!string.IsNullOrEmpty(rawData))
{
try
{
currIobConf = JsonConvert.DeserializeObject<IobManConfig>(rawData) ?? new IobManConfig();
TargetIobList = currIobConf.ListTarget;
}
catch { }
}
// fix eventuale mancanza BaseArgs nel file raw di conf
if (!rawData.Contains("BaseArgs"))
{
RewriteConfFile();
}
}
// sistemo eventuali conf x target mancanti...
FixMissingTargets();
}
currIobType = currIobConf.ListIOB.Select(x => x.Value).Distinct().ToList();
numTypeConfig = currIobType.Count();
numProcConfig = currIobConf.ListIOB.Count();
// leggo altri valori
minDelayrestart = currAppConf.GetKVP_Int("DelayTimerRestart", 20);
}
/// <summary>
/// riapro child chiusi
/// </summary>
public void DoReopenClosed()
{
var listClosed = ListIobAdapters.Where(x => !x.isRunning).ToList();
foreach (var item in listClosed)
{
DoOpenChildSel(item);
}
}
/// <summary>
/// Effettua scansione applicazioni, salva e solleva update
/// </summary>
public async Task DoScan()
{
CheckRunningchild();
await Task.Delay(1);
ReportStatusUpd();
}
/// <summary>
/// Restituisce conf del target IOB dato nome
/// </summary>
/// <param name="codTarget"></param>
/// <returns></returns>
public TargetConfig GetTargetConf(string codTarget)
{
TargetConfig answ = new TargetConfig();
if (currIobConf.ListTarget.ContainsKey(codTarget))
{
answ = currIobConf.ListTarget[codTarget];
}
return answ;
}
public string IobTgtPath(string codIOB)
{
string answ = "";
if (!string.IsNullOrEmpty(codIOB))
{
if (currIobConf.ListIOB.ContainsKey(codIOB))
{
string iobType = currIobConf.ListIOB[codIOB];
if (currIobConf.ListTarget.ContainsKey(iobType))
{
var exeName = currIobConf.ListTarget[iobType].ExePath;
answ = Path.GetDirectoryName(exeName) ?? exeName;
}
}
}
return answ;
}
public string IobType(string codIOB)
{
string answ = "";
if (!string.IsNullOrEmpty(codIOB))
{
if (currIobConf.ListIOB.ContainsKey(codIOB))
{
answ = currIobConf.ListIOB[codIOB];
}
}
return answ;
}
/// <summary>
/// Solleva evento richiesta restart
/// </summary>
public void RaiseRestartReq()
{
// sollevo evento
if (EA_RestartRequested != null)
{
EA_RestartRequested?.Invoke();
}
}
public void ReportStatusUpd()
{
if (EA_StatusUpdated != null)
{
EA_StatusUpdated?.Invoke();
}
}
/// <summary>
/// Avvio di un child process da parametro ARG
/// </summary>
/// <param name="tgtName">Nome Target EXE</param>
/// <param name="codIob">Args da passare all'exe (IobAdaptConf name da caricare)</param>
/// <param name="indice">posizione (opzionale) in lista</param>
public void startChildProc(string tgtName, string codIob, int indice = -1)
{
Stopwatch sw = Stopwatch.StartNew();
// da testare x aprire chiudere risorsa...
string targetExe = @"C:\Steamware\IOB-WIN-NEXT\IOB-WIN-NEXT.exe";// utils.CRS("targetExe");
if (string.IsNullOrEmpty(targetExe))
{
targetExe = Path.Combine(AppContext.BaseDirectory, "Resources", "IOB-WIN-FACADE.exe");
}
string currTgtExe = targetExe;
string startArg = "MODE=MAN IOB=";// $"{utils.CRS("BaseArg")}{codIob}";
if (TargetIobList.Count > 0)
{
if (TargetIobList.ContainsKey(tgtName))
{
currTgtExe = TargetIobList[tgtName].ExePath;
startArg = $"{TargetIobList[tgtName].BaseArgs}{codIob}";
}
}
// verifico esistenza exe, altrimenti crea copia da IOB-WIN-FACADE
if (!File.Exists(currTgtExe))
{
// creo folder
if (!string.IsNullOrEmpty(currTgtExe))
{
string baseExeDir = Path.GetDirectoryName(currTgtExe) ?? "";
if (!string.IsNullOrEmpty(baseExeDir))
{
Directory.CreateDirectory(baseExeDir);
// creo folder conf..
Directory.CreateDirectory(Path.Combine(baseExeDir, "DATA", "CONF"));
// creo file exe!
string srcPath = Path.Combine(AppContext.BaseDirectory, "Resources", "IOB-WIN-FACADE.exe");
File.Copy(srcPath, currTgtExe);
}
}
}
// avvio processo
ProcessStartInfo psi = new ProcessStartInfo
{
//FileName = targetExe,
FileName = currTgtExe,
Arguments = startArg,
WindowStyle = ProcessWindowStyle.Minimized
};
try
{
//childProc.StartInfo = psi;
var p = Process.Start(psi);
if (p != null)
{
// accodo nuovo IobAdaptConf...
DateTime adesso = DateTime.Now;
var exeName = FileVersionInfo.GetVersionInfo(currTgtExe).FileDescription ?? p.ProcessName;
IobAdapt newIob = new IobAdapt(redisConn, codIob, p.Id, exeName, tgtName);
// cerco IOB tra quelli esistenti x calcolo posizione...
var prevRec = ListIobAdapters.FirstOrDefault(x => x.CodIOB == codIob);
if (prevRec != null)
{
indice = ListIobAdapters.IndexOf(prevRec);
}
// aggiungo a datasource, se indice -1 aggiungendo e basta, altrimenti alla posizione richiesta...
if (indice == -1)
{
ListIobAdapters.Add(newIob);
}
else
{
// rimuovo il vecchio
ListIobAdapters.RemoveAt(indice);
// inserisco il nuovo...
ListIobAdapters.Insert(indice, newIob);
}
sw.Stop();
Log.Info($"Avviato child process per {codIob} | pid: {p.Id} | {sw.ElapsedMilliseconds}ms");
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in startChildProc | codIOB: {codIob} | tgtName: {tgtName}{Environment.NewLine}{exc}");
}
}
#endregion Public Methods
#region Protected Fields
/// <summary>
/// elenco item da rimuovere x check andato male...
/// </summary>
protected static List<IobAdapt> item2rem = new List<IobAdapt>();
/// <summary>
/// Dataora prossima scadenza riavvio automatico
/// </summary>
protected DateTime _VetoAutoCheck = DateTime.Now;
protected string ConfDirBase = "";
protected List<string> currIobType = new List<string>();
protected string DeviceName = "";
protected int numProcConfig;
protected int numProcRunning;
protected int numProcStarted;
protected int numTypeConfig;
#endregion Protected Fields
#region Protected Properties
protected AppSettings currAppConf { get; set; } = new AppSettings();
protected AppSettings CurrAppConf
{
get => currAppConf;
}
protected IobManConfig currIobConf { get; set; } = new IobManConfig();
protected SubLicManager SubLicManager { get; set; } = new SubLicManager();
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Helper copia directory + contenuto
/// </summary>
/// <param name="sourceDir"></param>
/// <param name="destDir"></param>
protected void CopyDirectory(string sourceDir, string destDir)
{
// Create the destination directory if it doesn't exist
if (!Directory.Exists(destDir))
{
Directory.CreateDirectory(destDir);
}
// copio SOLO SE ho la dir di partenza
if (Directory.Exists(sourceDir))
{
// Copy all files
foreach (var file in Directory.GetFiles(sourceDir))
{
string destFile = Path.Combine(destDir, Path.GetFileName(file));
File.Copy(file, destFile, true);
}
// Copy all subdirectories
foreach (var dir in Directory.GetDirectories(sourceDir))
{
string destSubDir = Path.Combine(destDir, Path.GetFileName(dir));
CopyDirectory(dir, destSubDir);
}
}
}
#endregion Protected Methods
#region Private Fields
/// <summary>
/// Classe logger
/// </summary>
private static Logger Log = LogManager.GetCurrentClassLogger();
private string AppConfName = "appsettings.json";
private string confDirIob = "";
/// <summary>
/// Path file di conf Applicazione
/// </summary>
private string ConfPathApp = "";
/// <summary>
/// Path file di conf IobAdaptConf
/// </summary>
private string ConfPathIob = "";
/// <summary>
/// semaforo impegno in fase avvio/chiusura...
/// </summary>
private bool isBusy = false;
private LogLevelIob logLevel = LogLevelIob.Info;
private int minDelayrestart = 30;
/// <summary>
/// Valore massimo ammesso refresh millisecondi
/// </summary>
private int refPMax = 10000;
/// <summary>
/// Valore minimo ammesso refresh millisecondi
/// </summary>
private int refPMin = 100;
/// <summary>
/// Dizionario applicazioni target da lanciare
/// </summary>
private Dictionary<string, TargetConfig> TargetIobList = new Dictionary<string, TargetConfig>();
/// <summary>
/// Ms di attesa x uscita processo (std)
/// </summary>
private int waitForExitMsec = 250;
#endregion Private Fields
#region Private Properties
private bool cloudCallActive { get; set; } = false;
private string CodImpiego { get; set; } = "";
/// <summary>
/// multiplexer Redis
/// </summary>
private ConnectionMultiplexer redisConn { get; set; } = null!;
#endregion Private Properties
#region Private Methods
private bool checkIstance(IobAdapt item, List<Process> processList)
{
bool needRem = false;
if (!isBusy)
{
// verifico se non sia già stato segnato x rimozione...)
if (item2rem.Find(x => x != null && x.pID == item.pID) != null)
{
needRem = true;
}
else
{
// verifico se esista il processo...
try
{
if (processList.Count > 0)
{
Process p = processList.FirstOrDefault(pr => pr.Id == item.pID);
if (p != null)
{
needRem = p.HasExited;
}
else
{
needRem = true;
}
}
else
{
needRem = true;
}
}
catch
{
needRem = true;
}
if (needRem)
{
if (!item2rem.Contains(item))
{
item2rem.Add(item);
}
item.isRunning = false;
}
else
{
item.isRunning = true;
}
}
}
return needRem;
}
/// <summary>
/// Verifica se i proc child siano ancora in RUN
/// </summary>
private void CheckRunningchild()
{
bool needRem = false;
if (!isBusy)
{
// solo se ho qualocsa...
if (TargetIobList.Count > 0 && ListIobAdapters.Count > 0)
{
ConcurrentBag<Process> concList = new ConcurrentBag<Process>();
// effettua ricerca 1 proc alla volta
bool checkSingle = false;
if (checkSingle)
{
// 2024.12.16 chiamata parallela controllo processi
// chiamo in parallelo la ricerca di tutti i TIPI di EXE gestiti...
Parallel.ForEach(TargetIobList, item =>
{
// 2020.02.01 passato chiamata specifica x leggere in 1 sola volta elenco processi da nome
var tempProcList = Process.GetProcessesByName(item.Key);
foreach (var sProc in tempProcList)
{
concList.Add(sProc);
}
}
);
}
else
{
// 2025.06.04 recupero tutti i processi in un colpo solo
var allProcList = Process.GetProcesses();
// ...poi chiamata parallela controllo processi da tutti i TIPI di EXE gestiti...
Parallel.ForEach(TargetIobList, item =>
{
// ricerco x nome della targetlist...
var tempProcList = allProcList.Where(x => x.ProcessName == item.Key).ToList();
foreach (var sProc in tempProcList)
{
concList.Add(sProc);
}
}
);
// ciclo
Parallel.ForEach(ListIobAdapters, item =>
{
needRem = checkIstance(item, concList.ToList());
}
);
}
}
}
UpdateCounters();
}
/// <summary>
/// Elimina contenuto directory
/// </summary>
/// <param name="directoryPath"></param>
private void DeleteDirectoryContents(string directoryPath)
{
// recupero info dir
DirectoryInfo directory = new DirectoryInfo(directoryPath);
// elimina file
foreach (FileInfo file in directory.GetFiles())
{
file.Delete();
}
// elimina ulteriori directory
foreach (DirectoryInfo subDirectory in directory.GetDirectories())
{
subDirectory.Delete(true);
}
}
private void DoSetupRedis()
{
string redisConnStr = currAppConf.Redis;
redisConn = ConnectionMultiplexer.Connect(redisConnStr);
}
/// <summary>
/// Verifica target richiesti e configurati, con sistemazione file conf x mancanti eventuali...
/// </summary>
private void FixMissingTargets()
{
bool needWrite = false;
string baseArgs = currAppConf.GetKVP("BaseArgs");
// verifico tutti i target IOB...
foreach (var sIob in currIobConf.ListIOB)
{
// se mancasse il target lo aggiungo...
if (!TargetIobList.ContainsKey(sIob.Value))
{
// prendo il primo target list
var sTarget = TargetIobList.FirstOrDefault();
// ...e sostituisco...
TargetConfig defTgt = new TargetConfig()
{
ExeName = sIob.Value,
ExePath = sTarget.Value.ExePath.Replace(sTarget.Key, sIob.Value),
LogDir = sTarget.Value.LogDir.Replace(sTarget.Key, sIob.Value),
ConfDir = sTarget.Value.ConfDir.Replace(sTarget.Key, sIob.Value),
NLogPath = sTarget.Value.NLogPath.Replace(sTarget.Key, sIob.Value),
BaseArgs = baseArgs
};
TargetIobList.Add(sIob.Value, defTgt);
needWrite = true;
}
}
// 2025.01.08: salvo il file aggiornato...
if (needWrite)
{
RewriteConfFile();
}
}
/// <summary>
/// Effettua un force kill dato nome processo
/// </summary>
/// <param name="nomeProc"></param>
private void ForceKillByName(string nomeProc)
{
Process[] stillRunningProc = Process.GetProcessesByName(nomeProc);
if (stillRunningProc != null)
{
if (stillRunningProc.Length > 0)
{
foreach (var item in stillRunningProc)
{
try
{
Process p = Process.GetProcessById(item.Id);
{
if (!p.HasExited)
{
int closeWaitTime = waitForExitMsec * 8;
// se è MAN --> aspetto + a lungo...
if (nomeProc.Contains("IOB-MAN"))
{
closeWaitTime = closeWaitTime * 4;
}
p.CloseMainWindow();
p.WaitForExit(closeWaitTime);
}
if (!p.HasExited)
{
Log.Error($"Process not Exited, 2nd try p.kill()");
p.Kill();
p.WaitForExit(waitForExitMsec);
}
if (!p.HasExited)
{
Log.Error($"Process not Killed, 3nd try p.kill()");
p.Kill();
p.WaitForExit(waitForExitMsec * 2);
}
if (!p.HasExited)
{
Log.Error($"Process not Killed, 4th try p.kill()");
p.Kill();
}
}
}
catch (Exception exc)
{
Log.Error($"Errore in fase di kill processo da nome {exc}");
}
}
}
}
}
/// <summary>
/// Effettua chiusura processo da pID
/// </summary>
/// <param name="pID"></param>
private void ForceKillByPID(int pID)
{
try
{
int numTry = 5;
Process p = Process.GetProcessById(pID);
if (p != null && p.Responding)
{
p.WaitForExit(waitForExitMsec);
p.CloseMainWindow();
while (numTry > 0 && !p.HasExited && p.Responding)
{
Log.Info($"Process {p.Id} not exited, waiting for {waitForExitMsec}ms");
p.WaitForExit(waitForExitMsec);
numTry--;
//p = Process.GetProcessById(pID);
}
p = Process.GetProcessById(pID);
if (!p.HasExited && p.Responding)
{
Log.Error($"Process {p.Id} not exited, now calling p.Kill()");
p.Kill();
}
else
{
Log.Info($"Process {p.Id} closed");
}
}
}
catch (Exception exc)
{
Log.Error($"Errore in fase di chiusura processo (pid: {pID} ) da elenco{Environment.NewLine}{exc}");
}
}
/// <summary>
/// Esecuzione init configurazione + restart globale (se richiesto)
/// </summary>
/// <param name="startProc"></param>
private void LoadConfAndStart(bool startProc)
{
try
{
string startDir = Path.GetDirectoryName(AppContext.BaseDirectory)!;
Log.Trace($"LoadConfAndStart starting | startDir: {startDir} | target Framework: {AppContext.TargetFrameworkName}");
ConfDirBase = startDir;
// init configurazioni
DoReloadConfig();
// init servizio Redis monitoring
DoSetupRedis();
Log.Trace($"Config setup done | ConfPathApp: {ConfPathApp} | ConfPathIob: {ConfPathIob}");
// sistemo log a INFO
SetIobLogLevel("INFO");
Log.Trace($"Log set to INFO");
if (startProc)
{
// avvio i processi...
DoOpenAllChild();
Log.Trace($"Child Opened");
// avvio timers e schedulazioni varie
StartScheduler();
}
}
catch (Exception exc)
{
Log.Error($"Error in AppControlService.init:{Environment.NewLine}{exc}");
}
}
private void ReportConfigUpd()
{
if (EA_ConfigUpdated != null)
{
EA_ConfigUpdated?.Invoke();
}
}
/// <summary>
/// Esegue riscrittura file di conf da parametri correnti a json
/// </summary>
private void RewriteConfFile()
{
IobManConfig currIobManConf = new IobManConfig()
{
ListIOB = currIobConf.ListIOB,
ListTarget = TargetIobList
};
// serializzo e salvo file!
string jsonData = JsonConvert.SerializeObject(currIobManConf, Formatting.Indented);
File.WriteAllText(ConfPathIob, jsonData);
}
/// <summary>
/// Imposta livello log nei file di conf degli IOB tramite procedura x riscrivere il file conf di NLog
/// </summary>
/// <param name="logReq"></param>
private void SetIobLogLevel(string logReq)
{
// leggo il file loglevel in resources
string tplPath = Path.Combine(ConfDirBase, "Resources", "NLog.template.config");
string rawData = File.ReadAllText(tplPath);
// sostituzione livello minimo da selezione
rawData = rawData.Replace("{{minLevel}}", logReq);
// scrivo conf x programma IOB-MAN
string nlogFPath = Path.Combine(ConfDirBase, "NLog.config");
File.WriteAllText(nlogFPath, rawData);
// scrivo conf x SW gestiti
foreach (var item in TargetIobList)
{
if (!File.Exists(item.Value.NLogPath))
{
// verifico folder parent...
string parentDir = Path.GetDirectoryName(item.Value.NLogPath);
if (!Directory.Exists(parentDir))
{
Directory.CreateDirectory(parentDir);
}
}
File.WriteAllText(item.Value.NLogPath, rawData);
}
}
/// <summary>
/// Avvia schedulatore reboot
/// </summary>
private void StartScheduler()
{
// avvio lo schedulatore, se abilitato...
if (currAppConf.TaskData.AutoRebootEnabled)
{
var dtReq = currAppConf.TaskData.AutoRebootTSpan;
TaskSchedulerService.IntervalInMinutes(dtReq.Hours, dtReq.Minutes, currAppConf.TaskData.AutoRebootMinutes, () =>
{
LoadConfAndStart(true);
});
}
}
private void UpdateCounters()
{
numProcStarted = ListIobAdapters.Where(x => x.isRunning).Count();
numProcRunning = ListIobAdapters.Where(x => x.isRunning && x.plcOk && x.iobOnline).Count();
}
#endregion Private Methods
}
}