#region License Information /* HeuristicLab * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Principal; using System.ServiceProcess; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; using HeuristicLab.Common; using HeuristicLab.Core.Views; using HeuristicLab.MainForm; namespace HeuristicLab.Clients.Hive.SlaveCore.Views { [View("HeuristicLab Slave View")] [Content(typeof(SlaveItem), IsDefaultView = true)] public partial class SlaveView : ItemView { private SlaveDisplayStat lastSlaveDisplayStat; private const string serviceName = "HeuristicLab.Clients.Hive.SlaveCore.SlaveWindowsService"; private const UInt32 BCM_SETSHIELD = 0x160C; [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] static extern int SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam); public new SlaveItem Content { get { return (SlaveItem)base.Content; } set { if (base.Content != value) { base.Content = value; } } } public SlaveView() { InitializeComponent(); if (CheckRunAsAdmin()) { btnKill.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; btnKill.Image = HeuristicLab.Common.Resources.VSImageLibrary.BreakpointActive; } else { this.btnKill.FlatStyle = FlatStyle.System; SendMessage(btnKill.Handle, BCM_SETSHIELD, 0, (IntPtr)1); } lblSlaveState.Text = SlaveDisplayStat.NoService.ToString(); lastSlaveDisplayStat = SlaveDisplayStat.NoService; Content_SlaveDisplayStateChanged(this, new EventArgs(lastSlaveDisplayStat)); } #region Register Content Events protected override void DeregisterContentEvents() { Content.SlaveShutdown -= new System.EventHandler(Content_SlaveShutdown); Content.SlaveStatusChanged -= new System.EventHandler>(Content_SlaveStatusChanged); Content.SlaveDisplayStateChanged -= new EventHandler>(Content_SlaveDisplayStateChanged); Content.CoreConnectionChanged -= new EventHandler>(Content_CoreConnectionChanged); base.DeregisterContentEvents(); } protected override void RegisterContentEvents() { base.RegisterContentEvents(); Content.SlaveShutdown += new System.EventHandler(Content_SlaveShutdown); Content.SlaveStatusChanged += new System.EventHandler>(Content_SlaveStatusChanged); Content.SlaveDisplayStateChanged += new EventHandler>(Content_SlaveDisplayStateChanged); Content.CoreConnectionChanged += new EventHandler>(Content_CoreConnectionChanged); } #endregion protected override void OnContentChanged() { base.OnContentChanged(); btnKill.Enabled = false; btnStart.Enabled = false; btnStop.Enabled = false; if (Content == null) { //nothing to do... } else { //try to establish a connection to the slave service if (base.Content != null) { ((SlaveItem)base.Content).Open(); Task.Factory.StartNew(Connector); } } } private void Connector() { Content_SlaveDisplayStateChanged(this, new EventArgs(SlaveDisplayStat.NoService)); bool connected = false; while (!connected) { this.Invoke(new Func(() => connected = ((SlaveItem)base.Content).ReconnectToSlaveCore())); if (!connected) { Thread.Sleep(1000); } } this.Invoke(new Action(SetEnabledStateOfControls)); } protected override void SetEnabledStateOfControls() { base.SetEnabledStateOfControls(); //do nothing at the moment, we have nothing editable } #region Event Handlers void Content_SlaveStatusChanged(object sender, EventArgs e) { RenderJobChart(e.Value); RenderCoreChart(e.Value); } void Content_SlaveShutdown(object sender, System.EventArgs e) { Task.Factory.StartNew(Connector); } void Content_SlaveDisplayStateChanged(object sender, EventArgs e) { lblSlaveState.Text = e.Value.ToString(); lastSlaveDisplayStat = e.Value; if (e.Value == SlaveDisplayStat.Asleep || e.Value == SlaveDisplayStat.NoService) { btnKill.Enabled = false; btnStart.Enabled = true; btnStop.Enabled = false; } if (e.Value == SlaveDisplayStat.Busy || e.Value == SlaveDisplayStat.Idle || e.Value == SlaveDisplayStat.Offline) { btnKill.Enabled = true; btnStart.Enabled = false; btnStop.Enabled = true; } } void Content_CoreConnectionChanged(object sender, EventArgs e) { if (e.Value == CoreConnection.Offline) { btnKill.Enabled = false; btnStart.Enabled = false; btnStop.Enabled = false; } } #endregion private void RenderJobChart(StatusCommons status) { jobChart.Series[0].Points.Clear(); jobChart.Series[1].Points.Clear(); jobChart.Series[2].Points.Clear(); jobChart.Series[3].Points.Clear(); jobChart.Series[4].Points.Clear(); DataPoint pJobs = new DataPoint(1, status.Jobs.Count); DataPoint pJobsAborted = new DataPoint(2, status.JobsAborted); DataPoint pJobsDone = new DataPoint(3, status.JobsFinished); DataPoint pJobsFetched = new DataPoint(4, status.JobsFetched); DataPoint pJobsFailed = new DataPoint(5, status.JobsFailed); pJobs.LegendText = "Current jobs: " + status.Jobs.Count; pJobs.Color = System.Drawing.Color.Yellow; pJobs.ToolTip = pJobs.LegendText; jobChart.Series[0].Color = System.Drawing.Color.Yellow; jobChart.Series[0].LegendText = pJobs.LegendText; jobChart.Series[0].Points.Add(pJobs); pJobsAborted.LegendText = "Aborted jobs: " + status.JobsAborted; pJobsAborted.Color = System.Drawing.Color.Orange; pJobsAborted.ToolTip = pJobsAborted.LegendText; jobChart.Series[1].Color = System.Drawing.Color.Orange; jobChart.Series[1].LegendText = pJobsAborted.LegendText; jobChart.Series[1].Points.Add(pJobsAborted); pJobsDone.LegendText = "Finished jobs: " + status.JobsFinished; pJobsDone.Color = System.Drawing.Color.Green; pJobsDone.ToolTip = pJobsDone.LegendText; jobChart.Series[2].Color = System.Drawing.Color.Green; jobChart.Series[2].LegendText = pJobsDone.LegendText; jobChart.Series[2].Points.Add(pJobsDone); pJobsFetched.LegendText = "Fetched jobs: " + status.JobsFetched; pJobsFetched.ToolTip = pJobsFetched.LegendText; pJobsFetched.Color = System.Drawing.Color.Blue; jobChart.Series[3].Color = System.Drawing.Color.Blue; jobChart.Series[3].LegendText = pJobsFetched.LegendText; jobChart.Series[3].Points.Add(pJobsFetched); pJobsFailed.LegendText = "Failed jobs: " + status.JobsFailed; pJobsFailed.ToolTip = pJobsFailed.LegendText; pJobsFailed.Color = System.Drawing.Color.Red; jobChart.Series[4].Color = System.Drawing.Color.Red; jobChart.Series[4].LegendText = pJobsFailed.LegendText; jobChart.Series[4].Points.Add(pJobsFailed); } private void RenderCoreChart(StatusCommons statusCommons) { int usedCores = statusCommons.TotalCores - statusCommons.FreeCores; DataPoint pFreeCores = new DataPoint(statusCommons.FreeCores, statusCommons.FreeCores); DataPoint pUsedCores = new DataPoint(usedCores, usedCores); coresChart.Series[0].Points.Clear(); pFreeCores.LegendText = "Free cores: " + statusCommons.FreeCores; pFreeCores.Color = System.Drawing.Color.Green; pUsedCores.LegendText = "Used cores: " + usedCores; pUsedCores.Color = System.Drawing.Color.Red; coresChart.Series[0].Points.Add(pFreeCores); coresChart.Series[0].Points.Add(pUsedCores); } private bool CheckRunAsAdmin() { bool isRunAsAdmin = false; WindowsIdentity user = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(user); try { isRunAsAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator); } catch { } return isRunAsAdmin; } /// /// Shows the windows UAC dialog and restarts tray icon app /// private void ElevateApplication() { // launch itself as administrator ProcessStartInfo proc = new ProcessStartInfo(Application.ExecutablePath, "showui"); proc.UseShellExecute = true; proc.WorkingDirectory = Environment.CurrentDirectory; proc.FileName = Application.ExecutablePath; proc.Verb = "runas"; try { Process.Start(proc); } catch { // user refused to allow privileges elevation return; } Application.Exit(); } private void StartService() { TimeSpan timeout = TimeSpan.FromMilliseconds(5000); ServiceController service = new ServiceController(serviceName); try { if (service.Status == ServiceControllerStatus.Running) { service.Stop(); service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); } service.Start(); service.WaitForStatus(ServiceControllerStatus.Running, timeout); } catch (InvalidOperationException ex) { MessageBox.Show("Error starting service: Hive Slave Service not found!" + Environment.NewLine + ex.ToString()); } catch (Exception ex) { MessageBox.Show("Error starting service, exception is: " + Environment.NewLine + ex.ToString()); } } private void StopService() { TimeSpan timeout = TimeSpan.FromMilliseconds(7000); ServiceController service = new ServiceController(serviceName); try { if (service.Status == ServiceControllerStatus.Running) { service.Stop(); service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); } } catch (InvalidOperationException ex) { MessageBox.Show("Error starting service: Hive Slave Service not found!" + Environment.NewLine + ex.ToString()); } catch (Exception ex) { MessageBox.Show("Error starting service, exception is: " + Environment.NewLine + ex.ToString()); } } private void btnKill_Click(object sender, EventArgs e) { if (CheckRunAsAdmin()) { StopService(); } else { ElevateApplication(); } } private void btnStop_Click(object sender, EventArgs e) { if (Content != null) { Content.Sleep(); } } private void btnStart_Click(object sender, EventArgs e) { if (Content != null) { if (lastSlaveDisplayStat == SlaveDisplayStat.Asleep) { Content.RestartCore(); } else if (lastSlaveDisplayStat == SlaveDisplayStat.NoService) { if (CheckRunAsAdmin()) { StartService(); } else { ElevateApplication(); } } } } } }