|
|
using System;
using System.Windows.Forms;
namespace jMonitor
{
public partial class AddDialog : Form
{
/// <summary>
/// Add a new Computer to monitor
/// </summary>
public AddDialog()
{
InitializeComponent();
}
/// <summary>
/// get the newly added info and return it as a ComputerInfo
/// </summary>
/// <returns>ComputerInfo object</returns>
public ComputerInfo GetInfo()
{
ComputerInfo ci = new ComputerInfo(null, null, null, this.textBoxName.Text);
//set the computer name. must be before other lines so the xml entity is created
ci.ComputerName = this.textBoxName.Text;
ci.Port = Int32.Parse(this.textBoxPort.Text);
return ci;
}
/// <summary>
/// default the Port to 5000
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void AddDialog_Load(object sender, EventArgs e)
{
this.textBoxPort.Text = ComputerInfo.DefaultPort.ToString();
}
private void btnOk_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
}
}
|
|
|
using System;
using System.Collections;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
using System.Xml;
using System.IO;
using System.Data;
using System.Reflection;
namespace jMonitor
{
/// keeps all the Computer information together
/// runs the query and sets the result Control
public class ComputerInfo : CheckBox, IStateChecker, IEnumerable
{
public const int DefaultPort = 5000;
public const int DefaultRetryTimeout = 200;
public const int DefaultNumRetries = 3;
private static string mXmlPath;
private static System.Xml.XmlDataDocument mXml = null;
private string mComputerName;
private WorkerThread mWorkerThread;
private ITraceable mTracer;
private IRefreshable mRefresher;
private string mReason;
private Control mControl;
private int mRow;
public static string GetXmlPath()
{
if (mXmlPath == null)
{
mXmlPath = Directory.GetCurrentDirectory() + @"\jMonitor.xml";
}
return mXmlPath;
}
public static ArrayList GetComputers()
{
ArrayList computers = new ArrayList();
System.Xml.XmlDataDocument doc = new System.Xml.XmlDataDocument();
doc.Load(GetXmlPath());
XmlNodeList nodes = doc.SelectNodes("/ComputerList/Computer");
foreach (XmlNode node in nodes)
{
XmlNode n = node.Attributes.GetNamedItem("name");
string name = n.Value;
//Console.WriteLine("x=name='" + name + "'");
computers.Add(new ComputerInfo(null, null, null, name));
}
return computers;
}
public ComputerInfo(ITraceable t, IRefreshable i, Control c, string n)
{
if (mXml == null)
{
mXml = new System.Xml.XmlDataDocument();
mXml.Load(GetXmlPath());
}
mComputerName = n;
mTracer = t;
mRefresher = i;
mControl = c;
mReason = "";
mRow = -1;
}
public void SetUI(ITraceable t, IRefreshable i, Control c)
{
mTracer = t;
mRefresher = i;
mControl = c;
mControl.Text = "unknown";
mWorkerThread = new WorkerThread(t, this, this);
}
private int mFailureCount = 0;
private int mSuccessCount = 0;
public void Reset()
{
mFailureCount = 0;
mSuccessCount = 0;
mControl.BackColor = Color.Transparent;
mReason = "";
}
public void ConnectionFailed(string reason)
{
mControl.BackColor = Color.Red;
mReason = mReason + ((mReason == "") ? "" : "\n") + reason;
}
public void ConnectionSucceeded()
{
mControl.BackColor = Color.Blue;
mReason = mReason + ((mReason == "") ? "" : "\n") + "Connection OK";
}
public void RequestFailed(string reason)
{
mFailureCount++;
if (mSuccessCount == 0)
{
mControl.BackColor = Color.Orange;
}
else
{
mControl.BackColor = Color.Yellow;
}
mReason = mReason + ((mReason == "") ? "" : "\n") + reason + "\n";
mReason += "Succeeded: " + mSuccessCount.ToString() + " Failed: " + mFailureCount.ToString();
}
public void RequestSucceeded()
{
mSuccessCount++;
if (mFailureCount == 0)
{
mControl.BackColor = Color.Green;
}
else
{
mControl.BackColor = Color.Yellow;
}
mReason = "Succeeded: " + mSuccessCount.ToString() + " Failed: " + mFailureCount.ToString();
}
public void CheckResponse(string computer, string component, string parameter, string response)
{
bool gotit = RunAssembly(component, computer, parameter, response);
if (gotit)
{
RequestSucceeded();
}
else
{
RequestFailed("CheckResponse failed");
}
}
//---------------------------
bool RunAssembly(string name, string computer, string parameter, string response)
{
string cwd = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string path = cwd + "\\" + name + ".dll";
string title_class = name + "." + name;
string title_method = "CheckResponse";
Assembly u = Assembly.LoadFrom(path);
if (u == null)
{
throw new Exception("LoadAssemblyIntoDomain: LoadAssembly failed, returned null");
}
Type t = u.GetType(title_class);
if (t == null)
{
throw new Exception("LoadAssemblyIntoDomain: GetType failed, returned null");
}
MethodInfo m = t.GetMethod(title_method);
if (m == null)
{
throw new Exception("LoadAssemblyIntoDomain: GetMethod failed, returned null");
}
object[] myparam = new object[3];
myparam[0] = computer;
myparam[1] = parameter;
myparam[2] = response;
return (bool)m.Invoke(null, myparam);
}
public void RefreshControls()
{
mRefresher.RefreshControls(this);
}
public void Run()
{
mWorkerThread.Run();
}
public void WaitFor()
{
mWorkerThread.WaitFor();
}
public int Row
{
get { return mRow; }
set { mRow = value; }
}
//public override string ToString()
// {
// return mData.ToString();
// }
public string Reason
{
get { return mReason; }
}
public static void Save()
{
mXml.Save(GetXmlPath());
}
public void DeleteComputer()
{
XmlNode pnode = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']");
if (pnode == null)
return;
XmlNode computers = mXml.SelectSingleNode("/ComputerList");
computers.RemoveChild(pnode);
}
public string ComputerName
{
get { return mComputerName; }
set
{
//convert to lowercase and find the current element...
XmlElement computer = (XmlElement)mXml.SelectSingleNode("/ComputerList/Computer[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='" + mComputerName.ToLower() + "']");
//before setting to the new name
mComputerName = value;
if (computer == null)
{
//not there, so add it
computer = mXml.CreateElement("Computer");
computer.SetAttribute("name", mComputerName);
XmlNode computers = mXml.SelectSingleNode("/ComputerList");
//todo: check if null
computers.AppendChild(computer);
}
}
}
public string IPAddress
{
get
{
XmlNode ipnode = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/IPAddress");
if (ipnode == null)
return "";
return ipnode.InnerText;
}
set
{
XmlNode ipnode = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/IPAddress");
if (ipnode == null)
{
XmlElement ipelem = mXml.CreateElement("IPAddress");
ipelem.InnerText = value;
XmlElement computer = (XmlElement)mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']");
computer.AppendChild(ipelem);
}
else
{
ipnode.InnerText = value;
}
}
}
public Boolean UseIPAddress
{
get
{
XmlNode useipnode = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/UseIPAddress");
if (useipnode == null)
return false;
return (useipnode.InnerText == "True");
}
set
{
XmlNode useipnode = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/UseIPAddress");
if (useipnode == null)
{
XmlElement useipelem = mXml.CreateElement("UseIPAddress");
useipelem.InnerText = value.ToString();
XmlElement computer = (XmlElement)mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']");
computer.AppendChild(useipelem);
}
else
{
useipnode.InnerText = value.ToString();
}
}
}
public int Port
{
get
{
XmlNode pnode = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/Port");
if (pnode == null)
return ComputerInfo.DefaultPort;
return Int32.Parse(pnode.InnerText);
}
set
{
XmlNode pnode = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/Port");
if (pnode == null)
{
XmlElement portelem = mXml.CreateElement("Port");
portelem.InnerText = value.ToString();
XmlElement computer = (XmlElement)mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']");
computer.AppendChild(portelem);
}
else
{
pnode.InnerText = value.ToString();
}
}
}
public class ActionEnum : IEnumerator
{
DataTable table;
IEnumerator rows;
public ActionEnum(ComputerInfo ci)
{
DataSet ds = ci.ActionList;
table = ds.Tables["Action"];
rows = table.Rows.GetEnumerator();
}
public bool MoveNext()
{
return rows.MoveNext();
}
public void Reset()
{
rows.Reset();
}
public object Current
{
get
{
DataRow row = (DataRow)rows.Current;
string c = (string)row[table.Columns["Component"]];
string p = (string)row[table.Columns["Parameter"]];
return c + ":" + p;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return new ActionEnum(this);
}
public DataSet ActionList
{
get
{
XmlNode node = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/ActionList");
DataSet ds = new DataSet();
if (node == null)
{
ds.ReadXml(new StringReader("<ActionList><Action><Component/><Parameter/></Action></ActionList>"));
}
else
{
ds.ReadXml(new StringReader(node.OuterXml));
}
return ds;
}
set
{
XmlNode node = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']");
if (node == null)
{
node = mXml.CreateElement("ActionList");
XmlElement computer = (XmlElement)mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']");
computer.AppendChild(node);
}
node.InnerXml = value.GetXml();
}
}
public int RetryTimeout
{
get
{
XmlNode node = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/RetryTimeout");
if (node == null)
return ComputerInfo.DefaultRetryTimeout;
return Int32.Parse(node.InnerText);
}
set
{
XmlNode node = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/RetryTimeout");
if (node == null)
{
XmlElement elem = mXml.CreateElement("RetryTimeout");
elem.InnerText = value.ToString();
XmlElement computer = (XmlElement)mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']");
computer.AppendChild(elem);
}
else
{
node.InnerText = value.ToString();
}
}
}
public int NumRetries
{
get
{
XmlNode node = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/NumRetries");
if (node == null)
return ComputerInfo.DefaultNumRetries;
return Int32.Parse(node.InnerText);
}
set
{
XmlNode node = mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']/NumRetries");
if (node == null)
{
XmlElement elem = mXml.CreateElement("NumRetries");
elem.InnerText = value.ToString();
XmlElement computer = (XmlElement)mXml.SelectSingleNode("/ComputerList/Computer[@name='" + mComputerName + "']");
computer.AppendChild(elem);
}
else
{
node.InnerText = value.ToString();
}
}
}
}
}
|
|
|
using System;
using System.Data;
using System.Windows.Forms;
namespace jMonitor
{
public partial class EditDialog : Form
{
private ComputerInfo mComputerInfo;
/// <summary>
/// Edit an existing computer to monitor
/// </summary>
/// <param name="ci">the computer to monitor</param>
public EditDialog(ref ComputerInfo ci)
{
InitializeComponent();
mComputerInfo = ci;
textBoxName.Text = mComputerInfo.ComputerName;
checkBoxUseIPAddress.Checked = mComputerInfo.UseIPAddress;
textBoxAddress.Text = mComputerInfo.IPAddress;
textBoxPort.Text = mComputerInfo.Port.ToString();
dataGridView1.DataSource = mComputerInfo.ActionList;
dataGridView1.DataMember = "Action";
textBoxRetryTimeout.Text = mComputerInfo.RetryTimeout.ToString();
textBoxNumRetries.Text = mComputerInfo.NumRetries.ToString();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
/// <summary>
/// add the dialog's values to computer
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAccept_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
mComputerInfo.ComputerName = this.textBoxName.Text;
//actionlist/watch parameters
mComputerInfo.ActionList = (DataSet)dataGridView1.DataSource;
mComputerInfo.Port = Int32.Parse(this.textBoxPort.Text);
mComputerInfo.UseIPAddress = this.checkBoxUseIPAddress.Checked;
mComputerInfo.IPAddress = this.textBoxAddress.Text;
mComputerInfo.RetryTimeout = Int32.Parse(textBoxRetryTimeout.Text);
mComputerInfo.NumRetries = Int32.Parse(textBoxNumRetries.Text);
//finally... save to the config file.
ComputerInfo.Save();
}
}
}
|
|
|
using System;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
namespace jMonitor
{
public partial class Form1 : Form, ITraceable, IRefreshable
{
/// <summary>
/// indicate whether or not we are currently checking the computers
/// </summary>
private bool mBusy;
private ToolTip toolTip1 = new ToolTip();
/// <summary>
/// The main panel for monitoring computers
/// </summary>
public Form1()
{
InitializeComponent();
mBusy = false;
LoadComputers();
// Set up the delays for the ToolTip.
toolTip1.AutoPopDelay = 3000;
toolTip1.InitialDelay = 500;
toolTip1.ReshowDelay = 500;
// Force the ToolTip text to be displayed whether or not the form is active.
toolTip1.ShowAlways = true;
}
void c_CheckedChanged(object sender, EventArgs e)
{
CheckBox c = (CheckBox)sender;
if (c.Checked)
{
c.BackColor = Color.Turquoise;
}
else
{
c.BackColor = Color.Transparent;
}
}
/// <summary>
/// get the list of computers from the registry
/// </summary>
private void LoadComputers()
{
tblComputerInfo.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
tblComputerInfo.AutoSize = true;
tblComputerInfo.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
tblComputerInfo.RowCount = 0;
tblComputerInfo.ColumnCount = 0;
foreach (ComputerInfo ci in ComputerInfo.GetComputers())
{
tblComputerInfo.RowCount = tblComputerInfo.RowCount + 1;
CreateComputer(tblComputerInfo.RowCount, ci);
}
}
private void CreateComputer(int row, ComputerInfo ci)
{
Label statelabel = new Label();
statelabel.TextAlign = ContentAlignment.MiddleCenter;
ci.SetUI(this, this, statelabel);
ci.Row = row;
int col = 0;
CheckBox c = new CheckBox();
c.CheckAlign = ContentAlignment.MiddleCenter;
c.CheckedChanged += new EventHandler(c_CheckedChanged);
tblComputerInfo.Controls.Add(ci, col, row);
col++;
statelabel.Text = ci.ComputerName;
statelabel.TextAlign = ContentAlignment.MiddleCenter;
tblComputerInfo.Controls.Add(statelabel, col, row);
col++;
Label x;
x = new Label();
x.Text = ci.IPAddress;
x.TextAlign = ContentAlignment.MiddleCenter;
x.AutoSize = true;
tblComputerInfo.Controls.Add(x, col, row);
col++;
if (tblComputerInfo.ColumnCount == 0)
tblComputerInfo.ColumnCount = col;
}
delegate void SetTextCallback(string format, params object[] arg);
/// <summary>
/// add a line to the console output
/// </summary>
/// <param name="format"></param>
/// <param name="arg"></param>
public void AddLine(string format, params object[] arg)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.listboxConsole.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(AddLine);
this.Invoke(d, new object[] { format, arg });
}
else
{
string msg = String.Format(format, arg);
for (; ; )
{
if (msg == "\n" || msg == "")
break;
int i = msg.IndexOf('\n');
if (i == -1)
{
listboxConsole.Items.Add(msg);
break;
}
else
{
string msg1 = msg.Substring(0, i);
listboxConsole.Items.Add(msg1);
msg = msg.Substring(i + 1);
}
}
while (listboxConsole.Items.Count > 1000)
{
listboxConsole.Items.RemoveAt(0);
}
ScrollTextBoxEnd(listboxConsole);
}
}
/// <summary>
/// check all computers in the list
/// </summary>
/// <param name="parm"></param>
private void Check(object parm)
{
mBusy = true;
this.UseWaitCursor = true;
foreach (ComputerInfo ci in (ArrayList)parm)
{
AddLine("Checking - running: " + ci.ComputerName);
ci.Run();
}
foreach (ComputerInfo ci in (ArrayList)parm)
{
ci.WaitFor();
}
mBusy = false;
this.UseWaitCursor = false;
}
delegate void UpdateLabels(ComputerInfo ci);
public void RefreshControls(ComputerInfo ci)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.tblComputerInfo.InvokeRequired)
{
UpdateLabels d = new UpdateLabels(RefreshControls);
this.Invoke(d, ci);
}
else
{
int row = ci.Row - 1;
((Label)tblComputerInfo.Controls[(row * tblComputerInfo.ColumnCount) + 1]).Text = ci.ComputerName;
((Label)tblComputerInfo.Controls[(row * tblComputerInfo.ColumnCount) + 2]).Text = ci.IPAddress;
// Set up the ToolTip text for the Button and Checkbox.
toolTip1.SetToolTip(tblComputerInfo.Controls[(row * tblComputerInfo.ColumnCount) + 1], ci.Reason);
}
}
/// <summary>
/// spin off a thread to monitor all checked computers
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnCheck_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ParameterizedThreadStart(Check));
ArrayList cilist = new ArrayList();
int itemcount = tblComputerInfo.Controls.Count / tblComputerInfo.ColumnCount;
bool doall = true;
for (int i = 0; i < itemcount; ++i)
{
if (((CheckBox)tblComputerInfo.Controls[i * tblComputerInfo.ColumnCount]).Checked)
{
doall = false;
}
}
for (int i = 0; i < itemcount; ++i)
{
if (doall || ((CheckBox)tblComputerInfo.Controls[i * tblComputerInfo.ColumnCount]).Checked)
{
cilist.Add((ComputerInfo)tblComputerInfo.Controls[i * tblComputerInfo.ColumnCount]);
}
}
t.Start(cilist);
}
/// <summary>
/// if we are in the middle of monitoring, disallow the close
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_FormClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (mBusy)
{
e.Cancel = true;
}
else
{
ComputerInfo.Save();
}
}
#region Native
/// <summary>
/// Scrolls the textbox to the end
/// </summary>
/// <param name="tb"></param>
private void ScrollTextBoxEnd(ListBox tb)
{
const int WM_VSCROLL = 277;
const int SB_BOTTOM = 7;
IntPtr ptrWparam = new IntPtr(SB_BOTTOM);
IntPtr ptrLparam = new IntPtr(0);
SendMessage(tb.Handle, WM_VSCROLL, ptrWparam, ptrLparam);
}
[DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
#endregion //Private
/// <summary>
/// add a new computer
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAdd_Click(object sender, EventArgs e)
{
AddDialog dlg = new AddDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
tblComputerInfo.RowCount = tblComputerInfo.RowCount + 1;
CreateComputer(tblComputerInfo.RowCount, dlg.GetInfo());
}
}
/// <summary>
/// edit one or more computers
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnEdit_Click(object sender, EventArgs e)
{
int itemcount = tblComputerInfo.Controls.Count / tblComputerInfo.ColumnCount;
for (int i = 0; i < itemcount; ++i)
{
if (((CheckBox)tblComputerInfo.Controls[i * tblComputerInfo.ColumnCount]).Checked)
{
ComputerInfo ci = (ComputerInfo)tblComputerInfo.Controls[i * tblComputerInfo.ColumnCount];
EditDialog dlg = new EditDialog(ref ci);
if (dlg.ShowDialog() == DialogResult.OK)
{
//todo: use ComputerInfo copy assignment or something better than this!!
((ComputerInfo)tblComputerInfo.Controls[i * tblComputerInfo.ColumnCount]).ComputerName = ci.ComputerName;
((ComputerInfo)tblComputerInfo.Controls[i * tblComputerInfo.ColumnCount]).Port = ci.Port;
//todo: remove dependency on column order (i.e. + 1, + 2)
((Label)tblComputerInfo.Controls[(i * tblComputerInfo.ColumnCount) + 1]).Text = ci.ComputerName;
}
}
}
}
/// <summary>
/// delete a computer from the list
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnDelete_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Are you sure you want to delete?", "Confirm Deletion", MessageBoxButtons.YesNo) == DialogResult.No)
return;
int itemcount = tblComputerInfo.Controls.Count / tblComputerInfo.ColumnCount;
//iterate backwards to preserve the indexes into the column widgets
for (int i = itemcount - 1; i >= 0; --i)
{
if (((CheckBox)tblComputerInfo.Controls[i * tblComputerInfo.ColumnCount]).Checked)
{
//remove the computer in the xml config file
ComputerInfo ci = (ComputerInfo)tblComputerInfo.Controls[i * tblComputerInfo.ColumnCount];
ci.DeleteComputer();
//remove the row on the screen, by removing the controls in the columns
for (int j = 0; j < tblComputerInfo.ColumnCount; ++j)
{
tblComputerInfo.Controls.RemoveAt(i * tblComputerInfo.ColumnCount);
}
}
}
}
}
}
|
|
|
namespace jMonitor
{
public interface IRefreshable
{
void RefreshControls(ComputerInfo ci);
}
}
|
|
|
namespace jMonitor
{
public interface IStateChecker
{
void Reset();
void ConnectionFailed(string reason);
void ConnectionSucceeded();
void RequestFailed(string reason);
void RequestSucceeded();
void CheckResponse(string computer, string component, string parameter, string response);
}
}
|
|
|
namespace jMonitor
{
public interface ITraceable
{
void AddLine(string format, params object[] arg);
}
}
|
|
|
using System;
using System.Windows.Forms;
namespace jMonitor
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 form = new Form1();
Application.Run(form);
}
}
}
|
|
|
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace jMonitor
{
class WorkerThread
{
private Thread mThread;
private ITraceable mTracer;
private IStateChecker mStateChecker;
private ComputerInfo mInfo;
public WorkerThread(ITraceable t, IStateChecker sc, ComputerInfo ci)
{
mTracer = t;
mInfo = ci;
mStateChecker = sc;
}
public void Run()
{
mThread = new Thread(new ThreadStart(ThreadProc));
mThread.Start();
Thread.Sleep(0);
}
public void WaitFor()
{
mTracer.AddLine("[{0}] Run: Waiting until ThreadProc ends.", mInfo.ComputerName);
mThread.Join();
mTracer.AddLine("[{0}] Run: ThreadProc has ended.", mInfo.ComputerName);
}
private System.Net.IPAddress[] GetAddressList()
{
System.Net.IPAddress[] addresslist;
if (mInfo.UseIPAddress)
{
addresslist = new System.Net.IPAddress[1];
addresslist[0] = System.Net.IPAddress.Parse(mInfo.IPAddress);
}
else if (mInfo.ComputerName.ToUpperInvariant().Equals(SystemInformation.ComputerName.ToUpperInvariant()))
{
mTracer.AddLine("[{0}] INFO: Current computer {1}", mInfo.ComputerName, mInfo.ComputerName);
mInfo.ComputerName = SystemInformation.ComputerName;
addresslist = new System.Net.IPAddress[1];
addresslist[0] = System.Net.IPAddress.Loopback;
}
else
{
//try and get the IP address of the remote computer
try
{
System.Net.IPHostEntry host;
host = System.Net.Dns.GetHostEntry(mInfo.ComputerName);
addresslist = host.AddressList;
}
catch (System.Net.Sockets.SocketException /*ignore*/)
{
mTracer.AddLine("[{0}] ERROR: Could not find IP address for {1}", mInfo.ComputerName, mInfo.ComputerName);
mTracer.AddLine("[{0}] : check the name", mInfo.ComputerName);
mTracer.AddLine("[{0}] : or use the IP address", mInfo.ComputerName);
mStateChecker.ConnectionFailed("Could find IP address of remote computer");
mInfo.RefreshControls();
addresslist = null;
}
}
return addresslist;
}
private void AdjustComputerInfo(System.Net.IPAddress addr)
{
System.Net.IPHostEntry ipHostEntry = System.Net.Dns.GetHostEntry(addr.ToString());
mTracer.AddLine("[{0}] INFO: remote {1} is IP address: {2}",
mInfo.ComputerName, mInfo.ComputerName, addr.ToString());
mTracer.AddLine("[{0}] INFO: remote {1} is Host : {2}",
mInfo.ComputerName, mInfo.ComputerName, ipHostEntry.HostName);
//if the computername was entered as an ip address, then convert to a name
if (mInfo.ComputerName.Equals(addr.ToString()))
{
mInfo.ComputerName = ipHostEntry.HostName;
}
//if it's just a difference in case, use the correct case
if (mInfo.ComputerName.ToUpperInvariant().Equals(ipHostEntry.HostName.ToUpperInvariant()))
{
mInfo.ComputerName = ipHostEntry.HostName;
}
foreach (string alias in ipHostEntry.Aliases)
{
mTracer.AddLine("[{0}] INFO: remote {1} is Alias : {2}",
mInfo.ComputerName, mInfo.ComputerName, alias);
}
mInfo.IPAddress = addr.ToString();
}
private class ClientSocket
{
Socket mClient;
System.Net.EndPoint mEndPoint;
public ClientSocket(System.Net.IPAddress addr, int port)
{
mEndPoint = new System.Net.IPEndPoint(new System.Net.IPAddress(addr.GetAddressBytes()), port);
mClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
mClient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 100);
}
public int Send(byte[] buf)
{
return mClient.SendTo(buf, buf.Length, SocketFlags.None, mEndPoint);
}
public int WaitForReply(int timeout, int maxtries)
{
int bytesready = 0;
for (int j = 0; j < maxtries; ++j)
{
//if there is, go get em
bytesready = mClient.Available;
if (bytesready > 0)
break;
//sleep a while and try again
Thread.Sleep(timeout);
//use exponential backoff
timeout = 2 * timeout;
}
return bytesready;
}
public int Receive(byte[] buf)
{
return mClient.ReceiveFrom(buf, buf.Length, SocketFlags.None, ref mEndPoint);
}
}
private int SendWithRetry(ClientSocket client, byte[] buf)
{
int bytesready = 0;
for (int retries = 0; retries < 3; ++retries)
{
mTracer.AddLine("[{0}] INFO: Trying to send (try {1})...", mInfo.ComputerName, retries + 1);
int bytessent = client.Send(buf);
if (bytessent != buf.Length)
{
mTracer.AddLine("[{0}] WARN: Send failed, trying again...", mInfo.ComputerName);
mStateChecker.ConnectionFailed("Send failed"); //todo: why did it fail?
continue;
}
//check if there is a reply. If not, try again.
bytesready = client.WaitForReply(mInfo.RetryTimeout, mInfo.NumRetries);
if (bytesready == 0)
{
mTracer.AddLine("[{0}] WARN: Message sent, but didn't get a reply...", mInfo.ComputerName);
mStateChecker.ConnectionFailed("Send succeeded, but no reply"); //todo: why did it fail?
continue;
}
break;
}
return bytesready;
}
public void ThreadProc()
{
mStateChecker.Reset();
System.Net.IPAddress[] addresslist = GetAddressList();
if (addresslist == null)
return;
foreach (System.Net.IPAddress addr in addresslist)
{
AdjustComputerInfo(addr);
mInfo.RefreshControls();
//set up the socket and endpoint needed to send
ClientSocket client = new ClientSocket(addr, mInfo.Port);
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
foreach (string action in mInfo)
{
mTracer.AddLine("[{0}] Action: {1}", mInfo.ComputerName, action);
//set up the buffer to send
byte[] buf = new byte[4096];
buf = encoding.GetBytes(action);
bool transactioncompleted = false;
bool communicatedwithremote = false;
int bytesready = 0;
//try to sending a few times in case once didn't work
bytesready = SendWithRetry(client, buf);
if (bytesready > 0)
{
communicatedwithremote = true;
try
{
//we got a reply, handle it
byte[] recvbuf = new byte[bytesready];
int bytesreceived = client.Receive(recvbuf);
mTracer.AddLine("[{0}] INFO: Reply received from: {1}", mInfo.ComputerName, addr.ToString());
string s = Encoding.ASCII.GetString(recvbuf, 0, bytesreceived);
foreach (string l in s.Split('\n'))
{
if (l != "")
mTracer.AddLine("[{0}] {1}", mInfo.ComputerName, l);
}
//todo: create a small class to hold component and parameter
string component = action.Substring(0, action.IndexOf(':'));
string parameter = action.Substring(action.IndexOf(':') + 1);
mStateChecker.CheckResponse(mInfo.ComputerName, component, parameter, s);
transactioncompleted = true; //we're done
}
catch (SocketException ex)
{
mTracer.AddLine("[{0}] WARN: Got a reply but couldn't read it: ", mInfo.ComputerName);
mTracer.AddLine("[{0}] WARN: {1}", mInfo.ComputerName, ex.Message);
mStateChecker.RequestFailed("Request sent, but could not read reply");
}
}
if (transactioncompleted)
{
mInfo.RefreshControls();
//go on to the next Action
}
else if (communicatedwithremote)
{
mTracer.AddLine("[{0}] ERROR: Could not communicate with {1}", mInfo.ComputerName, mInfo.ComputerName);
mTracer.AddLine("[{0}] : check that the Monitor service is running", mInfo.ComputerName);
mStateChecker.RequestFailed("Send succeeded, did not receive a reply from remote computer");
mInfo.RefreshControls();
break; //don't try anymore Actions
}
else
{
mTracer.AddLine("[{0}] ERROR: Could not communicate with {1}", mInfo.ComputerName, mInfo.ComputerName);
mTracer.AddLine("[{0}] : check the name or IP address", mInfo.ComputerName);
mTracer.AddLine("[{0}] : or check firewall settings", mInfo.ComputerName);
mStateChecker.ConnectionFailed("Could not communicate with remote computer");
mInfo.RefreshControls();
break; //don't try anymore Actions
}
}
}
}
}
}
|
|
|
using System.ServiceProcess;
namespace jMonitorService
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
// More than one user Service may run within the same process. To add
// another service to this process, change the following line to
// create a second service object. For example,
//
// ServicesToRun = new ServiceBase[] {new Service1(), new MySecondUserService()};
//
ServicesToRun = new ServiceBase[] { new Service1() };
ServiceBase.Run(ServicesToRun);
}
}
}
|
|
|
//#define LOGEVENTS
using System;
using System.ServiceProcess;
using System.Threading;
using System.Diagnostics;
using System.Text;
using System.Net.Sockets;
using System.Reflection;
using System.IO;
namespace jMonitorService
{
public partial class Service1 : ServiceBase
{
private Thread mServerThread;
static private AppDomain mDomain;
//------------------------------------
public Service1()
{
InitializeComponent();
}
//------------------------------------
// Start the service.
protected override void OnStart(string[] args)
{
//ServiceControllerStatus status = new ServiceControllerStatus();
IntPtr handle = this.ServiceHandle;
//status.currentState = (int)State.SERVICE_START_PENDING;
//SetServiceStatus(handle, myServiceStatus);
// Start a separate thread that does the actual work.
if (mServerThread == null)
{
#if LOGEVENTS
EventLog.WriteEntry("jMonitorService.OnStart", DateTime.Now.ToLongTimeString() +
" - Starting the service worker thread.");
#endif
mServerThread = new Thread(new ThreadStart(ServerWorkerMethod));
}
//the thread is created one way or another...
if (mServerThread != null)
{
mServerThread.Start();
#if LOGEVENTS
EventLog.WriteEntry("jMonitorService.OnStart", DateTime.Now.ToLongTimeString() +
" - Worker thread state = " +
mServerThread.ThreadState.ToString());
#endif
}
//myServiceStatus.currentState = (int)State.SERVICE_RUNNING;
//SetServiceStatus(handle, myServiceStatus);
}
//------------------------------------
protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to stop your service.
if (mServerThread != null)
{
mServerThread.Abort();
//mServerThread.Join();
mServerThread = null;
#if LOGEVENTS
EventLog.WriteEntry("jMonitorService.OnStop", DateTime.Now.ToLongTimeString() +
" - Worker thread aborted ");
#endif
}
}
//------------------------------------
private void ServerWorkerMethod()
{
System.Net.IPEndPoint ipep = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 5000);
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
newsock.Bind(ipep);
System.Net.IPEndPoint sender = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
System.Net.EndPoint Remote = (System.Net.EndPoint)(sender);
for (; ; )
{
byte[] data = new byte[1024];
#if LOGEVENTS
EventLog.WriteEntry("jMonitorService.ServerWorkerThread", DateTime.Now.ToLongTimeString() +
" - Waiting for a client...");
#endif
int recv = newsock.ReceiveFrom(data, ref Remote);
#if LOGEVENTS
EventLog.WriteEntry("jMonitorService.ServerWorkerThread", DateTime.Now.ToLongTimeString() +
" - Message received");
#endif
//Console.WriteLine("Message received from {0}:", Remote.ToString());
string request = Encoding.ASCII.GetString(data, 0, recv);
//Console.WriteLine("Check for: '" + request + "'");
string component;
string parameter;
int p = request.IndexOf(':');
if (p == -1)
{
EventLog.WriteEntry("jMonitorService.ServerWorkerMethod", DateTime.Now.ToLongTimeString() +
" - WARNING missng ':', using component 'ProcessCheck'");
component = "ProcessCheck";
parameter = request;
}
else
{
component = request.Substring(0, p);
parameter = request.Substring(p + 1);
}
#if LOGEVENTS
EventLog.WriteEntry("jMonitorService.ServerWorkerMethod", DateTime.Now.ToLongTimeString() +
" - component='" + component+ "' parameter='" + parameter + "'");
#endif
string response = "";
try
{
ManualResetEvent waitonevent = new ManualResetEvent(false);
LoadAssembly(component, parameter, waitonevent);
waitonevent.WaitOne();
response = UnloadAssembly();
#if LOGEVENTS
EventLog.WriteEntry("jMonitorService.ServerWorkerMethod", DateTime.Now.ToLongTimeString() +
" - response='" + response + "'");
#endif
}
catch (Exception ex)
{
EventLog.WriteEntry("jMonitorService.ServerWorkerMethod", DateTime.Now.ToLongTimeString() +
" - Exception= '" + ex.Message + "'");
response = "ERROR: " + ex.Message;
}
data = Encoding.ASCII.GetBytes(response);
newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
}
}
static void LoadAssembly(string name, string parameter, ManualResetEvent waitonevent)
{
System.Security.Policy.Evidence evidence = new System.Security.Policy.Evidence(AppDomain.CurrentDomain.Evidence);
mDomain = AppDomain.CreateDomain(name, evidence);
mDomain.SetData("Name", name);
mDomain.SetData("Parameter", parameter);
mDomain.SetData("WaitOnEvent", waitonevent);
mDomain.DoCallBack(new CrossAppDomainDelegate(RunAssembly));
}
//---------------------------
static string UnloadAssembly()
{
string response = (string)mDomain.GetData("Response");
AppDomain.Unload(mDomain);
return response;
}
//---------------------------
static void RunAssembly()
{
#if LOGEVENTS
EventLog.WriteEntry("jMonitorService.LoadAssemblyIntoDomain", DateTime.Now.ToLongTimeString() +
" - domainname = '" + AppDomain.CurrentDomain.FriendlyName + "'");
#endif
AppDomain ad = AppDomain.CurrentDomain;
if (ad == null)
{
Exception ex = new Exception("LoadAssemblyIntoDomain: LoadAssembly failed, returned null");
throw ex;
}
string name = (string)ad.GetData("Name");
string parameter = (string)ad.GetData("Parameter");
ManualResetEvent waitonevent = (ManualResetEvent) ad.GetData("WaitOnEvent");
#if LOGEVENTS
EventLog.WriteEntry("jMonitorService.LoadAssemblyIntoDomain", DateTime.Now.ToLongTimeString() +
" - name='" + name + "' parm='" + parameter + "'");
#endif
string cwd = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string path = cwd + "\\" + name + ".dll";
string title_class = name + "." + name;
string title_method = "Run";
Assembly u = Assembly.LoadFrom(path);
if (u == null)
{
throw new Exception("LoadAssemblyIntoDomain: LoadAssembly failed, returned null");
}
Type t = u.GetType(title_class);
if (t == null)
{
throw new Exception("LoadAssemblyIntoDomain: GetType failed, returned null");
}
MethodInfo m = t.GetMethod(title_method);
if (m == null)
{
throw new Exception("LoadAssemblyIntoDomain: GetMethod failed, returned null");
}
object[] myparam = new object[1];
myparam[0] = parameter;
string response = (string)m.Invoke(null, myparam);
ad.SetData("Response", response);
waitonevent.Set();
}
}
}
|
|
|
using System;
using System.Diagnostics;
//Must have a namespace with the same name as the .dll
namespace ProcessCheck
{
//Must have a class with the same name as the .dll
public class ProcessCheck
{
//Must have a method signature "static string Run(string)"
public static string Run(string parm)
{
EventLog.WriteEntry("jMonitorService.ProcessCheck", DateTime.Now.ToLongTimeString() +
" - Run('" + parm + "')");
string response = "";
Process[] myProcesses = Process.GetProcesses();
foreach (Process myProcess in myProcesses)
{
if (myProcess.ProcessName.StartsWith(parm))
{
//Console.WriteLine("Matched : " + myProcess.ProcessName);
response += myProcess.ProcessName + "\n";
}
else
{
//Console.WriteLine("No Match: " + myProcess.ProcessName);
}
}
//Console.WriteLine("\nMessage:\n" + response);
return response;
}
//---------------------
public static bool CheckResponse(string computer, string parameter, string response)
{
//Console.WriteLine("CheckResponse: computer=" + computer + " parm=" + parameter + " response=" + response);
foreach (string l in response.Split('\n'))
{
if (l != "")
{
if (l.StartsWith(parameter))
return true;
}
}
return false;
}
}
}
|