using System; using System.Collections.Generic; using System.Diagnostics; 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 ceh va a zero faccio vero check) /// protected int chekMult = utils.CRI("chekMult"); /// /// 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 = ""; public IOBManPanel() { InitializeComponent(); myInit(); updateStatus(); } private void myInit() { utils.lgInfo("Starting App"); // 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 = utils.CRI("checkPeriod"); loadConfig(); MainTimer.Start(); utils.lgInfo("Timer started"); } 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}"); 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); } } } 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}"; // 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; } else { tsslNumProc.ForeColor = System.Drawing.Color.OrangeRed; } } /// /// Apro un child x ogni args specificato /// private void apriChild() { //Process childProc = new Process(); ProcessStartInfo psi = null; foreach (var item in ArgsList) { // da testare x aprire chiudere risorsa... psi = new ProcessStartInfo { FileName = TargetExe, Arguments = $"{utils.CRS("BaseArg")}{item}", WindowStyle = ProcessWindowStyle.Minimized }; //childProc.StartInfo = psi; Process p = Process.Start(psi); // accodo nuovo IOB... iobAdapt newIob = new iobAdapt(); DateTime adesso = DateTime.Now; newIob.CodIOB = item; newIob.startTime = adesso; newIob.pID = p.Id; newIob.isRunning = true; // aggiungo a datasource ElencoIOB.Add(newIob); utils.lgInfo($"Avviato child process per {item} | pid: {p.Id}"); } numProcAvviati = ArgsList.Count; numProcRunning = numProcAvviati; } /// /// 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"); // 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 ho da riavviare... elimino! foreach (var item in proc2restart) { ElencoIOB.Remove(item); utils.lgInfo($"Chiusura processo non running | IOB: {item.CodIOB} | pid: {item.pID}"); } // gestisco processi chiusi ProcessStartInfo psi = null; // li faccio ripartire! foreach (var item in proc2restart) { // da testare x aprire chiudere risorsa... psi = new ProcessStartInfo { FileName = TargetExe, Arguments = item.CodIOB, WindowStyle = ProcessWindowStyle.Minimized }; //childProc.StartInfo = psi; Process p = Process.Start(psi); // accodo nuovo IOB... iobAdapt newIob = new iobAdapt(); DateTime adesso = DateTime.Now; newIob.CodIOB = item.CodIOB; newIob.startTime = adesso; newIob.pID = p.Id; newIob.isRunning = true; // aggiungo a datasource ElencoIOB.Add(newIob); utils.lgInfo($"Riavvio processo | IOB: {newIob.CodIOB} | pid: {newIob.pID}"); } // aggiorno datagrid! dgvManagedItems.Invalidate(); } } /// /// 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(); } private void closeAllChild() { 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(); ElencoIOB.Remove(item); } 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) { Process p = Process.GetProcessById(item.Id); p.CloseMainWindow(); p.Kill(); } } // 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 chiusura + update status... /// /// /// private void closeALLToolStripMenuItem_Click(object sender, EventArgs e) { closeAllChild(); updateStatus(); } /// /// Chiama Restart (close/start) + update status... /// /// /// private void restartALLToolStripMenuItem_Click(object sender, EventArgs e) { // chiude tutto closeAllChild(); apriChild(); updateStatus(); } private void loadConfToolStripMenuItem_Click(object sender, EventArgs e) { // per iscurezza chiudo tutto closeAllChild(); Thread.Sleep(1000); // lettura conf file... loadConfig(); // apertura apriChild(); updateStatus(); } private void updateModeToolStripMenuItem_Click(object sender, EventArgs e) { // chiude tutte closeAllChild(); 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(); //apriChild(); updateStatus(); } private void btnRestartAll_Click(object sender, EventArgs e) { // chiude tutto closeAllChild(); apriChild(); updateStatus(); } private void btnOpenAll_Click(object sender, EventArgs e) { // per iscurezza chiudo tutto closeAllChild(); Thread.Sleep(1000); // lettura conf file... loadConfig(); // apertura apriChild(); updateStatus(); } private void updateIOBMANToolStripMenuItem_Click(object sender, EventArgs e) { // FIXME fare come IOB-WIN! } private void updateIOBWINToolStripMenuItem_Click(object sender, EventArgs e) { // chiude tutte closeAllChild(); Thread.Sleep(1000); updateStatus(); // apre solo 1 con conf "fake" x condurre update... apriOneUpdate(); } } }