Add code
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<system.net>
|
||||
<settings>
|
||||
<httpWebRequest useUnsafeHeaderParsing="true" />
|
||||
</settings>
|
||||
<defaultProxy>
|
||||
<proxy bypassonlocal="True" usesystemdefault="False" />
|
||||
</defaultProxy>
|
||||
</system.net>
|
||||
</configuration>
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{7686BAA6-A0C5-4FA5-BE6E-FA044C2FFDD4}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Endpoint</RootNamespace>
|
||||
<AssemblyName>Endpoint</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="HtmlAgilityPack, Version=1.3.0.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>References\HtmlAgilityPack.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.configuration" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="HtmlEndpoint.cs" />
|
||||
<Compile Include="IEndpoint.cs" />
|
||||
<Compile Include="HttpEndpoint.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SoapEndpoint.cs" />
|
||||
<Compile Include="Status.cs" />
|
||||
<Compile Include="StatusComparer.cs" />
|
||||
<Compile Include="WindowsServiceEndpoint.cs" />
|
||||
<Compile Include="WmiEndpoint.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using HtmlAgilityPack;
|
||||
|
||||
namespace Endpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// A website endpoint
|
||||
/// </summary>
|
||||
public class HtmlEndpoint : HttpEndpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the xpath query for the html document
|
||||
/// </summary>
|
||||
/// <value>The xpath query.</value>
|
||||
public string XpathQuery { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the expected query results.
|
||||
/// </summary>
|
||||
/// <value>The expected query results.</value>
|
||||
public string ExpectedXpathResult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the post.
|
||||
/// </summary>
|
||||
/// <value>The post.</value>
|
||||
public string RequestContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the HTML parsed into a standard <see cref="XmlDocument"/>.
|
||||
/// Uses the <see cref="HtmlAgilityPack"/> library for "out of the web" (poorly formatted) html file support.
|
||||
/// </summary>
|
||||
/// <param name="html">The HTML</param>
|
||||
/// <returns>An <see cref="XmlDocument"/> from the HTML</returns>
|
||||
private static XmlDocument getHtmlXml(string html)
|
||||
{
|
||||
var htmlDocument = new HtmlDocument();
|
||||
htmlDocument.LoadHtml(html);
|
||||
|
||||
var xmlDocument = new XmlDocument();
|
||||
using (Stream stream = new MemoryStream())
|
||||
{
|
||||
XmlWriter xmlTextWriter = new XmlTextWriter(stream, Encoding.UTF8);
|
||||
|
||||
htmlDocument.Save(xmlTextWriter);
|
||||
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using (var sr = new StreamReader(stream))
|
||||
xmlDocument.Load(sr);
|
||||
|
||||
xmlTextWriter.Close();
|
||||
}
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the HTML grabbed from the passed in URL parsed into a standard <see cref="XmlDocument"/>.
|
||||
/// Uses the <see cref="HtmlAgilityPack"/> library for "out of the web" html file support.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL.</param>
|
||||
/// <param name="requestContent">The post data.</param>
|
||||
/// <returns>An <see cref="XmlDocument"/> from the HTML</returns>
|
||||
private static XmlDocument getHtmlXml(Uri url, string requestContent)
|
||||
{
|
||||
return getHtmlXml(GetUrlContent(url, "application/x-www-form-urlencoded", requestContent, null));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status result of the endpoint
|
||||
/// </summary>
|
||||
/// <returns>Status</returns>
|
||||
public override Status GetStatus()
|
||||
{
|
||||
var baseStatus = base.GetStatus();
|
||||
if (baseStatus != Status.Up)
|
||||
return baseStatus;
|
||||
|
||||
try
|
||||
{
|
||||
var xml = getHtmlXml(Uri, RequestContent);
|
||||
|
||||
// xml.Save(@"c:\test.xml");
|
||||
|
||||
var nodes = xml.SelectNodes(XpathQuery);
|
||||
|
||||
// verify html has expected value
|
||||
if (nodes == null || nodes.Count == 0)
|
||||
{
|
||||
StatusDescription = "Couldn't find expected value in html";
|
||||
return Status.Error;
|
||||
}
|
||||
var value = nodes[0].Value.Trim();
|
||||
if (value != ExpectedXpathResult)
|
||||
{
|
||||
StatusDescription = String.Format("Result was: '{0}', was expecting '{1}'", value,
|
||||
ExpectedXpathResult);
|
||||
return Status.Error;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusDescription = ex.Message;
|
||||
return Status.Error;
|
||||
}
|
||||
return Status.Up;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace Endpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Http Endpoint - such as a webserver, a webservice, etc
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class HttpEndpoint : IEndpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// URI of the service
|
||||
/// </summary>
|
||||
public Uri Uri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the URI string.
|
||||
/// </summary>
|
||||
/// <value>The URI string.</value>
|
||||
public string UriString
|
||||
{
|
||||
get { return Uri.ToString(); }
|
||||
set { Uri = new Uri(value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the response string grabbed from the passed in URL.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL.</param>
|
||||
/// <param name="contentType">The HTTP content type.</param>
|
||||
/// <param name="requestContent">The request content.</param>
|
||||
/// <param name="webHeaders">The web headers.</param>
|
||||
/// <returns>A string containing response</returns>
|
||||
protected static string GetUrlContent(Uri url, string contentType, string requestContent,
|
||||
Dictionary<string, string> webHeaders)
|
||||
{
|
||||
// POST request
|
||||
if (!string.IsNullOrEmpty(contentType) && !string.IsNullOrEmpty(requestContent))
|
||||
{
|
||||
var webRequest = (HttpWebRequest) WebRequest.Create(url);
|
||||
|
||||
// NOTE: need a proxy? Here's where it would go
|
||||
// webRequest.Proxy = new WebProxy();
|
||||
|
||||
// SOAP
|
||||
webRequest.ContentType = contentType;
|
||||
if (webHeaders != null && webHeaders.Count > 0)
|
||||
{
|
||||
foreach (var webHeader in webHeaders)
|
||||
webRequest.Headers.Add(webHeader.Key, webHeader.Value);
|
||||
}
|
||||
|
||||
webRequest.Method = "POST";
|
||||
|
||||
//We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&
|
||||
var bytes = Encoding.ASCII.GetBytes(requestContent);
|
||||
webRequest.ContentLength = bytes.Length;
|
||||
using (var requestStream = webRequest.GetRequestStream())
|
||||
{
|
||||
requestStream.Write(bytes, 0, bytes.Length); //write it to the stream
|
||||
}
|
||||
var webResponse = webRequest.GetResponse();
|
||||
if (webResponse == null)
|
||||
return null;
|
||||
using (var streamReader = new StreamReader(webResponse.GetResponseStream()))
|
||||
{
|
||||
return streamReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// GET Request
|
||||
var client = new WebClient();
|
||||
using (var data = client.OpenRead(url))
|
||||
using (var reader = new StreamReader(data))
|
||||
{
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string explaining details on the current status
|
||||
/// </summary>
|
||||
/// <returns>string with status message</returns>
|
||||
public virtual string StatusDescription { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status result of the endpoint
|
||||
/// </summary>
|
||||
/// <returns>Status</returns>
|
||||
public virtual Status GetStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = WebRequest.Create(Uri);
|
||||
|
||||
using (var response = (HttpWebResponse) request.GetResponse())
|
||||
{
|
||||
StatusDescription = response.StatusDescription;
|
||||
return response.StatusCode == HttpStatusCode.OK
|
||||
? Status.Up
|
||||
: Status.Unreachable;
|
||||
}
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
StatusDescription = ex.Message + " (" + ex.Status + ")";
|
||||
|
||||
return ex.Status == WebExceptionStatus.Timeout
|
||||
? Status.Timeout
|
||||
: Status.Unreachable;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
namespace Endpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes a service endpoint, and the methods to find its current status
|
||||
/// </summary>
|
||||
public interface IEndpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the service name
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status result of the endpoint
|
||||
/// </summary>
|
||||
/// <returns>Status</returns>
|
||||
Status GetStatus();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string explaining details on the current status
|
||||
/// </summary>
|
||||
/// <returns>string with status message</returns>
|
||||
string StatusDescription { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Endpoint")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Endpoint")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("aef466bc-73b7-4f86-a374-8db991adb437")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace Endpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// A SOAP webservice endpoint.
|
||||
/// </summary>
|
||||
public class SoapEndpoint : HttpEndpoint
|
||||
{
|
||||
private string _xpathNamespaces = string.Empty;
|
||||
private Dictionary<string, string> _namespaceToUri;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the xpath query for the html document
|
||||
/// </summary>
|
||||
/// <value>The xpath query.</value>
|
||||
public string XpathQuery { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the namespaces used in the xpath query
|
||||
/// </summary>
|
||||
/// <value>The xpath namespaces.</value>
|
||||
public string XpathNamespaces
|
||||
{
|
||||
get { return _xpathNamespaces; }
|
||||
set
|
||||
{
|
||||
_xpathNamespaces = value;
|
||||
if (string.IsNullOrEmpty(_xpathNamespaces)) return;
|
||||
|
||||
var split = _xpathNamespaces.Split(',');
|
||||
if (split.Length != 2)
|
||||
throw new ArgumentException("Need a comma separated pair in XpathNamespaces.");
|
||||
|
||||
_namespaceToUri = new Dictionary<string, string>();
|
||||
_namespaceToUri.Add(split[0], split[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the expected query results.
|
||||
/// </summary>
|
||||
/// <value>The expected query results.</value>
|
||||
public string ExpectedXpathResult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SOAP action.
|
||||
/// </summary>
|
||||
/// <value>The post.</value>
|
||||
public string SoapAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the SOAP request.
|
||||
/// </summary>
|
||||
/// <value>The post.</value>
|
||||
public string SoapRequest { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status result of the endpoint
|
||||
/// </summary>
|
||||
/// <returns>Status</returns>
|
||||
public override Status GetStatus()
|
||||
{
|
||||
var baseStatus = base.GetStatus();
|
||||
if (baseStatus != Status.Up) // if we can't even get to the webserver, no need to try and call a WS.
|
||||
return baseStatus;
|
||||
|
||||
try
|
||||
{
|
||||
var headers = new Dictionary<string, string> {{"SOAPAction", SoapAction}};
|
||||
|
||||
var xml = new XmlDocument();
|
||||
|
||||
xml.LoadXml(GetUrlContent(Uri, "text/xml; charset=utf-8", SoapRequest, headers));
|
||||
|
||||
XmlNodeList nodes;
|
||||
if (_namespaceToUri != null)
|
||||
{
|
||||
var nsMgr = new XmlNamespaceManager(xml.NameTable);
|
||||
foreach (var namespaceToUri in _namespaceToUri)
|
||||
{
|
||||
nsMgr.AddNamespace(namespaceToUri.Key, namespaceToUri.Value);
|
||||
}
|
||||
|
||||
nodes = xml.SelectNodes(XpathQuery, nsMgr);
|
||||
}
|
||||
else
|
||||
nodes = xml.SelectNodes(XpathQuery);
|
||||
|
||||
//xml.Save(@"c:\soap.xml");
|
||||
|
||||
// verify response has expected value
|
||||
if (nodes == null || nodes.Count == 0)
|
||||
{
|
||||
StatusDescription = "Couldn't find expected value in SOAP response";
|
||||
return Status.Error;
|
||||
}
|
||||
var value = nodes[0].Value.Trim();
|
||||
if (value != ExpectedXpathResult)
|
||||
{
|
||||
StatusDescription = String.Format("Result was: '{0}', was expecting '{1}'", value,
|
||||
ExpectedXpathResult);
|
||||
return Status.Error;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusDescription = ex.Message;
|
||||
return Status.Error;
|
||||
}
|
||||
return Status.Up;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace Endpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Status of an endpoint
|
||||
/// </summary>
|
||||
/// <remarks>The <see cref="StatusComparer"/> expects these to be in order of best-to-worst descending.</remarks>
|
||||
public enum Status
|
||||
{
|
||||
/// <summary>
|
||||
/// Service state is unknown - this will occur only before the first poll.
|
||||
/// </summary>
|
||||
Unknown,
|
||||
/// <summary>
|
||||
/// Service is working
|
||||
/// </summary>
|
||||
Up,
|
||||
/// <summary>
|
||||
/// Service can be resolved, but does not respond
|
||||
/// </summary>
|
||||
Timeout,
|
||||
/// <summary>
|
||||
/// Service can not be resolved
|
||||
/// </summary>
|
||||
Unreachable,
|
||||
/// <summary>
|
||||
/// Service is available, but returns an error message
|
||||
/// </summary>
|
||||
Error
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Endpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares a Status for which is the worst status.
|
||||
/// </summary>
|
||||
public class StatusComparer : IComparer<Status>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
|
||||
/// </summary>
|
||||
/// <param name="x">The first object to compare.</param>
|
||||
/// <param name="y">The second object to compare.</param>
|
||||
/// <returns>
|
||||
/// Value
|
||||
/// Condition
|
||||
/// Less than zero
|
||||
/// <paramref name="x"/> is less than <paramref name="y"/>.
|
||||
/// Zero
|
||||
/// <paramref name="x"/> equals <paramref name="y"/>.
|
||||
/// Greater than zero
|
||||
/// <paramref name="x"/> is greater than <paramref name="y"/>.
|
||||
/// </returns>
|
||||
public int Compare(Status x, Status y)
|
||||
{
|
||||
return y.CompareTo(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.ServiceProcess;
|
||||
|
||||
namespace Endpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Endpoint for a Windows Service
|
||||
/// </summary>
|
||||
public class WindowsServiceEndpoint : IEndpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the service name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string explaining details on the current status
|
||||
/// </summary>
|
||||
/// <returns>string with status message</returns>
|
||||
public string StatusDescription { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the windows service.
|
||||
/// </summary>
|
||||
/// <value>The name of the service.</value>
|
||||
public string ServiceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the machine the service runs on.
|
||||
/// </summary>
|
||||
/// <value>The name of the machine.</value>
|
||||
public string MachineName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status result of the endpoint
|
||||
/// </summary>
|
||||
/// <returns>Status</returns>
|
||||
public Status GetStatus()
|
||||
{
|
||||
ServiceController myservice;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(MachineName))
|
||||
myservice = new ServiceController(ServiceName, MachineName);
|
||||
else
|
||||
myservice = new ServiceController(ServiceName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusDescription = ex.Message;
|
||||
return Status.Unreachable;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
switch (myservice.Status)
|
||||
{
|
||||
case ServiceControllerStatus.Running:
|
||||
StatusDescription = "Running";
|
||||
return Status.Up;
|
||||
default:
|
||||
StatusDescription = myservice.Status.ToString();
|
||||
return Status.Error;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusDescription = ex.Message;
|
||||
return Status.Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using System.Management;
|
||||
|
||||
namespace Endpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Endpoint for Windows Management Instrumentation (WMI)
|
||||
/// </summary>
|
||||
public class WmiEndpoint : IEndpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the service name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string explaining details on the current status
|
||||
/// </summary>
|
||||
/// <returns>string with status message</returns>
|
||||
public string StatusDescription { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the machine to query with WMI.
|
||||
/// </summary>
|
||||
/// <value>The name of the machine.</value>
|
||||
public string MachineName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the object query string.
|
||||
/// </summary>
|
||||
/// <value>The object query string.</value>
|
||||
public string ObjectQueryString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection username.
|
||||
/// </summary>
|
||||
/// <value>The connection username.</value>
|
||||
public string ConnectionUsername { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the connection password.
|
||||
/// </summary>
|
||||
/// <value>The connection password.</value>
|
||||
public string ConnectionPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the result property - this needs to be returned by the query.
|
||||
/// </summary>
|
||||
/// <value>The name of the result property.</value>
|
||||
public string ResultPropertyName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Report error when result is this value.
|
||||
/// </summary>
|
||||
/// <value>A result indicating an error.</value>
|
||||
public string ErrorResult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Report up when result is this value.
|
||||
/// </summary>
|
||||
/// <value>A result indicating everything is ok.</value>
|
||||
public string UpResult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Report error when result is below this number
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public double MinimumThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Report error when result is above this number
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public double MaximumThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WmiEndpoint"/> class.
|
||||
/// </summary>
|
||||
public WmiEndpoint()
|
||||
{
|
||||
MinimumThreshold = double.MinValue;
|
||||
MaximumThreshold = double.MaxValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status result of the endpoint
|
||||
/// </summary>
|
||||
/// <returns>Status</returns>
|
||||
public Status GetStatus()
|
||||
{
|
||||
var connectionOptions = new ConnectionOptions();
|
||||
if (!string.IsNullOrEmpty(ConnectionUsername) && !string.IsNullOrEmpty(ConnectionPassword))
|
||||
{
|
||||
connectionOptions.Username = ConnectionUsername;
|
||||
connectionOptions.Password = ConnectionPassword;
|
||||
}
|
||||
|
||||
ManagementScope managementScope;
|
||||
try
|
||||
{
|
||||
managementScope = new ManagementScope(MachineName, connectionOptions);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
StatusDescription = string.Format("Management Scope for MachineName \"{1}\" Failed : \"{0}\"", e.Message, MachineName);
|
||||
return Status.Error;
|
||||
}
|
||||
|
||||
ObjectQuery objectQuery;
|
||||
try
|
||||
{
|
||||
objectQuery = new ObjectQuery(ObjectQueryString);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
StatusDescription = string.Format("ObjectQuery initialization \"{1}\" Failed : \"{0}\"", e.Message, ObjectQueryString);
|
||||
return Status.Error;
|
||||
}
|
||||
|
||||
ManagementObjectSearcher results;
|
||||
try
|
||||
{
|
||||
//Execute the query
|
||||
results = new ManagementObjectSearcher(managementScope, objectQuery);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
StatusDescription = string.Format("Building Query failed : \"{0}\"", e.Message);
|
||||
return Status.Error;
|
||||
}
|
||||
|
||||
ManagementObjectCollection managementObjectCollection;
|
||||
try
|
||||
{
|
||||
//Get the results
|
||||
managementObjectCollection = results.Get();
|
||||
|
||||
if (managementObjectCollection.Count == 0)
|
||||
{
|
||||
StatusDescription = string.Format("Query returned 0 results : \"{0}\"", ObjectQueryString);
|
||||
return Status.Error;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusDescription = "Error retrieving results. Exception: " + ex.Message;
|
||||
return Status.Unreachable;
|
||||
}
|
||||
|
||||
ManagementObject firstResult = null;
|
||||
|
||||
//take only the first result if there are more than one
|
||||
foreach (ManagementObject result in managementObjectCollection)
|
||||
{
|
||||
firstResult = result;
|
||||
break;
|
||||
}
|
||||
|
||||
if (firstResult == null)
|
||||
{
|
||||
StatusDescription = "Problem accessing first result object";
|
||||
return Status.Error;
|
||||
}
|
||||
|
||||
object resultValue;
|
||||
try
|
||||
{
|
||||
resultValue = firstResult[ResultPropertyName];
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusDescription = string.Format("Error retrieving result property \"{0}\". Exception: {1}",
|
||||
ResultPropertyName, ex.Message);
|
||||
return Status.Error;
|
||||
}
|
||||
|
||||
if (resultValue == null)
|
||||
{
|
||||
StatusDescription = string.Format("Result value was null for property \"{0}\".", ResultPropertyName);
|
||||
return Status.Error;
|
||||
}
|
||||
|
||||
return getStatus(resultValue.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the status.
|
||||
/// </summary>
|
||||
/// <param name="resultValueString">The result value string.</param>
|
||||
/// <returns></returns>
|
||||
private Status getStatus(string resultValueString)
|
||||
{
|
||||
// Up Value
|
||||
if (!string.IsNullOrEmpty(UpResult) && UpResult != resultValueString)
|
||||
{
|
||||
StatusDescription =
|
||||
string.Format("Result for property \"{0}\" was not expected value. Expected \"{1}\" but was \"{2}\"",
|
||||
ResultPropertyName, UpResult ?? "(NULL)", resultValueString);
|
||||
return Status.Error;
|
||||
}
|
||||
|
||||
// Error Value
|
||||
if (!string.IsNullOrEmpty(ErrorResult) && ErrorResult == resultValueString)
|
||||
{
|
||||
StatusDescription =
|
||||
string.Format("Result for property \"{0}\" was error value - \"{1}\"",
|
||||
ResultPropertyName, resultValueString);
|
||||
return Status.Error;
|
||||
}
|
||||
|
||||
if (MinimumThreshold != double.MinValue || MaximumThreshold != double.MaxValue)
|
||||
{
|
||||
double resultValueDouble;
|
||||
if (Double.TryParse(resultValueString, out resultValueDouble))
|
||||
{
|
||||
if (resultValueDouble < MinimumThreshold)
|
||||
{
|
||||
StatusDescription =
|
||||
string.Format("Result for property \"{0}\" was less then threshold - {1} < {2}",
|
||||
ResultPropertyName, resultValueDouble, MinimumThreshold);
|
||||
return Status.Error;
|
||||
}
|
||||
if (resultValueDouble > MaximumThreshold)
|
||||
{
|
||||
StatusDescription =
|
||||
string.Format("Result for property \"{0}\" was more then threshold - {1} > {2}",
|
||||
ResultPropertyName, resultValueDouble, MaximumThreshold);
|
||||
return Status.Error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusDescription =
|
||||
string.Format("Result for property \"{0}\" was not a number - \"{1}\"",
|
||||
ResultPropertyName, resultValueString);
|
||||
return Status.Error;
|
||||
}
|
||||
}
|
||||
|
||||
StatusDescription = resultValueString;
|
||||
return Status.Up;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{76D78812-B640-4EF0-957B-15D0E9000A84}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>EndpointTest</RootNamespace>
|
||||
<AssemblyName>EndpointTest</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="HtmlAgilityPack, Version=1.3.0.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Endpoint\References\HtmlAgilityPack.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="Oracle.DataAccess, Version=2.102.2.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Endpoint\References\Oracle.DataAccess.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.configuration" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SoapEndpointTest.cs" />
|
||||
<Compile Include="HtmlEndpointTest.cs" />
|
||||
<Compile Include="HttpEndpointTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="WindowsServiceEndpointTest.cs" />
|
||||
<Compile Include="WmiEndpointTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Endpoint\Endpoint.csproj">
|
||||
<Project>{7686BAA6-A0C5-4FA5-BE6E-FA044C2FFDD4}</Project>
|
||||
<Name>Endpoint</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using Endpoint;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace EndpointTest
|
||||
{
|
||||
/// <summary>
|
||||
///This is a test class for HtmlEndpointTest and is intended
|
||||
///to contain all HtmlEndpointTest Unit Tests
|
||||
///</summary>
|
||||
[TestClass]
|
||||
public class HtmlEndpointTest
|
||||
{
|
||||
// Random website for functional testing
|
||||
private readonly Uri _goodUri = new Uri("http://www.seekwellness.com/sca/");
|
||||
|
||||
/// <summary>
|
||||
///A test for HtmlEndpointConfiguration
|
||||
///</summary>
|
||||
[TestMethod]
|
||||
public void HtmlEndpointConfigurationTest()
|
||||
{
|
||||
var target = new HtmlEndpoint
|
||||
{
|
||||
UriString = _goodUri.OriginalString,
|
||||
XpathQuery = "//td[contains(text(), 'Use this form')]/text()",
|
||||
ExpectedXpathResult = "Use this form to order your",
|
||||
RequestContent = "redeem_coupon=true&f_coupon_code=stuff"
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Up, status, target.StatusDescription);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///A test for HtmlEndpointConfiguration
|
||||
///</summary>
|
||||
[TestMethod]
|
||||
public void HtmlEndpointFormTest()
|
||||
{
|
||||
var target = new HtmlEndpoint
|
||||
{
|
||||
UriString = _goodUri.OriginalString,
|
||||
XpathQuery = "//p[@class='errorMsg']/text()",
|
||||
ExpectedXpathResult = "- Please enter a valid coupon code.",
|
||||
RequestContent = "redeem_coupon=true&f_coupon_code=stuff"
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Up, status, target.StatusDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using Endpoint;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace EndpointTest
|
||||
{
|
||||
/// <summary>
|
||||
///This is a test class for HttpEndpointTest and is intended
|
||||
///to contain all HttpEndpointTest Unit Tests
|
||||
///</summary>
|
||||
[TestClass]
|
||||
public class HttpEndpointTest
|
||||
{
|
||||
private readonly Uri _goodUri = new Uri("http://www.google.com");
|
||||
private readonly Uri _missingUri = new Uri("http://www.google.com/gasdfasdh598yqwejbiasalsdjfhaogle");
|
||||
private readonly Uri _unreachableDomainUri = new Uri("http://gasdfasdh598yqwejbiasalsdjfhaogle");
|
||||
private readonly Uri _downUri = new Uri("http://192.168.0.153");
|
||||
private readonly Uri _httpsUri = new Uri("https://sourceforge.net/");
|
||||
|
||||
/// <summary>
|
||||
///A test for HttpEndpoint Constructor
|
||||
///</summary>
|
||||
[TestMethod]
|
||||
public void HttpEndpointConstructorTest()
|
||||
{
|
||||
HttpEndpoint endpoint = new HttpEndpoint {Uri = _goodUri};
|
||||
Assert.AreEqual(_goodUri, endpoint.Uri);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///A test for UrlString
|
||||
///</summary>
|
||||
[TestMethod]
|
||||
public void UrlStringTest()
|
||||
{
|
||||
HttpEndpoint endpoint = new HttpEndpoint {UriString = "http://uri/"};
|
||||
Assert.AreEqual("http://uri/", endpoint.Uri.AbsoluteUri);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///A test for GetStatus
|
||||
///</summary>
|
||||
[TestMethod]
|
||||
public void GetStatusGoodTest()
|
||||
{
|
||||
HttpEndpoint endpoint = new HttpEndpoint {Uri = _goodUri};
|
||||
Assert.AreEqual(Status.Up, endpoint.GetStatus());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///A test for GetStatus
|
||||
///</summary>
|
||||
[TestMethod]
|
||||
public void GetStatusMissingTest()
|
||||
{
|
||||
HttpEndpoint endpoint = new HttpEndpoint {Uri = _missingUri};
|
||||
Assert.AreEqual(Status.Unreachable, endpoint.GetStatus());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///A test for GetStatus
|
||||
///</summary>
|
||||
[TestMethod]
|
||||
public void GetStatusUnreachableTest()
|
||||
{
|
||||
HttpEndpoint endpoint = new HttpEndpoint {Uri = _unreachableDomainUri};
|
||||
Assert.AreEqual(Status.Unreachable, endpoint.GetStatus());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///A test for GetStatus
|
||||
///</summary>
|
||||
[TestMethod]
|
||||
public void GetStatusDownTest()
|
||||
{
|
||||
HttpEndpoint endpoint = new HttpEndpoint {Uri = _downUri};
|
||||
Assert.AreEqual(Status.Unreachable, endpoint.GetStatus());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///A test for GetStatus
|
||||
///</summary>
|
||||
[TestMethod]
|
||||
public void GetHttpsTest()
|
||||
{
|
||||
HttpEndpoint endpoint = new HttpEndpoint {Uri = _httpsUri};
|
||||
Assert.AreEqual(Status.Up, endpoint.GetStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("EndpointTest")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("EndpointTest")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM componenets. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("b5dcbcfc-f05e-4e58-bd8b-e4cbf660065d")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Endpoint;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace EndpointTest
|
||||
{
|
||||
///// <summary>
|
||||
/////This is a test class for ServiceEndpointConfigurationTest and is intended
|
||||
/////to contain all ServiceEndpointConfigurationTest Unit Tests
|
||||
/////</summary>
|
||||
//[TestClass()]
|
||||
//public class ServiceEndpointConfigurationTest
|
||||
//{
|
||||
// private readonly Uri _uri = new Uri("http://www.google.com");
|
||||
// private const string _testFilename = "testFilename.xml";
|
||||
|
||||
// /// <summary>
|
||||
// ///A test for SaveConfigurationList
|
||||
// ///</summary>
|
||||
// [TestMethod]
|
||||
// public void SaveAndLoadConfigurationListTest()
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// HttpEndpointConfiguration httpEndpoint = new HttpEndpointConfiguration("", _uri);
|
||||
// OracleEndpointConfiguration oracleEndpoint = new OracleEndpointConfiguration("", "connection", "query", "result");
|
||||
|
||||
// List<IServiceEndpointConfiguration> serviceEndpointConfigurations
|
||||
// = new List<IServiceEndpointConfiguration> { httpEndpoint, oracleEndpoint };
|
||||
|
||||
// IServiceEndpointConfiguration.SaveConfigurationList(serviceEndpointConfigurations, _testFilename);
|
||||
|
||||
// // load the results
|
||||
// List<IServiceEndpointConfiguration> loadedList = IServiceEndpointConfiguration.LoadConfigurationList(_testFilename);
|
||||
|
||||
// // verify that they're the same
|
||||
// foreach (IServiceEndpointConfiguration serviceEndpointConfiguration in serviceEndpointConfigurations)
|
||||
// {
|
||||
// IServiceEndpointConfiguration tmp = serviceEndpointConfiguration;
|
||||
|
||||
// IServiceEndpointConfiguration foundConfig
|
||||
// = loadedList.Find(loadedEndpointConfig => loadedEndpointConfig.Equals(tmp));
|
||||
// Assert.IsNotNull(foundConfig);
|
||||
// }
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// FileInfo f = new FileInfo(_testFilename);
|
||||
// // f.CopyTo(@"c:\test.xml");
|
||||
// if (f.Exists)
|
||||
// f.Delete();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Endpoint;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace EndpointTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Functional Tests for SoapEndpoint
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public class SoapEndpointTest
|
||||
{
|
||||
// Random internet webservice
|
||||
private const string URISTRING = @"http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php";
|
||||
|
||||
private const string SOAPACTION =
|
||||
@"http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl#GmlTimeSeries";
|
||||
|
||||
private const string SOAPREQUEST =
|
||||
@"<soapenv:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:ndf=""http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl"">"
|
||||
+ @" <soapenv:Header/>"
|
||||
+ @" <soapenv:Body>"
|
||||
+ @" <ndf:GmlTimeSeries soapenv:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/"">"
|
||||
+ @" <listLatLon xsi:type=""dwml:listLatLonType"" xmlns:dwml=""http://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd"">?</listLatLon>"
|
||||
+ @" <startTime xsi:type=""xsd:dateTime"">?</startTime>"
|
||||
+ @" <endTime xsi:type=""xsd:dateTime"">?</endTime>"
|
||||
+ @" <compType xsi:type=""dwml:compTypeType"" xmlns:dwml=""http://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd"">?</compType>"
|
||||
+ @" <featureType xsi:type=""dwml:featureTypeType"" xmlns:dwml=""http://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd"">?</featureType>"
|
||||
+ @" <propertyName xsi:type=""xsd:string"">?</propertyName>"
|
||||
+ @" </ndf:GmlTimeSeries>"
|
||||
+ @" </soapenv:Body>"
|
||||
+ @"</soapenv:Envelope>";
|
||||
|
||||
private const string XPATHNAMESPACES =
|
||||
@"a,http://www.opengis.net/ows";
|
||||
|
||||
private const string XPATHQUERY =
|
||||
@"//a:Exception[1]/@ExceptionText";
|
||||
|
||||
private const string EXPECTEDXPATHRESULT =
|
||||
@"VERSION key not found";
|
||||
|
||||
/// <summary>
|
||||
/// Runs GetStatus
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetStatusTest()
|
||||
{
|
||||
var target = new SoapEndpoint
|
||||
{
|
||||
UriString = URISTRING,
|
||||
XpathQuery = XPATHQUERY,
|
||||
ExpectedXpathResult = EXPECTEDXPATHRESULT,
|
||||
SoapAction = SOAPACTION,
|
||||
SoapRequest = SOAPREQUEST,
|
||||
XpathNamespaces = XPATHNAMESPACES
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Up, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Endpoint;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace EndpointTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests for WindowsServiceEndpoint
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public class WindowsServiceEndpointTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Use a service that should always be running on localhost
|
||||
/// </summary>
|
||||
private const string SERVICENAME = "Windows Time";
|
||||
|
||||
/// <summary>
|
||||
/// Runs GetStatus
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetStatusTest()
|
||||
{
|
||||
var target = new WindowsServiceEndpoint
|
||||
{
|
||||
ServiceName = SERVICENAME
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Up, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
using Endpoint;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace EndpointTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests for WmiEndpoint
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public class WmiEndpointTest
|
||||
{
|
||||
private const string MACHINENAME = @"\\localhost";
|
||||
|
||||
/// <summary>
|
||||
/// Run GetStatus using "UpResult" expecting an up status.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetStatusUpPositiveTest()
|
||||
{
|
||||
var target = new WmiEndpoint
|
||||
{
|
||||
MachineName = MACHINENAME,
|
||||
ObjectQueryString = "Select * from Win32_Process",
|
||||
ResultPropertyName = "Name",
|
||||
UpResult = "System Idle Process"
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Up, status);
|
||||
Assert.AreEqual("System Idle Process", target.StatusDescription);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run GetStatus using "UpResult" expecting an error status.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetStatusUpNegativeTest()
|
||||
{
|
||||
var target = new WmiEndpoint
|
||||
{
|
||||
MachineName = MACHINENAME,
|
||||
ObjectQueryString = "Select * from Win32_Process",
|
||||
ResultPropertyName = "Name",
|
||||
UpResult = "Not A Real Process"
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Error, status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run GetStatus using "ErrorResult" expecting an error status.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetStatusErrorPositiveTest()
|
||||
{
|
||||
var target = new WmiEndpoint
|
||||
{
|
||||
MachineName = MACHINENAME,
|
||||
ObjectQueryString = "Select * from Win32_Process",
|
||||
ResultPropertyName = "Name",
|
||||
ErrorResult = "System Idle Process"
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Error, status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run GetStatus using "MinimumThreshold" expecting an up status.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetStatusMinimumThresholdPositiveTest()
|
||||
{
|
||||
var target = new WmiEndpoint
|
||||
{
|
||||
MachineName = MACHINENAME,
|
||||
ObjectQueryString = "select FreeSpace from Win32_LogicalDisk where DeviceID='C:'",
|
||||
ResultPropertyName = "FreeSpace",
|
||||
MinimumThreshold = 10 // assume you have more than 10B free on C:
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Up, status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run GetStatus using "MinimumThreshold" expecting an up status.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetStatusMinimumThresholdNegativeTest()
|
||||
{
|
||||
var target = new WmiEndpoint
|
||||
{
|
||||
MachineName = MACHINENAME,
|
||||
ObjectQueryString = "select FreeSpace from Win32_LogicalDisk where DeviceID='C:'",
|
||||
ResultPropertyName = "FreeSpace",
|
||||
MinimumThreshold = 1e15 // assume you have less than a petabyte free on C:
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Error, status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run GetStatus using "MaximumThreshold" expecting an up status.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetStatusMaximumThresholdPositiveTest()
|
||||
{
|
||||
var target = new WmiEndpoint
|
||||
{
|
||||
MachineName = MACHINENAME,
|
||||
ObjectQueryString = "select FreeSpace from Win32_LogicalDisk where DeviceID='C:'",
|
||||
ResultPropertyName = "FreeSpace",
|
||||
MaximumThreshold = 1e15 // assume you have less than a petabyte free on C:
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Up, status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run GetStatus using "MaximumThreshold" expecting an up status.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetStatusMaximumThresholdNegativeTest()
|
||||
{
|
||||
var target = new WmiEndpoint
|
||||
{
|
||||
MachineName = MACHINENAME,
|
||||
ObjectQueryString = "select FreeSpace from Win32_LogicalDisk where DeviceID='C:'",
|
||||
ResultPropertyName = "FreeSpace",
|
||||
MaximumThreshold = 10 // assume you have less than a 10B free on C:
|
||||
};
|
||||
|
||||
var status = target.GetStatus();
|
||||
Assert.AreEqual(Status.Error, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TestRunConfiguration name="Local Test Run" id="cb3ceb6c-2083-4222-b0c1-dda7a0f3b136" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
|
||||
<Description>This is a default test run configuration for a local test run.</Description>
|
||||
<TestTypeSpecific />
|
||||
</TestRunConfiguration>
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DA481DF1-5754-4499-AEA2-21F809256F35}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
LocalTestRun.testrunconfig = LocalTestRun.testrunconfig
|
||||
ServiceDashBored.vsmdi = ServiceDashBored.vsmdi
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceDashBored", "ServiceDashBored\ServiceDashBored.csproj", "{2D46A996-7DEF-4592-B401-70090686B3F2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Endpoint", "Endpoint\Endpoint.csproj", "{7686BAA6-A0C5-4FA5-BE6E-FA044C2FFDD4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EndpointTest", "EndpointTest\EndpointTest.csproj", "{76D78812-B640-4EF0-957B-15D0E9000A84}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(TestCaseManagementSettings) = postSolution
|
||||
CategoryFile = ServiceDashBored.vsmdi
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2D46A996-7DEF-4592-B401-70090686B3F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2D46A996-7DEF-4592-B401-70090686B3F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2D46A996-7DEF-4592-B401-70090686B3F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2D46A996-7DEF-4592-B401-70090686B3F2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7686BAA6-A0C5-4FA5-BE6E-FA044C2FFDD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7686BAA6-A0C5-4FA5-BE6E-FA044C2FFDD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7686BAA6-A0C5-4FA5-BE6E-FA044C2FFDD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7686BAA6-A0C5-4FA5-BE6E-FA044C2FFDD4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{76D78812-B640-4EF0-957B-15D0E9000A84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{76D78812-B640-4EF0-957B-15D0E9000A84}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{76D78812-B640-4EF0-957B-15D0E9000A84}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{76D78812-B640-4EF0-957B-15D0E9000A84}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
|
||||
<TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
|
||||
<RunConfiguration id="cb3ceb6c-2083-4222-b0c1-dda7a0f3b136" name="Local Test Run" storage="localtestrun.testrunconfig" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
</TestList>
|
||||
</TestLists>
|
||||
@@ -0,0 +1,309 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using BitFactory.Logging;
|
||||
using Endpoint;
|
||||
using ServiceDashBored.Properties;
|
||||
|
||||
namespace ServiceDashBored
|
||||
{
|
||||
/// <summary>
|
||||
/// Monitors a single Endpoint's Status
|
||||
/// </summary>
|
||||
public class EndpointStatus : INotifyPropertyChanged, IDisposable
|
||||
{
|
||||
#region Private Members
|
||||
|
||||
private readonly IEndpoint _endpoint;
|
||||
private readonly Timer _lastUpdateTimer;
|
||||
private DateTime _lastUpdate;
|
||||
private readonly Logger _logger;
|
||||
private readonly TimeSpan _updatePeriod;
|
||||
private static readonly object _propertyUpdateSyncObject = new Object();
|
||||
private static readonly object _callbackSyncObject = new Object();
|
||||
private bool _insideCallback;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the icon based on the status.
|
||||
/// </summary>
|
||||
public Icon StatusIcon { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets service's current status.
|
||||
/// </summary>
|
||||
/// <value>The status.</value>
|
||||
public Status Status { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string explaining details on the current status
|
||||
/// </summary>
|
||||
public string StatusDescription { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time since the last update
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string TimeSinceLastUpdate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_lastUpdate == DateTime.MinValue)
|
||||
return "never";
|
||||
if (_lastUpdate == DateTime.MaxValue)
|
||||
return "updating";
|
||||
|
||||
var timeSpan = DateTime.Now - _lastUpdate;
|
||||
if (timeSpan.Minutes > 0 )
|
||||
return String.Format("{0}m {1}s", timeSpan.Minutes, timeSpan.Seconds);
|
||||
return
|
||||
timeSpan.Seconds + 1 + "s";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the service.
|
||||
/// </summary>
|
||||
/// <value>The name of the service.</value>
|
||||
public string ServiceName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _endpoint.Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the last update time.
|
||||
/// </summary>
|
||||
/// <value>The last update time.</value>
|
||||
private DateTime lastUpdate
|
||||
{
|
||||
set
|
||||
{
|
||||
_lastUpdate = value;
|
||||
SignalPropertyChanged("TimeSinceLastUpdate");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Callback for the <c>threadpool</c>
|
||||
/// </summary>
|
||||
/// <param name="threadContext">The thread context.</param>
|
||||
/// <param name="isTimeOut">The callback was triggered from a timeout</param>
|
||||
public void ThreadPoolCallback(object threadContext, bool isTimeOut)
|
||||
{
|
||||
lock(_callbackSyncObject)
|
||||
{
|
||||
if (_insideCallback)
|
||||
return;
|
||||
_insideCallback = true;
|
||||
}
|
||||
try
|
||||
{
|
||||
// turn off the timer while waiting for an update
|
||||
_lastUpdateTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
updateStatus();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// log exception
|
||||
_logger.LogError(_endpoint.Name + ": " + ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lastUpdateTimer.Change(_updatePeriod, _updatePeriod);
|
||||
_insideCallback = false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status result of the endpoint
|
||||
/// </summary>
|
||||
/// <returns>Status</returns>
|
||||
private void updateStatus()
|
||||
{
|
||||
lastUpdate = DateTime.MaxValue;
|
||||
var newStatus = _endpoint.GetStatus();
|
||||
if (Status != newStatus)
|
||||
{
|
||||
Status = newStatus;
|
||||
StatusDescription = _endpoint.StatusDescription;
|
||||
StatusIcon = GetStatusIcon(Status);
|
||||
// NOTE: wait to signal the property changes until all of them have been updated
|
||||
SignalPropertyChanged("Status");
|
||||
SignalPropertyChanged("StatusDescription");
|
||||
SignalPropertyChanged("StatusIcon");
|
||||
}
|
||||
lastUpdate = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for the timer
|
||||
/// </summary>
|
||||
/// <param name="obj">The obj.</param>
|
||||
private void timerCallback(object obj)
|
||||
{
|
||||
SignalPropertyChanged("TimeSinceLastUpdate");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets the status icon.
|
||||
/// </summary>
|
||||
/// <param name="status">The status.</param>
|
||||
/// <returns></returns>
|
||||
public static Icon GetStatusIcon(Status status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case Status.Unknown:
|
||||
return Resources.question;
|
||||
case Status.Up:
|
||||
return Resources.up;
|
||||
case Status.Error:
|
||||
case Status.Unreachable:
|
||||
return Resources.remove;
|
||||
case Status.Timeout:
|
||||
return Resources.warning;
|
||||
default:
|
||||
return Resources.up;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EndpointStatus"/> class.
|
||||
/// </summary>
|
||||
/// <param name="endpoint">The endpoint.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public EndpointStatus(IEndpoint endpoint, Logger logger)
|
||||
{
|
||||
_endpoint = endpoint;
|
||||
lastUpdate = DateTime.MinValue;
|
||||
_logger = logger;
|
||||
_updatePeriod = new TimeSpan(0, 0, 0, 1);
|
||||
_lastUpdateTimer = new Timer(timerCallback, 0, _updatePeriod, _updatePeriod);
|
||||
StatusIcon = GetStatusIcon(Status);
|
||||
Status = Status.Unknown;
|
||||
StatusDescription = string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PropertyChanged event
|
||||
|
||||
///<summary>
|
||||
///Occurs when a property value changes.
|
||||
///</summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PropertyChanged methods
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the property (<paramref name="propertyName"/>) has been updated or changed.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property.</param>
|
||||
/// <param name="oldValue">The old value.</param>
|
||||
/// <param name="newValue">The new value.</param>
|
||||
/// <returns>True if the value was updated, false otherwise.</returns>
|
||||
protected bool CheckPropertyChanged<T>(string propertyName, ref T oldValue, ref T newValue) where T : class
|
||||
{
|
||||
if (oldValue == null && newValue == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (oldValue == null || !oldValue.Equals(newValue))
|
||||
{
|
||||
oldValue = newValue;
|
||||
|
||||
SignalPropertyChanged(propertyName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the property (<paramref name="propertyName"/>) has been updated or changed.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property.</param>
|
||||
/// <param name="oldValue">The old value.</param>
|
||||
/// <param name="newValue">The new value.</param>
|
||||
/// <returns>True if the value was updated, false otherwise.</returns>
|
||||
protected bool CheckValuePropertyChanged<T>(string propertyName, ref T oldValue, ref T newValue) where T : struct
|
||||
{
|
||||
if (!oldValue.Equals(newValue))
|
||||
{
|
||||
oldValue = newValue;
|
||||
|
||||
SignalPropertyChanged(propertyName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the event that a property has changed value
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
protected void SignalPropertyChanged(string propertyName)
|
||||
{
|
||||
if (PropertyChanged == null)
|
||||
return;
|
||||
try
|
||||
{
|
||||
lock (_propertyUpdateSyncObject) // send only one property changed event at once
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException) // HACK: Ignore the "BindingSource cannot be its own data source."
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning("SignalPropertyChanged: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable
|
||||
|
||||
///<summary>
|
||||
///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
///</summary>
|
||||
///<filterpriority>2</filterpriority>
|
||||
public void Dispose()
|
||||
{
|
||||
_lastUpdateTimer.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Generated
+256
@@ -0,0 +1,256 @@
|
||||
namespace ServiceDashBored
|
||||
{
|
||||
partial class Main
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (notifyIcon != null)
|
||||
{
|
||||
notifyIcon.Visible = false;
|
||||
notifyIcon.Dispose();
|
||||
notifyIcon = null;
|
||||
}
|
||||
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main));
|
||||
this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
|
||||
this.trayContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.dataGridView = new System.Windows.Forms.DataGridView();
|
||||
this.statusIconDataGridViewImageColumn = new System.Windows.Forms.DataGridViewImageColumn();
|
||||
this.ServiceName = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.TimeSinceLastUpdate = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.endpointBindingSource = new System.Windows.Forms.BindingSource(this.components);
|
||||
this.cellTextBox = new System.Windows.Forms.TextBox();
|
||||
this.statusTextBox = new System.Windows.Forms.RichTextBox();
|
||||
this.splitContainer = new System.Windows.Forms.SplitContainer();
|
||||
this.dataGridContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.updateNowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.trayContextMenuStrip.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.endpointBindingSource)).BeginInit();
|
||||
this.splitContainer.Panel1.SuspendLayout();
|
||||
this.splitContainer.Panel2.SuspendLayout();
|
||||
this.splitContainer.SuspendLayout();
|
||||
this.dataGridContextMenuStrip.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// notifyIcon
|
||||
//
|
||||
this.notifyIcon.ContextMenuStrip = this.trayContextMenuStrip;
|
||||
this.notifyIcon.Text = "Service DashBored";
|
||||
this.notifyIcon.Visible = true;
|
||||
this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.notifyIcon_MouseDoubleClick);
|
||||
//
|
||||
// trayContextMenuStrip
|
||||
//
|
||||
this.trayContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.exitToolStripMenuItem});
|
||||
this.trayContextMenuStrip.Name = "trayContextMenuStrip";
|
||||
this.trayContextMenuStrip.Size = new System.Drawing.Size(104, 26);
|
||||
//
|
||||
// exitToolStripMenuItem
|
||||
//
|
||||
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
|
||||
this.exitToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
|
||||
this.exitToolStripMenuItem.Text = "Exit";
|
||||
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
|
||||
//
|
||||
// dataGridView
|
||||
//
|
||||
this.dataGridView.AllowUserToAddRows = false;
|
||||
this.dataGridView.AllowUserToDeleteRows = false;
|
||||
this.dataGridView.AllowUserToResizeColumns = false;
|
||||
this.dataGridView.AllowUserToResizeRows = false;
|
||||
this.dataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.dataGridView.AutoGenerateColumns = false;
|
||||
this.dataGridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
|
||||
this.dataGridView.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.DisplayedCells;
|
||||
this.dataGridView.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.dataGridView.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None;
|
||||
this.dataGridView.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
|
||||
this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
|
||||
this.dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||
this.statusIconDataGridViewImageColumn,
|
||||
this.ServiceName,
|
||||
this.TimeSinceLastUpdate});
|
||||
this.dataGridView.DataSource = this.endpointBindingSource;
|
||||
this.dataGridView.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
|
||||
this.dataGridView.EnableHeadersVisualStyles = false;
|
||||
this.dataGridView.Location = new System.Drawing.Point(12, 12);
|
||||
this.dataGridView.MultiSelect = false;
|
||||
this.dataGridView.Name = "dataGridView";
|
||||
this.dataGridView.ReadOnly = true;
|
||||
this.dataGridView.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
|
||||
this.dataGridView.RowHeadersVisible = false;
|
||||
this.dataGridView.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
|
||||
this.dataGridView.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
|
||||
this.dataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||
this.dataGridView.Size = new System.Drawing.Size(368, 126);
|
||||
this.dataGridView.TabIndex = 1;
|
||||
this.dataGridView.RowEnter += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_RowEnter);
|
||||
this.dataGridView.MouseUp += new System.Windows.Forms.MouseEventHandler(this.dataGridView_MouseUp);
|
||||
this.dataGridView.DataError += new System.Windows.Forms.DataGridViewDataErrorEventHandler(this.dataGridView_DataError);
|
||||
//
|
||||
// statusIconDataGridViewImageColumn
|
||||
//
|
||||
this.statusIconDataGridViewImageColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
|
||||
this.statusIconDataGridViewImageColumn.DataPropertyName = "StatusIcon";
|
||||
this.statusIconDataGridViewImageColumn.HeaderText = "";
|
||||
this.statusIconDataGridViewImageColumn.Name = "statusIconDataGridViewImageColumn";
|
||||
this.statusIconDataGridViewImageColumn.ReadOnly = true;
|
||||
this.statusIconDataGridViewImageColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this.statusIconDataGridViewImageColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
|
||||
this.statusIconDataGridViewImageColumn.Width = 30;
|
||||
//
|
||||
// ServiceName
|
||||
//
|
||||
this.ServiceName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
||||
this.ServiceName.DataPropertyName = "ServiceName";
|
||||
this.ServiceName.HeaderText = "Service";
|
||||
this.ServiceName.MinimumWidth = 100;
|
||||
this.ServiceName.Name = "ServiceName";
|
||||
this.ServiceName.ReadOnly = true;
|
||||
//
|
||||
// TimeSinceLastUpdate
|
||||
//
|
||||
this.TimeSinceLastUpdate.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
|
||||
this.TimeSinceLastUpdate.DataPropertyName = "TimeSinceLastUpdate";
|
||||
this.TimeSinceLastUpdate.HeaderText = "Last Update";
|
||||
this.TimeSinceLastUpdate.Name = "TimeSinceLastUpdate";
|
||||
this.TimeSinceLastUpdate.ReadOnly = true;
|
||||
this.TimeSinceLastUpdate.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this.TimeSinceLastUpdate.Width = 90;
|
||||
//
|
||||
// endpointBindingSource
|
||||
//
|
||||
this.endpointBindingSource.DataSource = typeof(ServiceDashBored.EndpointStatus);
|
||||
//
|
||||
// cellTextBox
|
||||
//
|
||||
this.cellTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cellTextBox.Location = new System.Drawing.Point(12, 144);
|
||||
this.cellTextBox.Name = "cellTextBox";
|
||||
this.cellTextBox.ReadOnly = true;
|
||||
this.cellTextBox.Size = new System.Drawing.Size(368, 20);
|
||||
this.cellTextBox.TabIndex = 2;
|
||||
//
|
||||
// statusTextBox
|
||||
//
|
||||
this.statusTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.statusTextBox.BackColor = System.Drawing.SystemColors.Window;
|
||||
this.statusTextBox.Location = new System.Drawing.Point(12, 3);
|
||||
this.statusTextBox.Name = "statusTextBox";
|
||||
this.statusTextBox.ReadOnly = true;
|
||||
this.statusTextBox.Size = new System.Drawing.Size(368, 85);
|
||||
this.statusTextBox.TabIndex = 3;
|
||||
this.statusTextBox.Text = "";
|
||||
//
|
||||
// splitContainer
|
||||
//
|
||||
this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.splitContainer.Location = new System.Drawing.Point(0, 0);
|
||||
this.splitContainer.Name = "splitContainer";
|
||||
this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
|
||||
//
|
||||
// splitContainer.Panel1
|
||||
//
|
||||
this.splitContainer.Panel1.Controls.Add(this.cellTextBox);
|
||||
this.splitContainer.Panel1.Controls.Add(this.dataGridView);
|
||||
this.splitContainer.Panel1MinSize = 135;
|
||||
//
|
||||
// splitContainer.Panel2
|
||||
//
|
||||
this.splitContainer.Panel2.Controls.Add(this.statusTextBox);
|
||||
this.splitContainer.Panel2MinSize = 100;
|
||||
this.splitContainer.Size = new System.Drawing.Size(392, 270);
|
||||
this.splitContainer.SplitterDistance = 166;
|
||||
this.splitContainer.SplitterWidth = 3;
|
||||
this.splitContainer.TabIndex = 4;
|
||||
//
|
||||
// dataGridContextMenuStrip
|
||||
//
|
||||
this.dataGridContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.updateNowToolStripMenuItem});
|
||||
this.dataGridContextMenuStrip.Name = "dataGridContextMenuStrip";
|
||||
this.dataGridContextMenuStrip.Size = new System.Drawing.Size(145, 26);
|
||||
//
|
||||
// updateNowToolStripMenuItem
|
||||
//
|
||||
this.updateNowToolStripMenuItem.Name = "updateNowToolStripMenuItem";
|
||||
this.updateNowToolStripMenuItem.Size = new System.Drawing.Size(144, 22);
|
||||
this.updateNowToolStripMenuItem.Text = "Update Now";
|
||||
this.updateNowToolStripMenuItem.Click += new System.EventHandler(this.updateNowToolStripMenuItem_Click);
|
||||
//
|
||||
// Main
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(392, 270);
|
||||
this.Controls.Add(this.splitContainer);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MaximizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(400, 300);
|
||||
this.Name = "Main";
|
||||
this.Text = "Service DashBored";
|
||||
this.Load += new System.EventHandler(this.main_Load);
|
||||
this.Resize += new System.EventHandler(this.main_Resize);
|
||||
this.trayContextMenuStrip.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.endpointBindingSource)).EndInit();
|
||||
this.splitContainer.Panel1.ResumeLayout(false);
|
||||
this.splitContainer.Panel1.PerformLayout();
|
||||
this.splitContainer.Panel2.ResumeLayout(false);
|
||||
this.splitContainer.ResumeLayout(false);
|
||||
this.dataGridContextMenuStrip.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.NotifyIcon notifyIcon;
|
||||
private System.Windows.Forms.ContextMenuStrip trayContextMenuStrip;
|
||||
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
|
||||
private System.Windows.Forms.DataGridView dataGridView;
|
||||
private System.Windows.Forms.BindingSource endpointBindingSource;
|
||||
private System.Windows.Forms.TextBox cellTextBox;
|
||||
private System.Windows.Forms.DataGridViewImageColumn statusIconDataGridViewImageColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn TimeSinceLastUpdate;
|
||||
private System.Windows.Forms.RichTextBox statusTextBox;
|
||||
private System.Windows.Forms.SplitContainer splitContainer;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn ServiceName;
|
||||
private System.Windows.Forms.ContextMenuStrip dataGridContextMenuStrip;
|
||||
private System.Windows.Forms.ToolStripMenuItem updateNowToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,428 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using BitFactory.Logging;
|
||||
using Endpoint;
|
||||
|
||||
namespace ServiceDashBored
|
||||
{
|
||||
/// <summary>
|
||||
/// DashBored's UI.
|
||||
/// </summary>
|
||||
public partial class Main : Form
|
||||
{
|
||||
/// <summary>
|
||||
/// Number of seconds between trying to poll an endpoint for its status
|
||||
/// </summary>
|
||||
private const int ENDPOINT_POLL_TIME_INTERVAL = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Number of milliseconds to display status updates on the system tray notify balloon
|
||||
/// </summary>
|
||||
private const int NOTIFY_BALLOON_UPDATE_DELAY = 300;
|
||||
|
||||
/// <summary>
|
||||
/// Win32 message for when the user ends their session.
|
||||
/// </summary>
|
||||
/// <remarks>http://msdn.microsoft.com/en-us/library/aa376890(VS.85).aspx</remarks>
|
||||
private const int WM_QUERYENDSESSION = 0x11;
|
||||
|
||||
/// <summary>
|
||||
/// The status to display in the system tray
|
||||
/// </summary>
|
||||
private Status _systemTrayStatusIcon = Status.Timeout;
|
||||
private readonly BindingList<EndpointStatus> _endpoints;
|
||||
private readonly Dictionary<EndpointStatus, Status> _endpointStatuses;
|
||||
private readonly Dictionary<EndpointStatus, EventWaitHandle> _endpointEventWaitHandle;
|
||||
|
||||
/// <summary>
|
||||
/// Default font for the Status Description text box
|
||||
/// </summary>
|
||||
private readonly Font _defaultFont = new Font("Microsoft Sans Serif", (float)8.25, FontStyle.Regular);
|
||||
/// <summary>
|
||||
/// Bold font for the Status Description text box
|
||||
/// </summary>
|
||||
private readonly Font _boldFont = new Font("Microsoft Sans Serif", (float)8.25, FontStyle.Bold);
|
||||
/// <summary>
|
||||
/// Different colors to use for each Status
|
||||
/// </summary>
|
||||
private readonly Dictionary<Status, Color> _statusColor
|
||||
= new Dictionary<Status, Color>
|
||||
{
|
||||
{Status.Error, Color.DarkRed},
|
||||
{Status.Timeout, Color.DarkOrange},
|
||||
{Status.Unknown, Color.DarkOrange},
|
||||
{Status.Unreachable, Color.DarkRed},
|
||||
{Status.Up, Color.DarkGreen},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Set to true when windows is closing the current session.
|
||||
/// </summary>
|
||||
private bool _endSessionPending;
|
||||
|
||||
/// <summary>
|
||||
/// Logger instance.
|
||||
/// </summary>
|
||||
private readonly Logger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Main"/> class.
|
||||
/// </summary>
|
||||
public Main(IEnumerable<IEndpoint> endpoints, Logger logger)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_logger.LogInfo("Starting.");
|
||||
|
||||
loadMainIcon(Status.Up);
|
||||
|
||||
_endpoints = new BindingList<EndpointStatus>();
|
||||
endpointBindingSource.DataSource = _endpoints;
|
||||
_endpointStatuses = new Dictionary<EndpointStatus, Status>();
|
||||
_endpointEventWaitHandle = new Dictionary<EndpointStatus, EventWaitHandle>();
|
||||
|
||||
foreach (var serviceEndpoint in endpoints)
|
||||
{
|
||||
registerServiceEndpoint(serviceEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override to intercept WM_QUERYENDSESSION - so we know when the current OS session is ending.
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
/// <remarks>http://www.pixvillage.com/blogs/devblog/archive/2005/03/26/174.aspx</remarks>
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
if (m.Msg == WM_QUERYENDSESSION)
|
||||
_endSessionPending = true;
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimize when the close button is clicked
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected override void OnClosing(CancelEventArgs e)
|
||||
{
|
||||
if (!_endSessionPending)
|
||||
{
|
||||
e.Cancel = true;
|
||||
WindowState = FormWindowState.Minimized; // minimize instead of close
|
||||
}
|
||||
base.OnClosing(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Resize event of the Main control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
|
||||
void main_Resize(object sender, EventArgs e)
|
||||
{
|
||||
ShowInTaskbar = WindowState != FormWindowState.Minimized;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Load event of the Main control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
|
||||
private void main_Load(object sender, EventArgs e)
|
||||
{
|
||||
notifyIcon.BalloonTipTitle = "Service DashBored";
|
||||
notifyIcon.BalloonTipClicked += notifyIcon_BalloonTipClicked;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the PropertyChanged event of an Endpoint.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param>
|
||||
void endpoint_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName != "Status") return;
|
||||
|
||||
var senderEndpointStatus = sender as EndpointStatus;
|
||||
if (senderEndpointStatus == null)
|
||||
throw new ArgumentException("sender is not EndpointStatus - it is: " + sender.GetType());
|
||||
|
||||
Invoke((MethodInvoker)(()=>updateStatus(senderEndpointStatus)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the BalloonTipClicked event of the notifyIcon control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
|
||||
void notifyIcon_BalloonTipClicked(object sender, EventArgs e)
|
||||
{
|
||||
TopMost = true;
|
||||
WindowState = FormWindowState.Normal;
|
||||
Focus();
|
||||
TopMost = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Click event of the exitToolStripMenuItem control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
|
||||
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
_logger.LogInfo("User Exiting.");
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When notify is double clicked, show the main window
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (WindowState == FormWindowState.Normal)
|
||||
{
|
||||
WindowState = FormWindowState.Minimized;
|
||||
}
|
||||
else
|
||||
{
|
||||
TopMost = true;
|
||||
WindowState = FormWindowState.Normal;
|
||||
Focus();
|
||||
TopMost = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void dataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
var endpointStatus = (EndpointStatus)dataGridView.Rows[e.RowIndex].DataBoundItem;
|
||||
cellTextBox.Text = string.Format("{0}. Status Description: {1}",
|
||||
endpointStatus.ServiceName, endpointStatus.StatusDescription);
|
||||
}
|
||||
|
||||
private void dataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
|
||||
{
|
||||
_logger.LogError(e.Exception);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the service endpoint.
|
||||
/// </summary>
|
||||
/// <param name="endpoint">The service endpoint.</param>
|
||||
private void registerServiceEndpoint(IEndpoint endpoint)
|
||||
{
|
||||
var endpointStatus = new EndpointStatus(endpoint, _logger);
|
||||
|
||||
// Time Interval MasterThread will be executed
|
||||
var timeOut = TimeSpan.FromSeconds(ENDPOINT_POLL_TIME_INTERVAL);
|
||||
|
||||
// Register a timed callback method in the threadpool.
|
||||
var waitObject = new AutoResetEvent(false);
|
||||
ThreadPool.RegisterWaitForSingleObject(
|
||||
waitObject,
|
||||
endpointStatus.ThreadPoolCallback,
|
||||
null,
|
||||
timeOut,
|
||||
false
|
||||
);
|
||||
|
||||
_endpoints.Add(endpointStatus);
|
||||
_endpointStatuses.Add(endpointStatus, endpointStatus.Status);
|
||||
_endpointEventWaitHandle.Add(endpointStatus, waitObject);
|
||||
endpointStatus.PropertyChanged += endpoint_PropertyChanged;
|
||||
|
||||
waitObject.Set(); // signal an initial callback when done registying
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the icon based on the status.
|
||||
/// </summary>
|
||||
/// <param name="status">The status.</param>
|
||||
private void loadMainIcon(Status status)
|
||||
{
|
||||
if (_systemTrayStatusIcon == status)
|
||||
return;
|
||||
|
||||
notifyIcon.Icon = EndpointStatus.GetStatusIcon(status);
|
||||
|
||||
notifyIcon.BalloonTipIcon = (status == Status.Up) ? ToolTipIcon.Info : ToolTipIcon.Error;
|
||||
|
||||
_systemTrayStatusIcon = status;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the status for the given endpoint.
|
||||
/// </summary>
|
||||
/// <remarks>Execute on UI thread</remarks>
|
||||
/// <param name="endpointStatus">The endpoint status.</param>
|
||||
private void updateStatus(EndpointStatus endpointStatus)
|
||||
{
|
||||
if (endpointStatus == null)
|
||||
throw new ArgumentNullException("endpointStatus");
|
||||
|
||||
lock (_endpoints)
|
||||
{
|
||||
// if the status hasn't changed, don't do anything...
|
||||
if (_endpointStatuses[endpointStatus] == endpointStatus.Status) return;
|
||||
|
||||
// if the status has changed...
|
||||
var oldStatus = _endpointStatuses[endpointStatus];
|
||||
_endpointStatuses[endpointStatus] = endpointStatus.Status;
|
||||
|
||||
// find the worst status of all
|
||||
var statuses = new List<Status>(_endpointStatuses.Values);
|
||||
statuses.Sort(new StatusComparer());
|
||||
loadMainIcon(statuses[0]);
|
||||
|
||||
// update the system tray notify ballon info
|
||||
notifyIcon.BalloonTipText = getShortServiceStatusMessage(endpointStatus);
|
||||
notifyIcon.Text = endpointStatus.Status == Status.Up ? "Service Running" : "Service Problem";
|
||||
|
||||
// update the info in the status text box
|
||||
updateStatusTextBox();
|
||||
|
||||
if (oldStatus != Status.Unknown || endpointStatus.Status != Status.Up)
|
||||
{
|
||||
notifyIcon.ShowBalloonTip(NOTIFY_BALLOON_UPDATE_DELAY);
|
||||
_logger.LogInfo(string.Format("{0}. {1} : {2}", endpointStatus.ServiceName, endpointStatus.Status,
|
||||
endpointStatus.StatusDescription));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the status text box - call this from the UI thread.
|
||||
/// </summary>
|
||||
private void updateStatusTextBox()
|
||||
{
|
||||
statusTextBox.Text = String.Empty;
|
||||
var first = true;
|
||||
foreach (var endpointStatus in _endpoints)
|
||||
{
|
||||
if (endpointStatus.Status == Status.Up || endpointStatus.Status == Status.Unknown)
|
||||
continue;
|
||||
|
||||
if (!first)
|
||||
{
|
||||
statusTextBox.SelectedText = Environment.NewLine + Environment.NewLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
|
||||
// Make the service description all pretty in the rich text box
|
||||
statusTextBox.SelectionColor = _statusColor[endpointStatus.Status];
|
||||
statusTextBox.SelectionFont = _defaultFont;
|
||||
statusTextBox.SelectedText = endpointStatus.ServiceName;
|
||||
|
||||
statusTextBox.SelectionColor = Color.Black;
|
||||
statusTextBox.SelectionFont = _defaultFont;
|
||||
statusTextBox.SelectedText = ". ";
|
||||
|
||||
statusTextBox.SelectionColor = _statusColor[endpointStatus.Status];
|
||||
statusTextBox.SelectionFont = _boldFont;
|
||||
statusTextBox.SelectedText = endpointStatus.Status.ToString();
|
||||
|
||||
statusTextBox.SelectionColor = Color.Black;
|
||||
statusTextBox.SelectionFont = _defaultFont;
|
||||
statusTextBox.SelectedText = " : " + endpointStatus.StatusDescription;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the service status message.
|
||||
/// </summary>
|
||||
/// <param name="senderEndpointStatus">The sender endpoint status.</param>
|
||||
/// <returns></returns>
|
||||
private static string getShortServiceStatusMessage(EndpointStatus senderEndpointStatus)
|
||||
{
|
||||
var msg = string.Empty;
|
||||
switch (senderEndpointStatus.Status)
|
||||
{
|
||||
case Status.Error:
|
||||
msg = "Service Error: " + senderEndpointStatus.ServiceName;
|
||||
break;
|
||||
case Status.Timeout:
|
||||
msg = "Service Timeout: " + senderEndpointStatus.ServiceName;
|
||||
break;
|
||||
case Status.Unknown:
|
||||
msg = "Status Unknown: " + senderEndpointStatus.ServiceName;
|
||||
break;
|
||||
case Status.Unreachable:
|
||||
msg = "Service Unreachable: " + senderEndpointStatus.ServiceName;
|
||||
break;
|
||||
case Status.Up:
|
||||
msg = "Service Running: " + senderEndpointStatus.ServiceName;
|
||||
break;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
private void dataGridView_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
var hitTestInfo = dataGridView.HitTest(e.X, e.Y);
|
||||
if (hitTestInfo.Type != DataGridViewHitTestType.Cell)
|
||||
{
|
||||
// deselect everything
|
||||
var selectedEndpointStatus = getSelectedDataGridViewRow();
|
||||
if (selectedEndpointStatus != null)
|
||||
selectedEndpointStatus.Selected = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Button == MouseButtons.Right && hitTestInfo.RowIndex >= 0)
|
||||
{
|
||||
// select row on right click as well
|
||||
if (hitTestInfo.RowIndex >= 0)
|
||||
{
|
||||
var selectedEndpointStatus = getSelectedDataGridViewRow();
|
||||
if (selectedEndpointStatus != null)
|
||||
selectedEndpointStatus.Selected = false;
|
||||
|
||||
var clickedRow = dataGridView.Rows[hitTestInfo.RowIndex];
|
||||
clickedRow.Selected = true;
|
||||
}
|
||||
|
||||
// show the context menu
|
||||
dataGridContextMenuStrip.Show(dataGridView, e.Location);
|
||||
}
|
||||
}
|
||||
|
||||
private DataGridViewRow getSelectedDataGridViewRow()
|
||||
{
|
||||
return dataGridView.SelectedRows.Count > 0
|
||||
? dataGridView.Rows[dataGridView.SelectedRows[0].Index]
|
||||
: null;
|
||||
}
|
||||
|
||||
private EndpointStatus getSelectedEndpointStatus()
|
||||
{
|
||||
var dataGridViewRow = getSelectedDataGridViewRow();
|
||||
return dataGridViewRow != null
|
||||
? dataGridViewRow.DataBoundItem as EndpointStatus
|
||||
: null;
|
||||
}
|
||||
|
||||
private void updateNowToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var endpointStatus = getSelectedEndpointStatus();
|
||||
if (endpointStatus != null)
|
||||
_endpointEventWaitHandle[endpointStatus].Set();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="notifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>160, 17</value>
|
||||
</metadata>
|
||||
<metadata name="trayContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="TimeSinceLastUpdate.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="endpointBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>245, 17</value>
|
||||
</metadata>
|
||||
<metadata name="dataGridContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>395, 17</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAEAMDAAAAEAIACoJQAAFgAAACgAAAAwAAAAYAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAADAAAABQAA
|
||||
AAUAAAAFAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABQAAAAUAAAADAAAAAgAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA
|
||||
AAMAAAACAAAACQAAAA0AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADQAAAAkAAAACAAAAAgAA
|
||||
AAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAABAAAAABAPDjQ4NzSmPTw5qURDQKtMSkesU1FNq1hWUqtbWlarV1ZSq1FPTKtKSEWrQkA+qzo5
|
||||
Nqk0MzGnEhIRPQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8uLGWLiIH/hoN9/4iFf/+Kh4H/jImC/42Kg/+NioP/i4iC/4iF
|
||||
f/+EgXz/gH14/3x5df+AfXj/ODc1ggAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8PDiRcWVXsYl9a/15cV/9eW1b/XFpV/1tY
|
||||
VP9aV1P/WVZS/1hWUf9XVVH/V1VQ/1dVUf9UUk70EBAPLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABGRkdZcHFxj3R1doh3d3iIfH19iISEhIhcXFyITk5Pik5OT4hqaWnZenp4/3t6
|
||||
eP99fHr/fn58/39/ff9/f37/f359/319fP98fHr/enp5/3h4d/9ub23oU1RUjFNTVIpeXl+Jg4SFiIKC
|
||||
goh7fHyId3h4iHV2d45MTExcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMTU67SktM/0tMTv9MTU7/TU5P/09QUf9XWFn/W1xd/15f
|
||||
YP9dX2D/X2Fh/2JjZP9kZWf/Zmdp/2hpav9pamv/aWpr/2hqa/9oaWr/Z2hq/2VmaP9lZmf/Z2hp/2Nk
|
||||
Zv9tbWr/iYh5/1hZWf9SU1T/UFFS/01OT/9DQ0TOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGFiYgNJSku/Pj8//zk6Ov84OTn/Nzc4/zU1
|
||||
Nv80NTX/NDU1/zQ1Nf80NTb/NTY2/zY3N/82Nzj/Nzg4/zc4Of84ODn/ODg5/zg5Of84OTn/ODk6/zg5
|
||||
Of84OTr/ODk5/zY3OP9HR0L/c3Jg/zw9O/83ODn/Nzc4/z4/P/82NzjSAAAABwAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhoaAJPUVK/LS0s/yUk
|
||||
If8nJiP/JiUi/yUkIf8kIyD/IiIf/yEhHv8gIB3/Hx8c/x4eG/8dHRr/HRwa/xwcGv8cHBr/HBsZ/xwb
|
||||
Gf8bGxn/GxoZ/xoaGf8aGhj/GhoY/xoaGP8ZGBf/FRQU/xkZF/8YGBb/FRUT/yYnJ/9FQj73JxwNogIC
|
||||
AGEAAAA6AAAAIAAAAAsAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJz
|
||||
dAJYWVq/Li4t/ykoJP8rKib/Kikl/ykoJf8nJiP/JiUi/yUkIf8kIyD/IiIf/yEhHv8hIR7/ICAd/yAg
|
||||
Hf8gHxz/Hx8c/x8fHP8fHhv/Hh4b/x4eG/8dHRv/HRwa/xwcGv8cGxr/GxsZ/xsbGf8bGxn/GBgW/yMl
|
||||
Jv9PSUH/e1kt/2VII/QsIA+7AgEBfgAAAFoAAAA5AAAAGwAAAAkAAAACAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAHd3dwJeX2C/MjIw/ywrJ/8uLSn/LSwo/ywrJ/8rKib/KSgl/ycmJP8nJSL/JSQh/yQj
|
||||
IP8kIyD/IyMg/yMiH/8jIh//IiIf/yEhHv8hIR7/ISEe/yAgHf8fHxz/Hx8c/x4eG/8eHhv/HR0b/x0d
|
||||
G/8dHRv/GhoY/yQlJ/9NRz//fFkt/39cLv9/XC7/WEAg5RMOB6AAAAB5AAAAXwAAADwAAAAeAAAACwAA
|
||||
AAMAAAABAAAAAAAAAAAAAAAAAAAAAHh4eAJkZWa/NTUz/zAvKv8yMCz/MS8r/zAuKv8uLSn/LCso/ysq
|
||||
Jv8qKSX/KCck/ygnJP8nJiP/JyYj/yYlIv8mJSL/JSQh/yUkIf8lJCH/JCMg/yMiH/8iIh//ISEe/yEg
|
||||
Hf8gIB3/Hx8d/x8fHf8eHhz/HBwa/yQmJ/9MRj7/gFor/35aLP99Wi3/gV0v/3NUKvgmHA6xAAAAfQAA
|
||||
AG4AAABPAAAALgAAABYAAAAJAAAAAwAAAAEAAAAAAAAAAH6AgwJra22/ODg2/zUyLv82NDD/NTMv/zQy
|
||||
Lv8yMCz/MC8r/y8uKv8uLSn/LCsn/ysqJ/8rKib/Kikm/yopJv8qKCX/KSgl/ykoJf8oJyT/JyYj/yYl
|
||||
Iv8mJSL/JCQh/yQjIP8jIyD/IiIf/yIiH/8hIR7/Hh4b/yQmJ/9MRj3/hl8u/4ReLv+BXC7/flsu/31b
|
||||
Lv94WC39MCMStQAAAHkAAABtAAAAUgAAADQAAAAcAAAADQAAAAUAAAAAAAAAAIqKigJxcnS/PDs5/zk3
|
||||
Mv87OTX/OTcz/zg2Mv83NTD/NTMv/zMxLf8yMCz/MS8r/zAuKv8vLir/Ly4q/y8tKf8uLSn/LSwp/y0s
|
||||
KP8sKyf/Kyon/yopJf8oJyT/KCck/ycmI/8mJSL/JSUi/yUkIf8kJCH/ISEe/yUmJ/9MRj3/jGUy/4lj
|
||||
Mf+GYTH/g2Aw/35cL/9lSif/blEq/ygdD7YAAABwAAAAZAAAAEsAAAAyAAAAHQAAAA0AAAAAAAAAAIuL
|
||||
iwN2eHnAPz88/z48N/8/PTj/Pjw3/z07Nv87OTX/Ojgz/zg2Mv83NTH/NjQw/zY0MP81My//NDIv/zQy
|
||||
Lv80Mi7/MzEt/zIwLP8xLyv/Ly4q/y4tKf8tLCj/LCsn/yopJv8qKSb/KSgl/ygnJP8nJiP/JSQh/yYn
|
||||
KP9MRj3/k2s4/49pNv+LZjX/iGQ0/4djM/9kSij/Uj0h/1hBIv8fFgyhAAAAYQAAAFUAAAA/AAAAKgAA
|
||||
ABcAAAAAAAAAAIuLiwN6e3zARENA/0NBPP9FQj3/Q0E8/0I/Ov9APjn/Pz04/z48N/89Ozb/PDo1/zs5
|
||||
NP86ODT/Ojg0/zo4M/85NzP/ODYy/zc1Mf82NDD/NDIu/zMxLf8xMCz/MC8r/y8uKv8uLSn/LSwo/ywr
|
||||
KP8rKif/KCck/ycoKP9NRz7/mHNA/5ZwPf+RbTz/jmo5/4toN/9/XjL/XUYm/1dBJP9RPCHyDQkFdgAA
|
||||
AFEAAABDAAAAMAAAAB0AAAAAAAAAAJGRkgN+f4DASUhG/0pHQv9LSUT/SkdC/0hGQf9HRD//RUM+/0RC
|
||||
PP9DQTz/QkA7/0E/Ov9BPzr/QD45/z89OP8/PTj/Pjw3/zw6Nf86ODX/OTcz/zg2Mv82NDD/NTMv/zMy
|
||||
Lv8yMS3/MTAs/zAvK/8vLir/LCsn/ygpKv9MRz7/nXxJ/5t4Rv+YdUT/k3FA/49tPf+Nazv/gmE1/2BI
|
||||
Kf9hSSn/RzUdwwAAAEsAAABBAAAAMQAAAB8AAAAAAAAAAJubmwODg4XAUE5M/1NQSv9SUEn/UU5I/09N
|
||||
R/9OTEb/TUpE/0xJQ/9LSEP/SkdC/0lGQf9IRkD/R0U//0ZEP/9FQz7/Q0E8/0E/Ov9APTn/Pjw3/zw7
|
||||
Nv87OTT/OTcz/zg2Mv83NTH/NjQw/zUzL/8zMi7/MC8r/ykqK/9MSED/oIVU/5+BUP+dfU3/mXlK/5V1
|
||||
Rv+Pb0H/jGs9/4JjOP96XTT/f181/yEZDnEAAAAyAAAALQAAAB0AAAAAAAAAAJubmwOFh4jAVFNQ/15c
|
||||
Vf9dW1T/WlhR/1hWT/9XVU7/VlNM/1RSS/9TUUr/U1BJ/1FPSP9QTkf/T01G/01LRf9MSUP/SkdC/0dF
|
||||
QP9FQz7/Q0E8/0E/Ov9APjj/Pjw4/z07N/88OjX/Ojg0/zk3M/83NjL/NDMv/yssLP9MSUL/pY5f/6OK
|
||||
XP+hhlj/noFU/5l8T/+Kb0b/h2tB/4ZpP/+FaD3/clg0/1xHKccAAAAqAAAAJQAAABkAAAAAAAAAAJub
|
||||
mwOIiYrAWVhU/2ZkXP9pZl//aGVe/2ZjW/9kYFn/Yl9X/19cVf9eW1T/XFpS/1pYUP9ZVk//VlRN/1RS
|
||||
S/9SUEn/UE1H/05LRf9LSEP/SUZB/0ZEP/9EQj7/Q0E8/0JAO/9BPzr/Pz04/z07N/87OTX/ODYy/ywt
|
||||
Lf9MSkP/qpZp/6iTZ/+ljmP/pIpf/5h/V/+OdU7/gmpG/4VrRf+Ha0P/f2U+/4NnPvsdFw5JAAAAFgAA
|
||||
ABMAAAAAAAAAAJycnAOLi43AXl1a/3FuZv9zcGj/c3Bo/3NvZ/9zb2f/cW5l/29sY/9taWH/a2df/2hl
|
||||
Xf9mY1v/ZGBZ/2FeVv9eW1T/W1hR/1hWT/9VU03/U1BL/1BNSP9OS0b/SkdC/0dFQP9FQj3/Q0E8/0E/
|
||||
Ov8/PTn/PDk1/y4tLf9NTEf/rqB5/6yacv+qlW3/p5Fp/6CJYv+dhV3/moBY/5N6Uf+PdU3/i3BI/45y
|
||||
SP9PQCmTAAAABwAAAA4AAAAAAAAAAJydnQONj5DAZGNf/3x4cP9+enL/f3tz/397c/9/e3L/f3ty/316
|
||||
cP98eG//eXVs/3Zyaf9zb2f/b2xk/2toYP9nZFz/ZGFa/2BeV/9dW1T/WlhR/1dVT/9VU03/U1BL/1FO
|
||||
Sf9MSUT/R0VA/0RCPf9CQDv/Pz04/y8vLv9OTkr/tKuR/7GliP+unnr/qJVw/6OPbP+ciGT/m4Vg/5iA
|
||||
Wv+Te1T/jnVP/450Tf9vWzzGAQEBBwAAAAcAAAAAAAAAAJ2dnQOPkJHAamhl/4iEev+Lh37/jIl//42J
|
||||
f/+Nin//jIl+/4uHfP+IhXr/hoJ4/4J+dP99enD/eXVt/3Vxaf9wbWX/bGlg/2hlXf9jYVr/YF5X/11b
|
||||
VP9bWFL/WFZQ/1ZTTv9TUEv/UE1I/0tIQ/9FQz7/QT86/zEwL/9QT0z/uK+W/6yiif+zqZD/rqCB/6WT
|
||||
c/+mknD/nYpn/5qFYf+XgVz/kXtW/411Uf+Lc0/4HRgQKgAAAAAAAAAAAAAAAJ2dnQKPkJG/b25q/5OP
|
||||
hf+Wk4n/mJSK/5qWi/+blov/mZWK/5iUif+VkYb/ko6D/42Kf/+IhXv/g4B2/356cf95dG3/dHBp/29s
|
||||
ZP9raGD/Z2Rd/2NhWv9fXVb/XFtU/1lXUf9XVE//U1BL/1BNSP9LSUT/REI9/zExMP9SUk//ubCX/6qd
|
||||
hP+6sZv/r6SN/5iJcP+olnb/oY9v/5+Laf+ahWP/lH9c/5B6V/+Se1b/MioeUgAAAAAAAAAAAAAAAJyc
|
||||
nAOPkJHAdXRv/56bj/+inpP/paGW/6eil/+no5f/pqGW/6WglP+hnZH/nZmO/5iUif+Tj4T/jYl//4aD
|
||||
ef+BfXT/e3hw/3Zza/9ybmf/bWpj/2lnX/9lY1z/YV9Y/15bVf9aV1L/V1RP/1NQS/9PTEf/SkhD/zMz
|
||||
Mv9UVFH/vrWc/6qbgf+4rZf/p5uD/5+Sev+tnoP/ppZ3/6ORcf+di2n/l4Ri/5J+XP+VgFz/QjgoaQAA
|
||||
AAAAAAAAAAAAAJ2dnQKPkJG/enhz/6ikmf+tqZ7/r6ug/7Gtof+yraH/sayg/6+qnv+rppr/p6KW/6Gd
|
||||
kv+cmI3/lZGG/46Lgf+IhXv/gn52/315cf94dW3/c3Bo/25rZP9qZ2D/ZWNc/2FfWP9dW1T/WVZR/1VS
|
||||
Tf9QTkn/TEpE/zY2Nf9TUk//uq2T/7Gjiv+toIj/p5uD/6KVfv+fk3z/p5h+/6aWeP+gjm//moho/5SC
|
||||
Yf+YhGL/ST8uegAAAAAAAAAAAAAAAJ2dnAONjo+/fnx3/7Gtov+1saX/ubSo/7u2qv+7tqr/urWp/7ez
|
||||
p/+0r6P/r6qe/6mkmf+jnpP/nJiN/5WSh/+Oi4H/iIR7/4J+dv98eXH/eHVt/3NwaP9ua2T/aWdg/2Ri
|
||||
W/9fXlf/W1lT/1dUT/9SUEv/TktG/zc3Nv9SUEz/vrCX/7mtk/+ypo7/raGK/6echP+flH3/ppmD/6qb
|
||||
f/+jk3X/nItt/5aFZv+UgmL/gXFVggAAAAAAAAAAAAAAAJ2dnQKMjY6/gH96/7q1qf++uKz/wLuv/8K9
|
||||
sf/CvbH/wbyv/765rf+6tan/tbCk/6+qnv+opJj/op2S/5qXjP+TkIb/jYmA/4eDev+Bfnb/fHlx/3d0
|
||||
bP9yb2j/bGpj/2dlXv9iYFr/XltW/1pXUv9VUk3/UE5I/zg4N/9VU0//x7uh/8G0nP+5rpb/s6eQ/6yg
|
||||
iv+lmYP/q6CM/6ibhP+gkXX/n49x/5mIav+TgmT/k4JkggAAAAAAAAAAAAAAAJydnQKKjI2/gH54/7y3
|
||||
qv/Auq7/wr2x/8S/sv/Ev7L/w72x/8C7rv+8t6r/t7Gl/7Crn/+ppZn/op6T/5uXjP+UkIb/jYmA/4eD
|
||||
ev+Bfnb/fHlx/3d0bP9yb2j/bWtj/2dmXv9jYVr/X1xX/1pXUv9VUk3/UE1I/zk4N/9WVVH/0MOq/8i8
|
||||
pP/AtJ3/ua2W/7Glj/+qnoj/rKGM/6qfif+jlXr/oJB0/5qLbv+UhWn/kYFlegAAAAAAAAAAAAAAAKGh
|
||||
oQOJiovAYmFf/2tpZP9vbWj/cG5p/3JxbP9ycWz/cG9r/29uaf9ta2f/amhk/2ZlYP9jYV3/Xl1Z/1pZ
|
||||
Vf9WVVH/UlFN/01MSf9KSUb/R0ZD/0NCQP9APz3/PT06/zs6OP83Nzb/NDQz/zIxMP8vLi3/Kioo/yYn
|
||||
Kf9TUk//2Mux/9DDqv/GuqL/vLGa/7Spk/+soYv/pJmC/6aahP+mmYD/oZJ2/5yNcf+Wh2z/koRpagAA
|
||||
AAAAAAAAAAAAAAAAAACVlpeQh4iJ1oeIic2HiInNh4eJzn98ePh/e3T/gHx2/398dv99enb/fHp3/3x6
|
||||
d/95eHX/eHd0/3h3dP92dXL/dXRy/3h3c/93d3P/d3Zz/3Z2cv92dnL/c3Ju/3Fvav9wbmr/b21o/2tq
|
||||
Zf9oZ2L/ZGNe/1taV/+GgHb/4dS6/9THsP/Kvqb/wLSe/7arlf+uoo3/pZmD/56Tff+lmID/o5V5/52P
|
||||
c/+XiW//k4VsUQAAAAAAAAAAAAAAAAAAAAClpqYBm5ubApmZmQKZmpsBAAAAAIVxUrqQd1H/l4Bb/5WB
|
||||
Yf+PgGf/lodv/52Qef+bkHv/o5iC/66jjv+qoI3/uK6Z/8vCrf/UzLb/3tW//+nhyv/17dX/9evS//Pk
|
||||
yP/77M////PV///22f//9dj//fDU//Xozf/w4sj/4tW8/9fKs//MwKn/wrag/7itlv+vo43/p5uF/6CU
|
||||
fv+lmIH/oZN6/5uOdP+YinH3lIdvJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH5n
|
||||
Q4KLc0//kXpX/4p4XP+NfmT/lIVt/5uOd/+dkXz/qp6H/7GlkP+too//v7Sg/8vBrP/VzLX/39W//+ri
|
||||
y//069P/+fHZ///64v//+eL///zh///84f//+97///bZ//zt0v/w4sj/49a9/9jLs//Nwan/wraf/7is
|
||||
lv+vo43/ppqE/6ichv+sn4j/m493/5qNdf+Yi3PDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAIFrSz6IclD/kHpY/4d3XP+OfmT/lIVt/5uNd/+ekn3/pJiD/7Clj/+zqJT/wLWg/8rA
|
||||
q//Rx7L/3dO9/+nfyP/069P/+vPb////6f///e3////x////6f///+f///vh//3y2f/z5s7/5trD/9rO
|
||||
uP/Pw63/xLii/7qvmf+xppD/qZ6I/6aahv+mmoT/npJ7/5qNd/+ZjHSIAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACFcVC7kXtY/4l4Xf+NfWT/k4Rs/5uNdv+iloD/n5SA/6me
|
||||
iv+yp5P/uK2a/8a8p//Euqf/2s+6/+fdx//z6NH//fXc//303P/+9uD///7t///95v///eX///jg//zw
|
||||
2f/y5s//59vF/9vQu//RxrH/xrun/72ynf+0qZT/rKGN/6Wahv+elID/mo97/5aLdveZjHQqAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEcFBej3lX/5J+Xv+VhGb/mYpv/56S
|
||||
eP+kmYH/pp2G/6ich/+vpJD/tauX/8K4o/+/taP/0siz/97Tvv/q38n/+e3W//3z2//68Nn///jg///3
|
||||
3///9t//+/DY//To0v/r38j/4dW//9bLtv/Mwaz/w7ei/7qumf+xppH/qp+L/6SYhf+dkn//mI56/5mN
|
||||
drQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACHclIEinVUzJaA
|
||||
Xf+ah2b/nY9w/56Qdf+hk3z/qZ+I/6echv+nnYn/t6yY/8C1oP+9s6D/x7yp/9jNuP/k2cP/8OXN//ru
|
||||
1v/269T/9OnS//ft1f/88dn/9OjQ/+vfyP/l2cL/28+5/9DFr//HvKb/v7Od/7aqlf+uo47/p5yI/6OY
|
||||
g/+iln7/nZF5/5uNdTwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAiHNTSpF8Wv+ZhGL/nIxs/5+SdP+jl3z/qJ+F/6qhif+rn4j/t6uU/7yxm/+6r5z/v7Wi/87D
|
||||
rv/f07z/5tvE/+7jy//z58//7OHK//Llzv/569L/9OfO/+vfxv/d0br/0saw/8m+p//Btp//ua2Y/7So
|
||||
kv+ypo//qp+J/6mchP+jln3/nZB3nQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIt3VpuWgV7/m4hn/56PcP+ilXj/ppyA/6yiif+pnof/sKOL/7er
|
||||
lP+zqpb/urCc/8O5pP/UybL/3dG6/+PXv//o3MT/697G/+3gx//s38b/5dm//+PWvP/bzrX/z8Kq/8C2
|
||||
n/+7sJn/u66W/7eqkv+ypo7/rKCI/6aZgP+gk3rfnZB3GwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIt3VQ+QfFrMmYVj/52MbP+gk3P/pJl7/6mf
|
||||
g/+qn4f/qJuF/66ii/+to47/s6iV/7yynf/MwKn/08av/9jLs//cz7b/3tG4/9/SuP/f0bf/2syz/9XH
|
||||
rv/Uxaz/zL6l/7+zm/+4rJX/uayT/7Snjv+toYn/qJuC/6OVfPueknlHAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNeVgklH9d4JuI
|
||||
Zv+ejm7/opV2/6ebff+roYT/qp6G/6WXgv+onIf/rKGM/7arlP/Et57/yLyj/83Ap//NwKj/0cOq/9LE
|
||||
q//SxKr/0MKn/8y+pP/Ju6H/xLac/7+xl/+5rJL/tKaN/6+hiP+pm4P/pJd+/qCTemAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAj3taKZeCYdudimj/oJBw/6SWd/+onX7/rKKG/6yhh/+qnIP/p5uE/7GkjP+7rpP/v7GX/8K1
|
||||
mv/As5r/w7Wb/8e5nv/HuZ3/xbec/8O1mv+/spf/u66T/7epj/+zpYv/rqGH/6qcg/+kl377oZR7XgAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJJ9XRyYhGO+notr/6GRcf+klnf/qJx+/62jhf+vpYb/q52B/66e
|
||||
g/+zpIj/tqeL/7mqjv+7rZD/vK2R/72ukv+9rpL/vK2R/7qrkP+3qI3/tKaK/7CiiP+tn4X/qZuB/6SW
|
||||
feugk3pIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUgGADmYVlfJ6La/WhkXH/pZZ2/6ib
|
||||
e/+soIH/rqOE/6yegP+rmn3/rp2A/7Cgg/+yooT/s6OG/7Skh/+0pYj/tKSI/7Kih/+voIX/rZ6D/6qb
|
||||
gP+mmH3/opR6uKGTeh8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJuH
|
||||
Zymei2uioY9v+qSUdP+nmHn/qpx9/62ggP+snn7/qZh5/6iXeP+pmHr/q5l8/6ybfv+sm3//q5t//6qa
|
||||
f/+omH3/pZZ7/6KTeM6hkndXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAn4xrK6GObYmjkXDgpZRz+aiYd/+qnHr/rJ18/6qaev+mlXb/pJJ0/6SS
|
||||
df+kk3b/o5N3/qOSdu2hkXWsoJB0R6GQdQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACij24Io5BvJqSRcGCllHOYp5Z0wamY
|
||||
d9WqmXjXqZh4yqWVdqyfjXB4no1wOp+PchEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP///////wAA//AAf///
|
||||
AAD/8AA///8AAP/wAH///wAA8AAAAH//AADgAAAAP/8AAOAAAAA//wAA4AAAAB//AADgAAAAB/8AAOAA
|
||||
AAAB/wAA4AAAAAD/AADgAAAAAH8AAOAAAAAAPwAA4AAAAAAfAADgAAAAAB8AAOAAAAAADwAA4AAAAAAP
|
||||
AADgAAAAAAcAAOAAAAAABwAA4AAAAAADAADgAAAAAAMAAOAAAAAAAwAA4AAAAAADAADgAAAAAAMAAOAA
|
||||
AAAAAwAA4AAAAAABAADgAAAAAAEAAOAAAAAAAwAA4AAAAAADAADgAAAAAAMAAP8AAAAAAwAA/wAAAAAD
|
||||
AAD/gAAAAAMAAP+AAAAABwAA/8AAAAAHAAD/wAAAAA8AAP/gAAAADwAA/+AAAAAfAAD/8AAAAD8AAP/4
|
||||
AAAAfwAA//wAAAD/AAD//gAAAf8AAP//gAAD/wAA///AAA//AAD///AAP/8AAP///wP//wAA////////
|
||||
AAA=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using BitFactory.Logging;
|
||||
using Castle.Core.Resource;
|
||||
using Castle.Windsor;
|
||||
using Castle.Windsor.Configuration.Interpreters;
|
||||
|
||||
namespace ServiceDashBored
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
IWindsorContainer container =
|
||||
new WindsorContainer(
|
||||
new XmlInterpreter(new ConfigResource("castle")));
|
||||
|
||||
// Request the component to use it
|
||||
var form = (Main)container[typeof(Main)];
|
||||
|
||||
try
|
||||
{
|
||||
// Use the component
|
||||
Application.Run(form);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var logger = (Logger)container[typeof(Logger)];
|
||||
logger.LogFatal(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Release it
|
||||
container.Release(form);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ServiceDashBored")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ServiceDashBored")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ff0209e6-0dad-4e5c-8dc2-c1f004eafab0")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is automatically generated by Visual Studio .Net. It is
|
||||
used to store generic object data source configuration information.
|
||||
Renaming the file extension or editing the content of this file may
|
||||
cause the file to be unrecognizable by the program.
|
||||
-->
|
||||
<GenericObjectDataSource DisplayName="EndpointStatus" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
|
||||
<TypeInfo>ServiceDashBored.EndpointStatus, ServiceDashBored, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
|
||||
</GenericObjectDataSource>
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30128.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ServiceDashBored.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ServiceDashBored.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon accept {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("accept", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon question {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("question", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon remove {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("remove", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon up {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("up", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Icon warning {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("warning", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="accept" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\accept.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="question" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\question.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="remove" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\remove.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="up" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\up.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="warning" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\warning.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
[InternetShortcut]
|
||||
URL=http://dryicons.com/free-icons/preview/aesthetica-version-2/
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
@@ -0,0 +1,148 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{2D46A996-7DEF-4592-B401-70090686B3F2}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ServiceDashBored</RootNamespace>
|
||||
<AssemblyName>ServiceDashBored</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BitFactory.Logging, Version=1.4.1.0, Culture=neutral, PublicKeyToken=de68848483a294a9, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>References\BitFactory.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Castle.Core, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>References\Castle.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Castle.DynamicProxy2, Version=2.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>References\Castle.DynamicProxy2.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Castle.MicroKernel, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>References\Castle.MicroKernel.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Castle.Windsor, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>References\Castle.Windsor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.configuration" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="EndpointStatus.cs">
|
||||
</Compile>
|
||||
<Compile Include="Main.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Main.Designer.cs">
|
||||
<DependentUpon>Main.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Main.resx">
|
||||
<DependentUpon>Main.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.config" />
|
||||
<None Include="Resources\up.ico" />
|
||||
<None Include="Resources\question.ico" />
|
||||
<None Include="Resources\remove.ico" />
|
||||
<None Include="Resources\accept.ico" />
|
||||
<None Include="Resources\warning.ico" />
|
||||
<None Include="Properties\DataSources\EndpointStatus.datasource" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Endpoint\Endpoint.csproj">
|
||||
<Project>{7686BAA6-A0C5-4FA5-BE6E-FA044C2FFDD4}</Project>
|
||||
<Name>Endpoint</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,157 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
|
||||
</configSections>
|
||||
<castle>
|
||||
<components>
|
||||
<component id="form.component" type="ServiceDashBored.Main, ServiceDashBored">
|
||||
<parameters>
|
||||
<endpoints>
|
||||
<array>
|
||||
<item>${google.endpoint}</item>
|
||||
<item>${10.21.63.6.endpoint}</item>
|
||||
<item>${localhost.freespace.endpoint}</item>
|
||||
</array>
|
||||
</endpoints>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="logger.component" service="BitFactory.Logging.Logger, BitFactory.Logging" type="BitFactory.Logging.FileLogger, BitFactory.Logging">
|
||||
<parameters>
|
||||
<aFileName>ServiceDashBored.log</aFileName>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="kpcodl06.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>kpcodl06:8080 (paypal)</Name>
|
||||
<UriString>http://kpcodl06:8080/paypal_server/PayPalService</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="kpapqlz03.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>kpapqlz03:8080 (paypal)</Name>
|
||||
<UriString>http://kpapqlz03:8080/paypal_server/PayPalService</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="kpcoql03.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>kpcoql03:8083 (OrderService)</Name>
|
||||
<UriString>http://kpcoql03.jewelry.qa:8083/catalyst_server/OrderService</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="10.21.63.6.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>10.21.63.6 (ws-virtual)</Name>
|
||||
<UriString>http://10.21.63.6</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="10.21.63.7.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>10.21.63.7 (ws-virtual)</Name>
|
||||
<UriString>http://10.21.63.7</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="10.21.63.8.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>10.21.63.8 (ws-virtual)</Name>
|
||||
<UriString>http://10.21.63.8</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="10.21.63.10.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>10.21.63.10 (ws-virtual)</Name>
|
||||
<UriString>http://10.21.63.10</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="10.21.63.11.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>10.21.63.11 (ws-physical)</Name>
|
||||
<UriString>http://10.21.63.11</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="10.21.63.12.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>10.21.63.12 (ws-physical)</Name>
|
||||
<UriString>http://10.21.63.12</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="images.jewelry.dmz.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>images.jewelry.dmz (ws-virtual)</Name>
|
||||
<UriString>http://images.jewelry.dmz</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="google.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.HttpEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>Google</Name>
|
||||
<UriString>http://www.google.com</UriString>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="localhost.freespace.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.WmiEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>localhost D: Freespace</Name>
|
||||
<MachineName>\\localhost</MachineName>
|
||||
<ObjectQueryString>select FreeSpace from Win32_LogicalDisk where DeviceID='D:'</ObjectQueryString>
|
||||
<ResultPropertyName>FreeSpace</ResultPropertyName>
|
||||
<MinimumThreshold>50e6</MinimumThreshold>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="kpapdl26.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.SoapEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>kpapdl26:8080 (payment)</Name>
|
||||
<UriString>http://kpapdl26:8080/core_server/paymentservice</UriString>
|
||||
<XpathQuery>//jtv:provider/text()</XpathQuery>
|
||||
<XpathNamespaces>jtv,http://jtv.com</XpathNamespaces>
|
||||
<ExpectedXpathResult>NoDecision</ExpectedXpathResult>
|
||||
<SoapAction>"urn:getPaymentKey"</SoapAction>
|
||||
<SoapRequest>
|
||||
<![CDATA[<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:jtv="http://jtv.com"><soapenv:Header/><soapenv:Body><jtv:getPaymentKey><jtv:context></jtv:context></jtv:getPaymentKey></soapenv:Body></soapenv:Envelope>]]>
|
||||
</SoapRequest>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="pscoql03.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.SoapEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>pscoql03:8080 (payment)</Name>
|
||||
<UriString>http://pscoql03:8080/core_server/paymentservice</UriString>
|
||||
<XpathQuery>//jtv:provider/text()</XpathQuery>
|
||||
<XpathNamespaces>jtv,http://jtv.com</XpathNamespaces>
|
||||
<ExpectedXpathResult>NoDecision</ExpectedXpathResult>
|
||||
<SoapAction>"urn:getPaymentKey"</SoapAction>
|
||||
<SoapRequest>
|
||||
<![CDATA[<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:jtv="http://jtv.com"><soapenv:Header/><soapenv:Body><jtv:getPaymentKey><jtv:context></jtv:context></jtv:getPaymentKey></soapenv:Body></soapenv:Envelope>]]>
|
||||
</SoapRequest>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
<component id="10.20.7.26.endpoint" service="Endpoint.IEndpoint, Endpoint" type="Endpoint.SoapEndpoint, Endpoint">
|
||||
<parameters>
|
||||
<Name>10.20.7.26:8080 (payment)</Name>
|
||||
<UriString>http://10.20.7.26:8080/core_server/paymentservice</UriString>
|
||||
<XpathQuery>//jtv:provider/text()</XpathQuery>
|
||||
<XpathNamespaces>jtv,http://jtv.com</XpathNamespaces>
|
||||
<ExpectedXpathResult>NoDecision</ExpectedXpathResult>
|
||||
<SoapAction>"urn:getPaymentKey"</SoapAction>
|
||||
<SoapRequest>
|
||||
<![CDATA[<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:jtv="http://jtv.com"><soapenv:Header/><soapenv:Body><jtv:getPaymentKey><jtv:context></jtv:context></jtv:getPaymentKey></soapenv:Body></soapenv:Envelope>]]>
|
||||
</SoapRequest>
|
||||
</parameters>
|
||||
</component>
|
||||
|
||||
</components>
|
||||
</castle>
|
||||
</configuration>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ServiceDashBoredTests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ServiceDashBoredTests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM componenets. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("515c4aa0-000b-4576-b132-a01941b92b89")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,51 @@
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{4160DFC0-6484-4B92-A6C8-8EAF8655C1CD}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ServiceDashBoredTests</RootNamespace>
|
||||
<AssemblyName>ServiceDashBoredTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
Reference in New Issue
Block a user