using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Configuration; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; namespace IOB_MAN { public partial class IOBManPanel : Form { #region area gestione hode/max finestre private const int SW_SHOWNORMAL = 1; private const int SW_SHOWMINIMIZED = 2; private const int SW_SHOWMAXIMIZED = 3; [DllImport("user32.dll")] private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); #endregion /// /// Totale processi avviati /// protected int numProcAvviati; /// /// Totale processi running /// protected int numProcRunning; /// /// Counter per verifica watchdog dei processi da riattivare... /// protected int watchDogMult = utils.CRI("watchDogMult"); /// /// Counter per verifica processi (ogni volta che va a zero faccio vero check) /// protected int chekMult = utils.CRI("chekMult"); /// /// Counter del timer di base /// protected int checkPeriod = utils.CRI("checkPeriod"); /// /// Elenco ARGS (uno per child da avviare) /// public List ArgsList = new List(); /// /// Binding source degli elementi gestiti.. /// private BindingSource ElencoIOB = new BindingSource(); /// /// Path dell'exe da chiamare /// protected string TargetExe = ""; /// /// Contatore autockeck nativo /// protected int tOutAutocheck = 100; public IOBManPanel() { InitializeComponent(); myInit(); updateStatus(); } private void myInit() { utils.lgInfo("Starting App"); lblApp.Text = $"{ConfigurationManager.AppSettings.Get("appName")}"; lblVers.Text = string.Format(" v.{0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); // init prog bar tsProgBar.Maximum = 100; tsProgBar.Step = 1; // gestione eventi binding source ElencoIOB.AddingNew += ElencoIOB_AddingNew; ElencoIOB.ListChanged += ElencoIOB_ListChanged; // colelgo tab a binding dgvManagedItems.DataSource = ElencoIOB; MainTimer.Interval = checkPeriod; loadConfig(); MainTimer.Start(); utils.lgInfo("Timer started"); if (utils.CRB("autoStartProc")) { apriChild(); utils.lgInfo("Start processi effettuato"); } } /// /// Caricamento configurazione /// private void loadConfig() { ArgsList.Clear(); TargetExe = utils.CRS("targetExe"); if (string.IsNullOrEmpty(TargetExe)) { TargetExe = string.Format(@"{0}\Resources\Test.bat", Application.StartupPath); } utils.lgInfo($"Target exe: {TargetExe}"); // caricamento configurazione argomenti di avvio processi loadArgList(); } private void loadArgList() { // in primis cerco SE ESISTA il file json di configuraizone parametri avvio string fileName = utils.CRS("ArgsConfFile"); string jsonFileName = $"{Application.StartupPath}{fileName}"; // verifico se esista il file richeisto if (File.Exists(jsonFileName)) { // leggo il file json StreamReader reader = new StreamReader(jsonFileName); string jsonData = reader.ReadToEnd(); if (!string.IsNullOrEmpty(jsonData)) { ArgsList = JsonConvert.DeserializeObject>(jsonData); } } else { // se non lo trovassi --> uso la chaive in web.config e GENERO un nuovo file x prox avvio... string ArgsString = utils.CRS("ArgsList"); utils.lgInfo($"Args found: {ArgsString}"); if (string.IsNullOrEmpty(ArgsString)) { var rand = new Random(); // ne creo rand (5-15) di default... for (int i = 0; i < rand.Next(5, 10); i++) { ArgsList.Add("127.0.0.1"); } } else { var elenco = ArgsString.Split(','); foreach (var item in elenco) { ArgsList.Add(item); } } // serializzo e salvo file! string jsonData = JsonConvert.SerializeObject(ArgsList); File.WriteAllText(jsonFileName, jsonData); } } private void ElencoIOB_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e) { updateStatus(); } private void ElencoIOB_AddingNew(object sender, System.ComponentModel.AddingNewEventArgs e) { updateStatus(); } private void updateStatus() { // aggiorno labels tsslNumProc.Text = $"Configurati {ArgsList.Count} processi | Avviati: {numProcAvviati} | Attivi: {numProcRunning}"; bool hlRestart = false; // colore da num proc... if (numProcRunning == ArgsList.Count) { tsslNumProc.ForeColor = System.Drawing.Color.Green; } else if (numProcAvviati < ArgsList.Count) { tsslNumProc.ForeColor = System.Drawing.Color.DarkRed; hlRestart = true; } else { tsslNumProc.ForeColor = System.Drawing.Color.OrangeRed; hlRestart = true; } // fix autorestart... if (hlRestart) { chkAutoRestart.ForeColor = System.Drawing.Color.Red; chkAutoRestart.Text = "Auto Restart!!!"; txtTOutAutoCheck.Visible = true; btnMoreTOut.Visible = true; // se NON checked aggiorno contatore... if (!chkAutoRestart.Checked) { tOutAutocheck--; txtTOutAutoCheck.Text = (tOutAutocheck / (1000 / (utils.CRI("checkPeriod") * utils.CRI("chekMult")))).ToString(); } } else { chkAutoRestart.ForeColor = DefaultForeColor; chkAutoRestart.Text = "Auto Restart"; txtTOutAutoCheck.Visible = false; btnMoreTOut.Visible = false; } } /// /// Apro un child x ogni args specificato /// private void apriChild() { // preventivamente CHIUDO TUTTO closeAllChild(true); Thread.Sleep(250); // avvio i child foreach (var item in ArgsList) { startChildProc(item); } numProcAvviati = ArgsList.Count; numProcRunning = numProcAvviati; } /// /// Avvio di un child process da parametro ARG /// /// private void startChildProc(string procArg) { ProcessStartInfo psi = null; // da testare x aprire chiudere risorsa... psi = new ProcessStartInfo { FileName = TargetExe, Arguments = $"{utils.CRS("BaseArg")}{procArg}", WindowStyle = ProcessWindowStyle.Minimized }; //childProc.StartInfo = psi; Process p = Process.Start(psi); // accodo nuovo IOB... iobAdapt newIob = new iobAdapt(); DateTime adesso = DateTime.Now; newIob.CodIOB = procArg; newIob.startTime = adesso; newIob.pID = p.Id; newIob.isRunning = true; // aggiungo a datasource ElencoIOB.Add(newIob); utils.lgInfo($"Avviato child process per {procArg} | pid: {p.Id}"); } /// /// Apro un child x fare udpate con parametro che impedisca avvio IOB /// private void apriOneUpdate() { ProcessStartInfo psi = null; // da testare x aprire chiudere risorsa... psi = new ProcessStartInfo { FileName = TargetExe, Arguments = "MODE=UPD IOB=NONE", WindowStyle = ProcessWindowStyle.Normal }; // avvio processo con using... using (Process p = Process.Start(psi)) { p.WaitForExit(); // ora chiudo current... SE configurato if (utils.CRB("closeOnChildUpdate")) { this.Close(); } } } /// /// Chiudo primo processo child (se ce ne sono) /// /// /// private void btnClose_Click(object sender, EventArgs e) { chiudiChild(); updateStatus(); } private void chiudiChild() { int pid = -1; // SOLO SE selezionato in dgv... if (dgvManagedItems.SelectedRows.Count > 0) { foreach (DataGridViewRow riga in dgvManagedItems.SelectedRows) { // chiudo! int.TryParse(riga.Cells["pID"].Value.ToString(), out pid); if (pid >= 0) { // provo a vedere SE ci sia il processo e di conseguenza lo chiudo... try { Process p = Process.GetProcessById(pid); // cerco e chiudo quelli che mi interessano... p.CloseMainWindow(); } catch { // errore era già chiuso.. } // indico NON running su datasource ((iobAdapt)ElencoIOB[riga.Index]).isRunning = false; } } } updateStatus(); } /// /// Cerca nell'elenco il processo corrente /// /// /// /// public Process myGetProcByID(Process[] processlist, int id) { return processlist.FirstOrDefault(pr => pr.Id == id); } /// /// Effettua tutte le verifiche periodiche a timer... /// /// /// private void MainTimer_Tick(object sender, EventArgs e) { updateProgBar(); chekProcessStatus(); checkWatchdog(); } /// /// Controllo periodico dei processi DA RIATTIVARE /// private void checkWatchdog() { watchDogMult--; if (watchDogMult < 0) { watchDogMult = utils.CRI("watchDogMult"); processAutoRestart(); // aggiorno datagrid! dgvManagedItems.Invalidate(); } } /// /// Effettua processing autorestart /// private void processAutoRestart() { // verifico se ci siano processi (da ARGS LIST) NON running --> li riavvio! List proc2restart = new List(); foreach (iobAdapt item in ElencoIOB.List) { if (!item.isRunning) { // segno da eliminare e riavviare proc2restart.Add(item); } } // SE abilitato autorestart... if (chkAutoRestart.Checked) { // se ho da riavviare... elimino! foreach (var item in proc2restart) { ElencoIOB.Remove(item); utils.lgInfo($"Chiusura processo non running | IOB: {item.CodIOB} | pid: {item.pID}"); } // li faccio ripartire! foreach (var item in proc2restart) { startChildProc(item.CodIOB); } } else { // se autorestart scaduto e NON checked --> lo imposto if (tOutAutocheck < 0) { // lo riattivo chkAutoRestart.Checked = true; } } } /// /// Controllo periodico dei processi attivi /// private void chekProcessStatus() { chekMult--; if (chekMult < 0) { chekMult = utils.CRI("chekMult"); checkRunningchild(); updateStatus(); } } private void updateProgBar() { tsProgBar.PerformStep(); if (tsProgBar.Value >= tsProgBar.Maximum) { tsProgBar.Value = 0; } } /// /// Verifica se i proc child siano ancora in RUN /// private void checkRunningchild() { List item2rem = new List(); bool needRem = false; numProcRunning = numProcAvviati; // leggo 1 sola volta TUTTO elenco processi... Process[] processList = Process.GetProcesses(); foreach (iobAdapt item in ElencoIOB.List) { // verifico se esista il processo... try { Process p = myGetProcByID(processList, item.pID); needRem = p.HasExited; } catch { needRem = true; } if (needRem) { item2rem.Add(item); item.isRunning = false; numProcRunning--; } else { item.isRunning = true; } } // aggiorno datagrid! dgvManagedItems.Invalidate(); updateStatus(); } private void IOBManPanel_FormClosing(object sender, FormClosingEventArgs e) { closeAllChild(true); Thread.Sleep(500); closeAllChild(true); } /// /// Chiude tutti i child /// /// resetta elenco private void closeAllChild(bool doReset) { List item2rem = new List(); foreach (iobAdapt item in ElencoIOB.List) { item2rem.Add(item); } // processod a elenco noto foreach (var item in item2rem) { if (item.isRunning) { try { Process p = Process.GetProcessById(item.pID); p.CloseMainWindow(); // indico NON running su datasource if (doReset) { ElencoIOB.Remove(item); } else { item.isRunning = false; } } catch { } } } // per sicurezza CERCO i processi x nome... string nomeProc = Path.GetFileName(TargetExe).Replace(".exe", ""); var stillRunningProc = Process.GetProcessesByName(nomeProc); if (stillRunningProc != null) { foreach (var item in stillRunningProc) { try { Process p = Process.GetProcessById(item.Id); p.CloseMainWindow(); p.WaitForExit(250); if (!p.HasExited) { utils.lgError($"Process not exited, now calling p.Close()"); p.Close(); } p.WaitForExit(250); if (!p.HasExited) { utils.lgError($"Process not exited, now calling p.Kill()"); p.Kill(); } } catch { } } } if (doReset) { // resetto elenco! ElencoIOB.Clear(); numProcAvviati = 0; } numProcRunning = 0; // update! updateStatus(); } private void dgvManagedItems_SelectionChanged(object sender, EventArgs e) { checkButtons(); } /// /// verifica buttons attivi data selezione su gridview... /// private void checkButtons() { bool selected = (dgvManagedItems.SelectedRows.Count > 0); btnClose.Enabled = selected; } private void dgvManagedItems_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { // seleziono riga... int pid = -1; if (e.RowIndex >= 0) { //dgvManagedItems.CurrentCell = dgvManagedItems.Rows[e.RowIndex].Cells[0]; dgvManagedItems.Rows[e.RowIndex].Selected = true; using (var riga = dgvManagedItems.Rows[e.RowIndex]) { int.TryParse(riga.Cells["pID"].Value.ToString(), out pid); if (pid >= 0) { // provo a vedere SE ci sia il processo e di conseguenza lo chiudo... try { Process p = Process.GetProcessById(pid); // cerco e chiudo quelli che mi interessano... var windowsHandle = p.MainWindowHandle; ShowWindowAsync(windowsHandle, SW_SHOWNORMAL); } catch { // errore era già chiuso.. } } } } } private void btnMinimizeAll_Click(object sender, EventArgs e) { foreach (iobAdapt item in ElencoIOB.List) { if (item.isRunning) { try { Process p = Process.GetProcessById(item.pID); // cerco e chiudo quelli che mi interessano... var windowsHandle = p.MainWindowHandle; ShowWindowAsync(windowsHandle, SW_SHOWMINIMIZED); } catch (Exception exc) { // errore era già chiuso.. utils.lgError($"Errore in HIDE windows:{Environment.NewLine}{exc}"); } } } } private void btnMaximixeAll_Click(object sender, EventArgs e) { foreach (iobAdapt item in ElencoIOB.List) { if (item.isRunning) { try { Process p = Process.GetProcessById(item.pID); // cerco e chiudo quelli che mi interessano... var windowsHandle = p.MainWindowHandle; ShowWindowAsync(windowsHandle, SW_SHOWNORMAL); } catch (Exception exc) { // errore era già chiuso.. utils.lgError($"Errore in SHOW windows:{Environment.NewLine}{exc}"); } } } } /// /// Chiama apertura + update status... /// /// /// private void openALLToolStripMenuItem_Click(object sender, EventArgs e) { } /// /// Chiama Restart (close/start) + update status... /// /// /// private void restartALLToolStripMenuItem_Click(object sender, EventArgs e) { // chiude tutto closeAllChild(false); apriChild(); updateStatus(); } private void loadConfToolStripMenuItem_Click(object sender, EventArgs e) { // per iscurezza chiudo tutto closeAllChild(true); Thread.Sleep(1000); // lettura conf file... loadConfig(); // apertura apriChild(); updateStatus(); } private void updateModeToolStripMenuItem_Click(object sender, EventArgs e) { // chiude tutte closeAllChild(true); Thread.Sleep(1000); updateStatus(); // apre solo 1 con conf "fake" x condurre update... apriOneUpdate(); } private void btnCloseAll_Click(object sender, EventArgs e) { // chiude tutto closeAllChild(false); //apriChild(); updateStatus(); } private void btnRestartAll_Click(object sender, EventArgs e) { // chiude tutto closeAllChild(true); apriChild(); updateStatus(); } private void btnOpenAll_Click(object sender, EventArgs e) { // per iscurezza chiudo tutto closeAllChild(true); Thread.Sleep(1000); // lettura conf file... loadConfig(); // apertura apriChild(); updateStatus(); } /// /// Ramo applicazione (x update) /// protected string branchName = "master"; /// /// URL stringa di UPDATE... /// protected string updateUrl { get { return string.Format("http://seriate.steamware.net:8083/SWS/MAPO/IOB-MAN/{0}/manifest.xml", branchName); } } private void AutoUpdater_ApplicationExitEvent() { utils.lgInfo("Chiusura IOB-WIN"); Thread.Sleep(100); // chiudo tutto closeAllChild(true); Thread.Sleep(1000); utils.lgInfo("Chiusura Applicazione"); // attendo 1 sec... Thread.Sleep(1000); // ESCO! Application.Exit(); } private void updateIOBWINToolStripMenuItem_Click(object sender, EventArgs e) { // chiude tutte closeAllChild(true); Thread.Sleep(1000); updateStatus(); // apre solo 1 con conf "fake" x condurre update... apriOneUpdate(); } private void chkAutoRestart_CheckedChanged(object sender, EventArgs e) { // se tolgo autorestart --> imposto NUOVA scadenza x forzare check tOutAutocheck = 60 * utils.CRI("autoRestartTimeoutMin") * (1000 / (utils.CRI("checkPeriod") * utils.CRI("chekMult"))); // fa subito controllo riavvio... processAutoRestart(); } private void btnMoreTOut_Click(object sender, EventArgs e) { tOutAutocheck += 60 * utils.CRI("autoRestartTimeoutMin") * (1000 / (utils.CRI("checkPeriod") * utils.CRI("chekMult"))); } private void txtTOutAutoCheck_TextChanged(object sender, EventArgs e) { } private void forceCloseALLToolStripMenuItem_Click(object sender, EventArgs e) { // per iscurezza chiudo tutto closeAllChild(true); Thread.Sleep(1000); updateStatus(); } private void reloadConfRestartToolStripMenuItem_Click(object sender, EventArgs e) { // per iscurezza chiudo tutto closeAllChild(true); Thread.Sleep(1000); updateStatus(); // rileggo conf loadConfig(); Thread.Sleep(500); // riapro apriChild(); } private void dgvManagedItems_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { //e.CellStyle = // If the column is the Artist column, check the // value. if (this.dgvManagedItems.Columns[e.ColumnIndex].Name == "isRunning") { if (e.Value != null) { // Check for the string "pink" in the cell. bool isRunning = false; bool.TryParse(e.Value.ToString(), out isRunning); //stringValue = stringValue.ToLower(); if (!isRunning) { e.CellStyle.ForeColor = Color.Red; DataGridViewCellStyle currstyle = dgvManagedItems[0, e.RowIndex].Style; currstyle.ForeColor = Color.Red; dgvManagedItems[1, e.RowIndex].Style = currstyle; dgvManagedItems[2, e.RowIndex].Style = currstyle; dgvManagedItems[3, e.RowIndex].Style = currstyle; } } } } } }