Compare commits

..

2 الالتزامات

المؤلف SHA1 الرسالة التاريخ
Era
408b04efb7 Merge branch 'main' of https://app.gitpasha.com/Erakimous/pingerino 2025-08-19 07:35:49 +03:00
Era
243f4787dd Initial commit - Pingerino network monitoring application 2025-08-19 07:34:27 +03:00
41 ملفات معدلة مع 12352 إضافات و0 حذوفات

63
.gitattributes مباع Normal file
عرض الملف

@@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

363
.gitignore مباع Normal file
عرض الملف

@@ -0,0 +1,363 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd

30
App.config Normal file
عرض الملف

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Pingerino.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<userSettings>
<Pingerino.Properties.Settings>
<setting name="FormPosition" serializeAs="String">
<value>0, 0</value>
</setting>
<setting name="TextBoxIntervalValue" serializeAs="String">
<value>1000</value>
</setting>
<setting name="IpAddressValue" serializeAs="String">
<value>8.8.8.8</value>
</setting>
<setting name="AutoPingEnabled" serializeAs="String">
<value>True</value>
</setting>
<setting name="LastUsedIpAddress" serializeAs="String">
<value>8.8.8.8</value>
</setting>
</Pingerino.Properties.Settings>
</userSettings>
</configuration>

1
Compiled/.gitkeep Normal file
عرض الملف

@@ -0,0 +1 @@

ثنائية
Compiled/IPAddressControlLib.dll Normal file

ملف ثنائي غير معروض.

ملف ثنائي غير معروض.

تم حذف اختلاف الملف لأن الملف كبير جداً تحميل الاختلاف

ثنائية
Compiled/Pingerino.exe Normal file

ملف ثنائي غير معروض.

عرض الملف

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Pingerino.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<userSettings>
<Pingerino.Properties.Settings>
<setting name="FormPosition" serializeAs="String">
<value>0, 0</value>
</setting>
<setting name="TextBoxIntervalValue" serializeAs="String">
<value />
</setting>
<setting name="IpAddressValue" serializeAs="String">
<value />
</setting>
<setting name="AutoPingEnabled" serializeAs="String">
<value>True</value>
</setting>
<setting name="LastUsedIpAddress" serializeAs="String">
<value>8.8.8.8</value>
</setting>
</Pingerino.Properties.Settings>
</userSettings>
</configuration>

844
FormPinger.Designer.cs مولّد Normal file
عرض الملف

@@ -0,0 +1,844 @@
namespace Pingerino
{
partial class FormPinger
{
/// <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 (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.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle9 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle10 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle14 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle15 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle16 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle11 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle12 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle13 = new System.Windows.Forms.DataGridViewCellStyle();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormPinger));
this.textBoxInterval = new System.Windows.Forms.TextBox();
this.COPYRIGHT = new System.Windows.Forms.TextBox();
this.textBoxPacketLoss = new System.Windows.Forms.TextBox();
this.textBoxJitter = new System.Windows.Forms.TextBox();
this.labelPacketLoss = new System.Windows.Forms.Label();
this.labelJitter = new System.Windows.Forms.Label();
this.ipAddress = new IPAddressControlLib.IPAddressControl();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.label4 = new System.Windows.Forms.Label();
this.ButtonExit = new System.Windows.Forms.Button();
this.ButtonMinimize = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.ButtonNetworkAdapters = new System.Windows.Forms.Button();
this.buttonCleanTemp = new System.Windows.Forms.Button();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.ButtonMenu = new System.Windows.Forms.Button();
this.ButtonCleanNetwork = new System.Windows.Forms.Button();
this.TextBoxMaxLoss = new System.Windows.Forms.TextBox();
this.TextBoxMaxJitter = new System.Windows.Forms.TextBox();
this.TextBoxAvgJitter = new System.Windows.Forms.TextBox();
this.TextBoxAvgLoss = new System.Windows.Forms.TextBox();
this.TextBoxMinLoss = new System.Windows.Forms.TextBox();
this.TextBoxMinJitter = new System.Windows.Forms.TextBox();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.Time = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Status = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.RTT = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
this.ButtonClearAll = new System.Windows.Forms.Button();
this.dataGridView2 = new System.Windows.Forms.DataGridView();
this.MinPing = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.AvgPing = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.MaxPing = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.panel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.tableLayoutPanel5.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).BeginInit();
this.SuspendLayout();
//
// textBoxInterval
//
this.textBoxInterval.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.textBoxInterval.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.textBoxInterval.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBoxInterval.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxInterval.ForeColor = System.Drawing.Color.Gold;
this.textBoxInterval.Location = new System.Drawing.Point(132, 48);
this.textBoxInterval.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.textBoxInterval.MaxLength = 4;
this.textBoxInterval.Name = "textBoxInterval";
this.textBoxInterval.Size = new System.Drawing.Size(178, 16);
this.textBoxInterval.TabIndex = 2;
this.textBoxInterval.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.textBoxInterval.TextChanged += new System.EventHandler(this.TextBoxInterval_TextChanged);
this.textBoxInterval.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxInterval_KeyDown);
//
// COPYRIGHT
//
this.COPYRIGHT.Anchor = System.Windows.Forms.AnchorStyles.None;
this.COPYRIGHT.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.COPYRIGHT.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.COPYRIGHT.Cursor = System.Windows.Forms.Cursors.Default;
this.COPYRIGHT.Enabled = false;
this.COPYRIGHT.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.COPYRIGHT.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(130)))));
this.COPYRIGHT.Location = new System.Drawing.Point(533, 530);
this.COPYRIGHT.Margin = new System.Windows.Forms.Padding(0);
this.COPYRIGHT.Name = "COPYRIGHT";
this.COPYRIGHT.Size = new System.Drawing.Size(180, 19);
this.COPYRIGHT.TabIndex = 31;
this.COPYRIGHT.Text = "© By Silicon Squire";
this.COPYRIGHT.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.COPYRIGHT.TextChanged += new System.EventHandler(this.COPYRIGHT_TextChanged);
//
// textBoxPacketLoss
//
this.textBoxPacketLoss.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.textBoxPacketLoss.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.textBoxPacketLoss.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBoxPacketLoss.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxPacketLoss.ForeColor = System.Drawing.Color.Gold;
this.textBoxPacketLoss.Location = new System.Drawing.Point(109, 9);
this.textBoxPacketLoss.Name = "textBoxPacketLoss";
this.textBoxPacketLoss.ReadOnly = true;
this.textBoxPacketLoss.Size = new System.Drawing.Size(66, 16);
this.textBoxPacketLoss.TabIndex = 33;
this.textBoxPacketLoss.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// textBoxJitter
//
this.textBoxJitter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.textBoxJitter.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.textBoxJitter.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBoxJitter.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxJitter.ForeColor = System.Drawing.Color.Gold;
this.textBoxJitter.Location = new System.Drawing.Point(109, 42);
this.textBoxJitter.Name = "textBoxJitter";
this.textBoxJitter.ReadOnly = true;
this.textBoxJitter.Size = new System.Drawing.Size(66, 16);
this.textBoxJitter.TabIndex = 34;
this.textBoxJitter.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.textBoxJitter.TextChanged += new System.EventHandler(this.TextBoxJitter_TextChanged);
//
// labelPacketLoss
//
this.labelPacketLoss.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.labelPacketLoss.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelPacketLoss.ForeColor = System.Drawing.Color.Gold;
this.labelPacketLoss.Location = new System.Drawing.Point(4, 8);
this.labelPacketLoss.Name = "labelPacketLoss";
this.labelPacketLoss.Size = new System.Drawing.Size(98, 18);
this.labelPacketLoss.TabIndex = 35;
this.labelPacketLoss.Text = "PacketLoss:";
this.labelPacketLoss.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.labelPacketLoss.Click += new System.EventHandler(this.Label1_Click);
//
// labelJitter
//
this.labelJitter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.labelJitter.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelJitter.ForeColor = System.Drawing.Color.Gold;
this.labelJitter.Location = new System.Drawing.Point(4, 41);
this.labelJitter.Name = "labelJitter";
this.labelJitter.Size = new System.Drawing.Size(98, 18);
this.labelJitter.TabIndex = 36;
this.labelJitter.Text = "Jitter:";
this.labelJitter.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.labelJitter.Click += new System.EventHandler(this.LabelJitter_Click);
//
// ipAddress
//
this.ipAddress.AllowInternalTab = false;
this.ipAddress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.ipAddress.AutoHeight = true;
this.ipAddress.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(35)))), ((int)(((byte)(35)))), ((int)(((byte)(45)))));
this.ipAddress.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.ipAddress.Cursor = System.Windows.Forms.Cursors.IBeam;
this.ipAddress.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.ipAddress.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(220)))), ((int)(((byte)(220)))), ((int)(((byte)(220)))));
this.ipAddress.Location = new System.Drawing.Point(131, 8);
this.ipAddress.MinimumSize = new System.Drawing.Size(117, 22);
this.ipAddress.Name = "ipAddress";
this.ipAddress.ReadOnly = false;
this.ipAddress.Size = new System.Drawing.Size(180, 22);
this.ipAddress.TabIndex = 37;
this.ipAddress.Text = "8.8.8.8";
this.ipAddress.Click += new System.EventHandler(this.IpAddress_Click);
this.ipAddress.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxIpAddress_KeyDown);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(190)))));
this.label1.Location = new System.Drawing.Point(4, 1);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(120, 36);
this.label1.TabIndex = 38;
this.label1.Text = "🌐 IP Address";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Dock = System.Windows.Forms.DockStyle.Fill;
this.label2.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(190)))));
this.label2.Location = new System.Drawing.Point(4, 38);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(120, 36);
this.label2.TabIndex = 39;
this.label2.Text = "⏱️ Interval (ms)";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.label2.Click += new System.EventHandler(this.Label2_Click);
//
// panel1
//
this.panel1.BackColor = System.Drawing.Color.Gold;
this.panel1.Controls.Add(this.label4);
this.panel1.Controls.Add(this.ButtonExit);
this.panel1.Controls.Add(this.ButtonMinimize);
this.panel1.Controls.Add(this.label3);
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
this.panel1.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(715, 27);
this.panel1.TabIndex = 40;
this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Panel1_MouseDown);
//
// label4
//
this.label4.AutoSize = true;
this.label4.BackColor = System.Drawing.Color.Gold;
this.label4.Location = new System.Drawing.Point(128, 2);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(100, 21);
this.label4.TabIndex = 64;
this.label4.Text = "Loading...";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// ButtonExit
//
this.ButtonExit.BackgroundImage = global::Pingerino.Properties.Resources.Untitled;
this.ButtonExit.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.ButtonExit.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.ButtonExit.Location = new System.Drawing.Point(657, 1);
this.ButtonExit.Name = "ButtonExit";
this.ButtonExit.Size = new System.Drawing.Size(25, 25);
this.ButtonExit.TabIndex = 33;
this.ButtonExit.UseVisualStyleBackColor = true;
this.ButtonExit.Click += new System.EventHandler(this.ButtonExit_Click);
//
// ButtonMinimize
//
this.ButtonMinimize.BackgroundImage = global::Pingerino.Properties.Resources.Untitlemd;
this.ButtonMinimize.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.ButtonMinimize.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.ButtonMinimize.Location = new System.Drawing.Point(629, 1);
this.ButtonMinimize.Name = "ButtonMinimize";
this.ButtonMinimize.Size = new System.Drawing.Size(25, 25);
this.ButtonMinimize.TabIndex = 32;
this.ButtonMinimize.UseVisualStyleBackColor = true;
this.ButtonMinimize.Click += new System.EventHandler(this.ButtonMinimize_Click);
//
// label3
//
this.label3.Anchor = System.Windows.Forms.AnchorStyles.None;
this.label3.AutoSize = true;
this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.label3.Location = new System.Drawing.Point(15, 2);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(91, 21);
this.label3.TabIndex = 31;
this.label3.Text = "Pingerino";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.label3.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Label3_MouseDown);
//
// ButtonNetworkAdapters
//
this.ButtonNetworkAdapters.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.ButtonNetworkAdapters.AutoSize = true;
this.ButtonNetworkAdapters.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ButtonNetworkAdapters.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonNetworkAdapters.FlatAppearance.BorderSize = 0;
this.ButtonNetworkAdapters.FlatAppearance.CheckedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonNetworkAdapters.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonNetworkAdapters.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonNetworkAdapters.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.ButtonNetworkAdapters.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.ButtonNetworkAdapters.ForeColor = System.Drawing.Color.Gold;
this.ButtonNetworkAdapters.Location = new System.Drawing.Point(4, 5);
this.ButtonNetworkAdapters.Name = "ButtonNetworkAdapters";
this.ButtonNetworkAdapters.Size = new System.Drawing.Size(148, 28);
this.ButtonNetworkAdapters.TabIndex = 41;
this.ButtonNetworkAdapters.Text = "Network Adapters";
this.ButtonNetworkAdapters.UseVisualStyleBackColor = false;
this.ButtonNetworkAdapters.Click += new System.EventHandler(this.ButtonNetworkAdapters_Click);
//
// buttonCleanTemp
//
this.buttonCleanTemp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.buttonCleanTemp.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.buttonCleanTemp.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.buttonCleanTemp.FlatAppearance.BorderSize = 0;
this.buttonCleanTemp.FlatAppearance.CheckedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.buttonCleanTemp.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.buttonCleanTemp.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.buttonCleanTemp.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.buttonCleanTemp.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.buttonCleanTemp.ForeColor = System.Drawing.Color.Gold;
this.buttonCleanTemp.Location = new System.Drawing.Point(159, 5);
this.buttonCleanTemp.Name = "buttonCleanTemp";
this.buttonCleanTemp.Size = new System.Drawing.Size(148, 27);
this.buttonCleanTemp.TabIndex = 43;
this.buttonCleanTemp.Text = "Kill N Clean";
this.buttonCleanTemp.UseVisualStyleBackColor = false;
this.buttonCleanTemp.Click += new System.EventHandler(this.ButtonCleanTemp_Click);
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(25)))), ((int)(((byte)(35)))));
this.tableLayoutPanel2.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Single;
this.tableLayoutPanel2.ColumnCount = 2;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.Controls.Add(this.ipAddress, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.label1, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.textBoxInterval, 1, 1);
this.tableLayoutPanel2.Controls.Add(this.label2, 0, 1);
this.tableLayoutPanel2.Location = new System.Drawing.Point(12, 31);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 2;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(315, 80);
this.tableLayoutPanel2.TabIndex = 45;
//
// ButtonMenu
//
this.ButtonMenu.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.ButtonMenu.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ButtonMenu.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonMenu.FlatAppearance.BorderSize = 0;
this.ButtonMenu.FlatAppearance.CheckedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonMenu.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonMenu.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonMenu.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.ButtonMenu.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.ButtonMenu.ForeColor = System.Drawing.Color.Gold;
this.ButtonMenu.Location = new System.Drawing.Point(159, 42);
this.ButtonMenu.Name = "ButtonMenu";
this.ButtonMenu.Size = new System.Drawing.Size(148, 27);
this.ButtonMenu.TabIndex = 43;
this.ButtonMenu.Text = "Stuff";
this.ButtonMenu.UseVisualStyleBackColor = false;
this.ButtonMenu.Click += new System.EventHandler(this.ButtonMenu_Click);
//
// ButtonCleanNetwork
//
this.ButtonCleanNetwork.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.ButtonCleanNetwork.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ButtonCleanNetwork.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonCleanNetwork.FlatAppearance.BorderSize = 0;
this.ButtonCleanNetwork.FlatAppearance.CheckedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonCleanNetwork.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonCleanNetwork.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonCleanNetwork.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.ButtonCleanNetwork.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.ButtonCleanNetwork.ForeColor = System.Drawing.Color.Red;
this.ButtonCleanNetwork.Location = new System.Drawing.Point(4, 42);
this.ButtonCleanNetwork.Name = "ButtonCleanNetwork";
this.ButtonCleanNetwork.Size = new System.Drawing.Size(148, 27);
this.ButtonCleanNetwork.TabIndex = 42;
this.ButtonCleanNetwork.Text = "Reset Network";
this.ButtonCleanNetwork.UseVisualStyleBackColor = false;
this.ButtonCleanNetwork.Click += new System.EventHandler(this.ButtonCleanNetwork_Click);
//
// TextBoxMaxLoss
//
this.TextBoxMaxLoss.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.TextBoxMaxLoss.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(25)))), ((int)(((byte)(35)))));
this.TextBoxMaxLoss.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.TextBoxMaxLoss.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.TextBoxMaxLoss.ForeColor = System.Drawing.Color.Gold;
this.TextBoxMaxLoss.Location = new System.Drawing.Point(312, 9);
this.TextBoxMaxLoss.Name = "TextBoxMaxLoss";
this.TextBoxMaxLoss.ReadOnly = true;
this.TextBoxMaxLoss.Size = new System.Drawing.Size(62, 22);
this.TextBoxMaxLoss.TabIndex = 52;
this.TextBoxMaxLoss.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// TextBoxMaxJitter
//
this.TextBoxMaxJitter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.TextBoxMaxJitter.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(25)))), ((int)(((byte)(35)))));
this.TextBoxMaxJitter.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.TextBoxMaxJitter.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.TextBoxMaxJitter.ForeColor = System.Drawing.Color.Gold;
this.TextBoxMaxJitter.Location = new System.Drawing.Point(312, 42);
this.TextBoxMaxJitter.Name = "TextBoxMaxJitter";
this.TextBoxMaxJitter.ReadOnly = true;
this.TextBoxMaxJitter.Size = new System.Drawing.Size(62, 22);
this.TextBoxMaxJitter.TabIndex = 52;
this.TextBoxMaxJitter.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// TextBoxAvgJitter
//
this.TextBoxAvgJitter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.TextBoxAvgJitter.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(25)))), ((int)(((byte)(35)))));
this.TextBoxAvgJitter.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.TextBoxAvgJitter.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.TextBoxAvgJitter.ForeColor = System.Drawing.Color.Gold;
this.TextBoxAvgJitter.Location = new System.Drawing.Point(247, 42);
this.TextBoxAvgJitter.Name = "TextBoxAvgJitter";
this.TextBoxAvgJitter.ReadOnly = true;
this.TextBoxAvgJitter.Size = new System.Drawing.Size(58, 22);
this.TextBoxAvgJitter.TabIndex = 51;
this.TextBoxAvgJitter.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// TextBoxAvgLoss
//
this.TextBoxAvgLoss.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.TextBoxAvgLoss.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(25)))), ((int)(((byte)(35)))));
this.TextBoxAvgLoss.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.TextBoxAvgLoss.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.TextBoxAvgLoss.ForeColor = System.Drawing.Color.Gold;
this.TextBoxAvgLoss.Location = new System.Drawing.Point(247, 9);
this.TextBoxAvgLoss.Name = "TextBoxAvgLoss";
this.TextBoxAvgLoss.ReadOnly = true;
this.TextBoxAvgLoss.Size = new System.Drawing.Size(58, 22);
this.TextBoxAvgLoss.TabIndex = 51;
this.TextBoxAvgLoss.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// TextBoxMinLoss
//
this.TextBoxMinLoss.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.TextBoxMinLoss.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(25)))), ((int)(((byte)(35)))));
this.TextBoxMinLoss.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.TextBoxMinLoss.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.TextBoxMinLoss.ForeColor = System.Drawing.Color.Gold;
this.TextBoxMinLoss.Location = new System.Drawing.Point(182, 9);
this.TextBoxMinLoss.Name = "TextBoxMinLoss";
this.TextBoxMinLoss.ReadOnly = true;
this.TextBoxMinLoss.Size = new System.Drawing.Size(58, 22);
this.TextBoxMinLoss.TabIndex = 50;
this.TextBoxMinLoss.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// TextBoxMinJitter
//
this.TextBoxMinJitter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.TextBoxMinJitter.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(25)))), ((int)(((byte)(35)))));
this.TextBoxMinJitter.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.TextBoxMinJitter.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.TextBoxMinJitter.ForeColor = System.Drawing.Color.Gold;
this.TextBoxMinJitter.Location = new System.Drawing.Point(182, 42);
this.TextBoxMinJitter.Name = "TextBoxMinJitter";
this.TextBoxMinJitter.ReadOnly = true;
this.TextBoxMinJitter.Size = new System.Drawing.Size(58, 22);
this.TextBoxMinJitter.TabIndex = 50;
this.TextBoxMinJitter.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.TextBoxMinJitter.TextChanged += new System.EventHandler(this.TextBoxMinJitter_TextChanged);
//
// contextMenuStrip1
//
this.contextMenuStrip1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(60)))), ((int)(((byte)(60)))));
this.contextMenuStrip1.Font = new System.Drawing.Font("Times New Roman", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4);
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(25)))), ((int)(((byte)(35)))));
this.tableLayoutPanel3.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Single;
this.tableLayoutPanel3.ColumnCount = 2;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel3.Controls.Add(this.ButtonCleanNetwork, 0, 1);
this.tableLayoutPanel3.Controls.Add(this.ButtonNetworkAdapters, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.ButtonMenu, 1, 1);
this.tableLayoutPanel3.Controls.Add(this.buttonCleanTemp, 1, 0);
this.tableLayoutPanel3.ForeColor = System.Drawing.Color.Gold;
this.tableLayoutPanel3.Location = new System.Drawing.Point(392, 31);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 2;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(311, 80);
this.tableLayoutPanel3.TabIndex = 58;
//
// dataGridView1
//
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.AllowUserToResizeColumns = false;
this.dataGridView1.AllowUserToResizeRows = false;
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle1.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle1.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridView1.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle1;
this.dataGridView1.BackgroundColor = System.Drawing.SystemColors.ActiveCaptionText;
this.dataGridView1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.dataGridView1.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Sunken;
dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle2.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle2.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle2.NullValue = null;
dataGridViewCellStyle2.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle2.SelectionForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle2;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Time,
this.Status,
this.RTT});
dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.InactiveCaptionText;
dataGridViewCellStyle6.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.ActiveCaption;
dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridView1.DefaultCellStyle = dataGridViewCellStyle6;
this.dataGridView1.EnableHeadersVisualStyles = false;
this.dataGridView1.GridColor = System.Drawing.Color.Gold;
this.dataGridView1.Location = new System.Drawing.Point(12, 118);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.ReadOnly = true;
dataGridViewCellStyle7.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle7.BackColor = System.Drawing.SystemColors.ActiveCaptionText;
dataGridViewCellStyle7.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle7.ForeColor = System.Drawing.SystemColors.MenuHighlight;
dataGridViewCellStyle7.SelectionBackColor = System.Drawing.SystemColors.GradientActiveCaption;
dataGridViewCellStyle7.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle7.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.dataGridView1.RowHeadersDefaultCellStyle = dataGridViewCellStyle7;
this.dataGridView1.RowHeadersVisible = false;
dataGridViewCellStyle8.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle8.BackColor = System.Drawing.Color.Black;
dataGridViewCellStyle8.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle8.ForeColor = System.Drawing.SystemColors.ActiveCaption;
this.dataGridView1.RowsDefaultCellStyle = dataGridViewCellStyle8;
this.dataGridView1.RowTemplate.DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
this.dataGridView1.RowTemplate.DefaultCellStyle.BackColor = System.Drawing.Color.Black;
this.dataGridView1.Size = new System.Drawing.Size(691, 330);
this.dataGridView1.TabIndex = 59;
this.dataGridView1.TabStop = false;
//
// Time
//
this.Time.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle3.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle3.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle3.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle3.SelectionForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.Time.DefaultCellStyle = dataGridViewCellStyle3;
this.Time.HeaderText = "Time";
this.Time.Name = "Time";
this.Time.ReadOnly = true;
this.Time.Width = 120;
//
// Status
//
this.Status.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle4.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle4.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle4.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle4.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle4.SelectionForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.Status.DefaultCellStyle = dataGridViewCellStyle4;
this.Status.HeaderText = "Status";
this.Status.Name = "Status";
this.Status.ReadOnly = true;
this.Status.Width = 468;
//
// RTT
//
this.RTT.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle5.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle5.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle5.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle5.SelectionForeColor = System.Drawing.Color.Gold;
this.RTT.DefaultCellStyle = dataGridViewCellStyle5;
this.RTT.HeaderText = "RTT";
this.RTT.Name = "RTT";
this.RTT.ReadOnly = true;
this.RTT.Width = 70;
//
// tableLayoutPanel5
//
this.tableLayoutPanel5.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(25)))), ((int)(((byte)(25)))), ((int)(((byte)(35)))));
this.tableLayoutPanel5.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Single;
this.tableLayoutPanel5.ColumnCount = 5;
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 72F));
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 64F));
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 64F));
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 68F));
this.tableLayoutPanel5.Controls.Add(this.labelJitter, 0, 1);
this.tableLayoutPanel5.Controls.Add(this.textBoxPacketLoss, 1, 0);
this.tableLayoutPanel5.Controls.Add(this.textBoxJitter, 1, 1);
this.tableLayoutPanel5.Controls.Add(this.TextBoxAvgLoss, 3, 0);
this.tableLayoutPanel5.Controls.Add(this.TextBoxMaxLoss, 4, 0);
this.tableLayoutPanel5.Controls.Add(this.TextBoxMaxJitter, 4, 1);
this.tableLayoutPanel5.Controls.Add(this.TextBoxAvgJitter, 3, 1);
this.tableLayoutPanel5.Controls.Add(this.TextBoxMinJitter, 2, 1);
this.tableLayoutPanel5.Controls.Add(this.TextBoxMinLoss, 2, 0);
this.tableLayoutPanel5.Controls.Add(this.labelPacketLoss, 0, 0);
this.tableLayoutPanel5.Location = new System.Drawing.Point(12, 455);
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
this.tableLayoutPanel5.RowCount = 2;
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel5.Size = new System.Drawing.Size(378, 70);
this.tableLayoutPanel5.TabIndex = 61;
//
// ButtonClearAll
//
this.ButtonClearAll.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(60)))), ((int)(((byte)(60)))));
this.ButtonClearAll.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonClearAll.FlatAppearance.BorderSize = 0;
this.ButtonClearAll.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonClearAll.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ButtonClearAll.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.ButtonClearAll.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 11F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.World, ((byte)(0)));
this.ButtonClearAll.ForeColor = System.Drawing.Color.Gold;
this.ButtonClearAll.Location = new System.Drawing.Point(395, 458);
this.ButtonClearAll.Name = "ButtonClearAll";
this.ButtonClearAll.Size = new System.Drawing.Size(88, 24);
this.ButtonClearAll.TabIndex = 64;
this.ButtonClearAll.Text = "CLEAR VALUES";
this.ButtonClearAll.UseVisualStyleBackColor = false;
this.ButtonClearAll.Click += new System.EventHandler(this.ButtonClearAll_Click);
//
// dataGridView2
//
this.dataGridView2.AllowUserToAddRows = false;
this.dataGridView2.AllowUserToDeleteRows = false;
this.dataGridView2.AllowUserToResizeColumns = false;
this.dataGridView2.AllowUserToResizeRows = false;
dataGridViewCellStyle9.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle9.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle9.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle9.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle9.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle9.SelectionForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle9.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridView2.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle9;
this.dataGridView2.BackgroundColor = System.Drawing.SystemColors.ActiveCaptionText;
this.dataGridView2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.dataGridView2.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Sunken;
dataGridViewCellStyle10.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle10.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle10.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle10.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle10.NullValue = null;
dataGridViewCellStyle10.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle10.SelectionForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle10.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridView2.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle10;
this.dataGridView2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView2.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.MinPing,
this.AvgPing,
this.MaxPing});
dataGridViewCellStyle14.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle14.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle14.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle14.ForeColor = System.Drawing.SystemColors.ActiveCaption;
dataGridViewCellStyle14.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle14.SelectionForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle14.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.dataGridView2.DefaultCellStyle = dataGridViewCellStyle14;
this.dataGridView2.EnableHeadersVisualStyles = false;
this.dataGridView2.GridColor = System.Drawing.Color.Gold;
this.dataGridView2.Location = new System.Drawing.Point(488, 455);
this.dataGridView2.Name = "dataGridView2";
this.dataGridView2.ReadOnly = true;
dataGridViewCellStyle15.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle15.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle15.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle15.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle15.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle15.SelectionForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle15.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.dataGridView2.RowHeadersDefaultCellStyle = dataGridViewCellStyle15;
this.dataGridView2.RowHeadersVisible = false;
dataGridViewCellStyle16.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
dataGridViewCellStyle16.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle16.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle16.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle16.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle16.SelectionForeColor = System.Drawing.Color.Gold;
this.dataGridView2.RowsDefaultCellStyle = dataGridViewCellStyle16;
this.dataGridView2.RowTemplate.DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
this.dataGridView2.RowTemplate.DefaultCellStyle.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.dataGridView2.RowTemplate.DefaultCellStyle.ForeColor = System.Drawing.Color.Gold;
this.dataGridView2.RowTemplate.DefaultCellStyle.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.dataGridView2.RowTemplate.DefaultCellStyle.SelectionForeColor = System.Drawing.Color.Gold;
this.dataGridView2.Size = new System.Drawing.Size(215, 54);
this.dataGridView2.TabIndex = 65;
this.dataGridView2.TabStop = false;
//
// MinPing
//
dataGridViewCellStyle11.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle11.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle11.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle11.SelectionForeColor = System.Drawing.Color.Gold;
this.MinPing.DefaultCellStyle = dataGridViewCellStyle11;
this.MinPing.HeaderText = "Min.";
this.MinPing.Name = "MinPing";
this.MinPing.ReadOnly = true;
this.MinPing.Width = 70;
//
// AvgPing
//
dataGridViewCellStyle12.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle12.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle12.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle12.SelectionForeColor = System.Drawing.Color.Gold;
this.AvgPing.DefaultCellStyle = dataGridViewCellStyle12;
this.AvgPing.HeaderText = "Avg.";
this.AvgPing.Name = "AvgPing";
this.AvgPing.ReadOnly = true;
this.AvgPing.Width = 70;
//
// MaxPing
//
dataGridViewCellStyle13.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle13.ForeColor = System.Drawing.Color.Gold;
dataGridViewCellStyle13.SelectionBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
dataGridViewCellStyle13.SelectionForeColor = System.Drawing.Color.Gold;
this.MaxPing.DefaultCellStyle = dataGridViewCellStyle13;
this.MaxPing.HeaderText = "Max.";
this.MaxPing.Name = "MaxPing";
this.MaxPing.ReadOnly = true;
this.MaxPing.Width = 70;
//
// FormPinger
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(17)))), ((int)(((byte)(23)))));
this.ClientSize = new System.Drawing.Size(715, 550);
this.Controls.Add(this.dataGridView2);
this.Controls.Add(this.ButtonClearAll);
this.Controls.Add(this.tableLayoutPanel5);
this.Controls.Add(this.dataGridView1);
this.Controls.Add(this.tableLayoutPanel3);
this.Controls.Add(this.tableLayoutPanel2);
this.Controls.Add(this.panel1);
this.Controls.Add(this.COPYRIGHT);
this.Font = new System.Drawing.Font("Cascadia Mono SemiBold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.ForeColor = System.Drawing.SystemColors.ActiveCaption;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.Name = "FormPinger";
this.Text = " ";
this.Load += new System.EventHandler(this.FormPinger_Load);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.tableLayoutPanel5.ResumeLayout(false);
this.tableLayoutPanel5.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBoxInterval;
private System.Windows.Forms.TextBox COPYRIGHT;
private System.Windows.Forms.TextBox textBoxPacketLoss;
private System.Windows.Forms.TextBox textBoxJitter;
private System.Windows.Forms.Label labelPacketLoss;
private System.Windows.Forms.Label labelJitter;
private IPAddressControlLib.IPAddressControl ipAddress;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button ButtonNetworkAdapters;
private System.Windows.Forms.Button buttonCleanTemp;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.TextBox TextBoxMaxLoss;
private System.Windows.Forms.TextBox TextBoxMaxJitter;
private System.Windows.Forms.TextBox TextBoxAvgJitter;
private System.Windows.Forms.TextBox TextBoxAvgLoss;
private System.Windows.Forms.TextBox TextBoxMinLoss;
private System.Windows.Forms.TextBox TextBoxMinJitter;
private System.Windows.Forms.Button ButtonMenu;
private System.Windows.Forms.Button ButtonCleanNetwork;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5;
private System.Windows.Forms.Button ButtonExit;
private System.Windows.Forms.Button ButtonMinimize;
private System.Windows.Forms.Button ButtonClearAll;
private System.Windows.Forms.DataGridView dataGridView2;
private System.Windows.Forms.DataGridViewTextBoxColumn Time;
private System.Windows.Forms.DataGridViewTextBoxColumn Status;
private System.Windows.Forms.DataGridViewTextBoxColumn RTT;
private System.Windows.Forms.DataGridViewTextBoxColumn MinPing;
private System.Windows.Forms.DataGridViewTextBoxColumn AvgPing;
private System.Windows.Forms.DataGridViewTextBoxColumn MaxPing;
private System.Windows.Forms.Label label4;
}
}

808
FormPinger.cs Normal file
عرض الملف

@@ -0,0 +1,808 @@
using System;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Pingerino.Infrastructure;
using Pingerino.Services.Interfaces;
using Pingerino.Utilities;
namespace Pingerino
{
public partial class FormPinger : Form
{
#region Services
private readonly IPingService _pingService;
private readonly INetworkService _networkService;
private readonly IConfigurationService _configService;
private readonly ISystemService _systemService;
private readonly ILoggingService _logger;
#endregion
#region Fields
private CancellationTokenSource _cancellationTokenSource;
private System.Threading.Timer _publicIpTimer;
private string _currentPublicIp = "Loading...";
private bool _disposed;
#endregion
#region Constructor
public FormPinger()
{
InitializeComponent();
// Get services from container
_pingService = ServiceContainer.Instance.GetService<IPingService>();
_networkService = ServiceContainer.Instance.GetService<INetworkService>();
_configService = ServiceContainer.Instance.GetService<IConfigurationService>();
_systemService = ServiceContainer.Instance.GetService<ISystemService>();
_logger = ServiceContainer.Instance.GetService<ILoggingService>();
InitializeFormAsync();
}
#endregion
#region Initialization
private async void InitializeFormAsync()
{
try
{
_logger.LogInformation("Initializing Pingerino application");
// Setup UI
SetupUI();
// Load configuration
LoadConfiguration();
// Setup event handlers
SetupEventHandlers();
// Initialize services
await InitializeServicesAsync();
_logger.LogInformation("Application initialized successfully");
}
catch (Exception ex)
{
_logger.LogError("Error during application initialization", ex);
UIHelper.ShowError($"Failed to initialize application: {ex.Message}");
}
}
private void SetupUI()
{
// Apply rounded corners
UIHelper.ApplyRoundedCorners(this);
// Enable form dragging
UIHelper.EnableFormDragging(this, panel1);
// Enable double buffering
this.DoubleBuffered = true;
// Initialize context menu
InitializeContextMenu();
// Set default values
textBoxInterval.Text = "300";
ipAddress.Select();
}
private void LoadConfiguration()
{
try
{
// Load form position
var savedPosition = _configService.FormPosition;
if (savedPosition != Point.Empty)
{
this.Location = savedPosition;
}
// Load IP address and interval
ipAddress.Text = _configService.IpAddressValue;
textBoxInterval.Text = _configService.TextBoxIntervalValue;
_logger.LogInformation("Configuration loaded successfully");
}
catch (Exception ex)
{
_logger.LogError("Error loading configuration", ex);
}
}
private void SetupEventHandlers()
{
// Form events
this.Load += FormPinger_Load;
this.FormClosing += FormPinger_FormClosing;
// Input events
textBoxInterval.KeyDown += TextBoxInterval_KeyDown;
ipAddress.KeyDown += TextBoxIpAddress_KeyDown;
// Button events are handled by Designer file - no manual registration needed
// Service events
_pingService.PingCompleted += PingService_PingCompleted;
_pingService.StatisticsUpdated += PingService_StatisticsUpdated;
}
private async System.Threading.Tasks.Task InitializeServicesAsync()
{
// Start public IP fetching
await StartPublicIpUpdatesAsync();
// Start initial ping if auto-ping is enabled
if (_configService.AutoPingEnabled)
{
await StartPingingAsync();
}
}
#endregion
#region Event Handlers
private async void FormPinger_Load(object sender, EventArgs e)
{
await UpdateNetworkStatisticsAsync();
}
private async void FormPinger_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
// Save configuration
_configService.FormPosition = this.Location;
_configService.IpAddressValue = ipAddress.Text;
_configService.TextBoxIntervalValue = textBoxInterval.Text;
_configService.Save();
// Stop services
await _pingService.StopPingingAsync();
_publicIpTimer?.Dispose();
_cancellationTokenSource?.Cancel();
_cancellationTokenSource?.Dispose();
_logger.LogInformation("Application closing - configuration saved");
}
catch (Exception ex)
{
_logger.LogError("Error during application shutdown", ex);
}
}
private async void TextBoxInterval_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
await HandleIntervalChangeAsync();
}
}
private async void TextBoxIpAddress_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
await HandleIpAddressChangeAsync();
}
}
private void ButtonExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void ButtonMinimize_Click(object sender, EventArgs e)
{
WindowState = FormWindowState.Minimized;
}
private async void ButtonClearAll_Click(object sender, EventArgs e)
{
await ClearAllDataAsync();
}
private async void ButtonCleanNetwork_Click(object sender, EventArgs e)
{
await ResetNetworkAsync();
}
private async void ButtonCleanTemp_Click(object sender, EventArgs e)
{
await CleanTemporaryFilesAsync();
}
private void ButtonNetworkAdapters_Click(object sender, EventArgs e)
{
_systemService.OpenNetworkAdaptersControl();
}
private void ButtonMenu_Click(object sender, EventArgs e)
{
contextMenuStrip1.Show(ButtonMenu, 0, ButtonMenu.Height);
}
// Additional event handlers referenced by Designer
private void COPYRIGHT_TextChanged(object sender, EventArgs e)
{
// Copyright text changed - no action needed
}
private void TextBoxInterval_TextChanged(object sender, EventArgs e)
{
// Interval text changed - we handle this with KeyDown events instead
}
private void TextBoxJitter_TextChanged(object sender, EventArgs e)
{
// Jitter display text changed - no action needed (read-only display)
}
private void Label1_Click(object sender, EventArgs e)
{
// Label click - no action needed
}
private void LabelJitter_Click(object sender, EventArgs e)
{
// Jitter label click - no action needed
}
private void IpAddress_Click(object sender, EventArgs e)
{
// IP address control click - no action needed
}
private void Label2_Click(object sender, EventArgs e)
{
// Label click - no action needed
}
private void Panel1_MouseDown(object sender, MouseEventArgs e)
{
// Panel mouse down - form dragging is handled by UIHelper.EnableFormDragging
}
private void Label3_MouseDown(object sender, MouseEventArgs e)
{
// Label mouse down - form dragging is handled by UIHelper.EnableFormDragging
}
private void TextBoxMinJitter_TextChanged(object sender, EventArgs e)
{
// Min jitter display text changed - no action needed (read-only display)
}
#endregion
#region Service Event Handlers
private void PingService_PingCompleted(object sender, PingResultEventArgs e)
{
UIHelper.SafeInvoke(this, () =>
{
var timestamp = e.Timestamp.ToString("HH:mm:ss.ff");
var status = e.Result.IsSuccess ?
$"Pinging {e.Result.IpAddress} - Success" :
$"Ping to {e.Result.IpAddress} - Failed: {e.Result.Status}";
var rtt = e.Result.IsSuccess ? $"{e.Result.RoundTripTime} ms" : "";
AddLineToOutput(timestamp, status, rtt);
});
}
private void PingService_StatisticsUpdated(object sender, NetworkStatisticsEventArgs e)
{
UIHelper.SafeInvoke(this, () =>
{
UpdateStatisticsDisplay(e.Statistics);
});
}
#endregion
#region Business Logic Methods
private async System.Threading.Tasks.Task HandleIntervalChangeAsync()
{
try
{
var intervalText = ValidationHelper.SanitizeInput(textBoxInterval.Text);
if (!ValidationHelper.IsValidPingInterval(intervalText, out int interval))
{
UIHelper.ShowError(ValidationHelper.GetValidationErrorMessage("Interval", intervalText));
return;
}
await ClearAllDataAsync();
if (_pingService.IsRunning)
{
await _pingService.StopPingingAsync();
await _pingService.StartPingingAsync(ipAddress.Text, interval);
}
_logger.LogInformation($"Ping interval changed to {interval}ms");
}
catch (Exception ex)
{
_logger.LogError("Error changing ping interval", ex);
UIHelper.ShowError("Failed to change ping interval");
}
}
private async System.Threading.Tasks.Task HandleIpAddressChangeAsync()
{
try
{
var address = ValidationHelper.SanitizeInput(ipAddress.Text);
if (!ValidationHelper.IsValidIpAddressOrHostname(address))
{
UIHelper.ShowError(ValidationHelper.GetValidationErrorMessage("IP Address", address));
return;
}
await ClearAllDataAsync();
// Save to configuration
_configService.LastUsedIpAddress = address;
_configService.Save();
// Restart pinging if it was running
if (_pingService.IsRunning)
{
var interval = int.Parse(textBoxInterval.Text);
await _pingService.StopPingingAsync();
await _pingService.StartPingingAsync(address, interval);
}
_logger.LogInformation($"IP address changed to {address}");
}
catch (Exception ex)
{
_logger.LogError("Error changing IP address", ex);
UIHelper.ShowError("Failed to change IP address");
}
}
private async System.Threading.Tasks.Task StartPingingAsync()
{
try
{
var address = ValidationHelper.SanitizeInput(ipAddress.Text);
var intervalText = ValidationHelper.SanitizeInput(textBoxInterval.Text);
if (!ValidationHelper.IsValidIpAddressOrHostname(address))
{
UIHelper.ShowError("Please enter a valid IP address or hostname");
return;
}
if (!ValidationHelper.IsValidPingInterval(intervalText, out int interval))
{
UIHelper.ShowError("Please enter a valid ping interval (100-60000 ms)");
return;
}
await _pingService.StartPingingAsync(address, interval);
_logger.LogInformation($"Started pinging {address} with {interval}ms interval");
}
catch (Exception ex)
{
_logger.LogError("Error starting ping service", ex);
UIHelper.ShowError("Failed to start pinging");
}
}
private async System.Threading.Tasks.Task ClearAllDataAsync()
{
try
{
_pingService.ClearStatistics();
UIHelper.SafeInvoke(this, () =>
{
dataGridView1.Rows.Clear();
dataGridView2.Rows.Clear();
// Reset statistics display
ResetStatisticsDisplay();
});
// Refresh public IP
await FetchPublicIpAsync();
_logger.LogInformation("All data cleared");
}
catch (Exception ex)
{
_logger.LogError("Error clearing data", ex);
}
}
private async System.Threading.Tasks.Task ResetNetworkAsync()
{
try
{
if (!UIHelper.ShowConfirmation(
"This action will release and renew network settings. Are you sure you want to continue?",
"Confirm Network Reset"))
{
return;
}
var adapter = await _networkService.GetActiveEthernetAdapterAsync();
if (adapter == null)
{
UIHelper.ShowError("No active Ethernet adapter found");
return;
}
ButtonCleanNetwork.Visible = false;
var progress = new Progress<int>(value =>
{
UIHelper.SafeInvoke(this, () =>
{
// Update progress if you have a progress bar
});
});
var success = await _networkService.ResetNetworkAdapterAsync(adapter.Name, progress);
UIHelper.SafeInvoke(this, () =>
{
ButtonCleanNetwork.Visible = true;
if (success)
{
AddLineToOutput(DateTime.Now.ToString("HH:mm:ss.ff"), "Network reset completed", "");
}
else
{
UIHelper.ShowError("Network reset failed");
}
});
}
catch (Exception ex)
{
_logger.LogError("Error during network reset", ex);
UIHelper.SafeInvoke(this, () =>
{
ButtonCleanNetwork.Visible = true;
UIHelper.ShowError("Network reset failed");
});
}
}
private async System.Threading.Tasks.Task CleanTemporaryFilesAsync()
{
try
{
buttonCleanTemp.Visible = false;
var progress = new Progress<int>(value =>
{
UIHelper.SafeInvoke(this, () =>
{
// Update progress if you have a progress bar
});
});
var success = await _systemService.CleanTemporaryFilesAsync(progress);
UIHelper.SafeInvoke(this, () =>
{
buttonCleanTemp.Visible = true;
if (success)
{
UIHelper.ShowInformation("Temporary files cleaned successfully");
}
else
{
UIHelper.ShowError("Failed to clean temporary files");
}
});
}
catch (Exception ex)
{
_logger.LogError("Error cleaning temporary files", ex);
UIHelper.SafeInvoke(this, () =>
{
buttonCleanTemp.Visible = true;
UIHelper.ShowError("Failed to clean temporary files");
});
}
}
private async System.Threading.Tasks.Task StartPublicIpUpdatesAsync()
{
await FetchPublicIpAsync();
// Update public IP every hour
_publicIpTimer = new System.Threading.Timer(async _ => await FetchPublicIpAsync(), null,
TimeSpan.FromHours(1), TimeSpan.FromHours(1));
}
private async System.Threading.Tasks.Task FetchPublicIpAsync()
{
try
{
_cancellationTokenSource?.Cancel();
_cancellationTokenSource = new CancellationTokenSource();
var publicIp = await _networkService.GetPublicIpAddressAsync(_cancellationTokenSource.Token);
_currentPublicIp = publicIp;
UIHelper.SafeInvoke(this, () =>
{
label4.Text = $"Public IP: {publicIp}";
});
}
catch (Exception ex)
{
_logger.LogError("Error fetching public IP", ex);
UIHelper.SafeInvoke(this, () =>
{
label4.Text = "Error fetching IP";
});
// Retry after delay
await System.Threading.Tasks.Task.Delay(30000);
_ = System.Threading.Tasks.Task.Run(async () => await FetchPublicIpAsync());
}
}
private async System.Threading.Tasks.Task UpdateNetworkStatisticsAsync()
{
try
{
var address = ValidationHelper.SanitizeInput(ipAddress.Text);
if (!ValidationHelper.IsValidIpAddressOrHostname(address))
return;
// This will trigger the StatisticsUpdated event
await System.Threading.Tasks.Task.Run(async () =>
{
var result = await _pingService.PingOnceAsync(address);
// Statistics are automatically calculated and updated via events
});
}
catch (Exception ex)
{
_logger.LogError("Error updating network statistics", ex);
}
}
#endregion
#region UI Helper Methods
private void AddLineToOutput(string time, string status, string rtt = "")
{
if (dataGridView1.IsDisposed || !dataGridView1.IsHandleCreated)
return;
UIHelper.SafeInvoke(this, () =>
{
dataGridView1.Rows.Add(new object[] { time, status, rtt });
// Auto-scroll to bottom
if (dataGridView1.Rows.Count > 0)
{
dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.Count - 1;
}
});
}
private void UpdateStatisticsDisplay(NetworkStatistics stats)
{
try
{
// Update ping statistics
if (dataGridView2.Rows.Count == 0)
{
dataGridView2.Rows.Add();
}
var row = dataGridView2.Rows[0];
row.Cells["MaxPing"].Value = $"{stats.MaxPing} ms";
row.Cells["MinPing"].Value = $"{stats.MinPing} ms";
row.Cells["AvgPing"].Value = $"{stats.AveragePing:F0} ms";
// Update jitter statistics
TextBoxMaxJitter.Text = $"{stats.MaxJitter:F0} ms";
TextBoxMinJitter.Text = $"{stats.MinJitter:F0} ms";
TextBoxAvgJitter.Text = $"{stats.AverageJitter:F0} ms";
// Update packet loss statistics
TextBoxMaxLoss.Text = $"{stats.MaxPacketLoss:F0}%";
TextBoxMinLoss.Text = $"{stats.MinPacketLoss:F0}%";
TextBoxAvgLoss.Text = $"{stats.AveragePacketLoss:F0}%";
// Update current values
textBoxPacketLoss.Text = $"{stats.PacketLoss:F2}%";
textBoxJitter.Text = $"{stats.Jitter:F2}ms";
}
catch (Exception ex)
{
_logger.LogError("Error updating statistics display", ex);
}
}
private void ResetStatisticsDisplay()
{
if (dataGridView2.Rows.Count > 0)
{
dataGridView2.Rows[0].Cells["MaxPing"].Value = "0 ms";
dataGridView2.Rows[0].Cells["MinPing"].Value = "0 ms";
dataGridView2.Rows[0].Cells["AvgPing"].Value = "0 ms";
}
TextBoxMaxJitter.Text = "0 ms";
TextBoxMinJitter.Text = "0 ms";
TextBoxAvgJitter.Text = "0 ms";
TextBoxMaxLoss.Text = "0%";
TextBoxMinLoss.Text = "0%";
TextBoxAvgLoss.Text = "0%";
textBoxPacketLoss.Text = "0%";
textBoxJitter.Text = "0ms";
}
#endregion
#region Context Menu
private void InitializeContextMenu()
{
contextMenuStrip1 = new ContextMenuStrip();
contextMenuStrip1.Items.Add("[1] Show Network Details");
contextMenuStrip1.Items.Add("[2] Auto Ping");
contextMenuStrip1.Items.Add("[3] Run with Windows");
contextMenuStrip1.Items.Add("[4] Proxy");
// Attach event handlers
contextMenuStrip1.Items[0].Click += ShowNetworkDetails_Click;
contextMenuStrip1.Items[1].Click += AutoPing_Click;
contextMenuStrip1.Items[2].Click += RunWithWindows_Click;
contextMenuStrip1.Items[3].Click += Proxy_Click;
UpdateContextMenuItems();
}
private async void ShowNetworkDetails_Click(object sender, EventArgs e)
{
try
{
var adapters = await _networkService.GetNetworkAdaptersAsync();
var activeAdapters = adapters.Where(a => a.IsActive).ToList();
if (!activeAdapters.Any())
{
UIHelper.ShowInformation("No active network adapters found");
return;
}
var details = string.Join("\n\n", activeAdapters.Select(adapter =>
$"Description: {adapter.Description}\n" +
$"Physical Address: {adapter.PhysicalAddress}\n" +
$"DHCP Enabled: {(adapter.IsDhcpEnabled ? "Yes" : "No")}\n" +
$"IPv4 Address: {adapter.IpAddress}\n" +
$"IPv4 Subnet Mask: {adapter.SubnetMask}\n" +
$"IPv4 Default Gateway: {adapter.DefaultGateway}\n" +
$"IPv4 DHCP Server: {adapter.DhcpServer}\n" +
$"IPv4 DNS Servers: {string.Join(", ", adapter.DnsServers)}"
));
UIHelper.ShowInformation(details, "Network Details");
}
catch (Exception ex)
{
_logger.LogError("Error showing network details", ex);
UIHelper.ShowError("Failed to retrieve network details");
}
}
private async void AutoPing_Click(object sender, EventArgs e)
{
try
{
if (_pingService.IsRunning)
{
await _pingService.StopPingingAsync();
_configService.AutoPingEnabled = false;
}
else
{
await StartPingingAsync();
_configService.AutoPingEnabled = true;
}
_configService.Save();
UpdateContextMenuItems();
}
catch (Exception ex)
{
_logger.LogError("Error toggling auto ping", ex);
UIHelper.ShowError("Failed to toggle auto ping");
}
}
private async void RunWithWindows_Click(object sender, EventArgs e)
{
try
{
const string taskName = "Pingerino";
var executablePath = Application.ExecutablePath;
var taskExists = await _systemService.IsStartupTaskExistsAsync(taskName);
bool success;
if (taskExists)
{
success = await _systemService.RemoveStartupTaskAsync(taskName);
}
else
{
success = await _systemService.CreateStartupTaskAsync(taskName, executablePath);
}
if (success)
{
UpdateContextMenuItems();
}
else
{
UIHelper.ShowError("Failed to update startup task");
}
}
catch (Exception ex)
{
_logger.LogError("Error managing startup task", ex);
UIHelper.ShowError("Failed to manage startup task");
}
}
private async void Proxy_Click(object sender, EventArgs e)
{
try
{
var scriptPath = System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(Application.ExecutablePath),
"runPS1.bat");
var success = await _systemService.RunExternalScriptAsync(scriptPath);
if (!success)
{
UIHelper.ShowError("Proxy script not found or failed to execute");
}
}
catch (Exception ex)
{
_logger.LogError("Error running proxy script", ex);
UIHelper.ShowError("Failed to run proxy script");
}
}
private async void UpdateContextMenuItems()
{
try
{
// Update auto ping status
contextMenuStrip1.Items[1].Text = _pingService.IsRunning ?
"[2] Auto Ping ✔" : "[2] Auto Ping";
// Update startup task status
var taskExists = await _systemService.IsStartupTaskExistsAsync("Pingerino");
contextMenuStrip1.Items[2].Text = taskExists ?
"[3] Run with Windows ✔" : "[3] Run with Windows";
}
catch (Exception ex)
{
_logger.LogError("Error updating context menu items", ex);
}
}
#endregion
}
}

377
FormPinger.resx Normal file
عرض الملف

@@ -0,0 +1,377 @@
<?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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="Time.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Status.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="RTT.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="MinPing.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="AvgPing.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="MaxPing.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>39</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.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>
AAABAAEAAAAAAAEAIAAgNQAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAEAAAABAAgEAAAA9ntg7QAANOdJ
REFUeNrt3XecHVX5P/D33d6y6Z0kCARC6B1p0pEmIAgiTazATxAVC2JXRL+iWFBUpDcBaYL03qtAaCFA
QnpPNmWzfef3xz07mbv1bjTZ4v3MK6/X5szMuTPnPHPO0x9yyCGHHHLIIYcccsghhxxyyCGHHHLIIYcc
csghhxxyyCGHHHLIIYcccsghh/6DVE8/QK9EyiQfs7FiVV73hOU9/UA5bFgcYapmkUikxi3G9PQD5bAh
MczTIlWucrpfWa7Z13v6kXLYkNhTlZXOUIwCF4vcqKCnH2p9Ia+nH6AXYqwK1aapQ6MpIkX9d5z67Yv9
ByiXMsoRYILTpCzU0NMPtb6QI4C2KJGHGnCs/UTeE/X0Q60v5AigLcag0bso8TEpDWb29COtP/Qn5qbC
lkaKrDTXTE3r2EuZHbHEFAwzEWss7OlXy6FrfMTfLVajxgrv+dI6r227WShynwrsaJHIXJN7+uVy6Ap5
fhkUN+njVSPXqZ8SfxVpcCY4RLXINON7+vXWH/rLFlBh94z/jzN+nRbuY5yAN90DhirC6sAQZoM8E2xj
Y41e8fI6b0MbEP2FAIqUZ/y/wuh16GVz31Wpxh/NASPko1pdlvdPcJajVbjP3sqd6e6eHpb/HVR6UiRS
7x1rRJqd0e0+ClysWeRfMTH9USTygLKs7i93g8gyX1TkayK3Ku7pYeka/UUMrA0L/qOOdj9S67ACTHa8
FIY51vZG281+oE5zVvdPdKB6v3CVem+ps7lBPT0sXaO/bAENFqHJbd71vGMwSqpb6puUo20EdrWjpZYY
aCyoz5oAhnrTdRqllUllfWEF6C8EEKnFClNQJZIyWrHabvQwxMdj74gCIxNSxJosmbmR8s0OvgNbKFSr
vqeHpWv0ly0g3xAsMEfLkj1cabd6mGzLDs6szHIFKEGFQpT4KOZZ1dPD0jX6CwEMsw3etQRVGjFERbd6
2NnADs4szXIrGYRRBmKUrfGaNT09LF2jvxDAQbYSeUEdFlqDgYZ04/5820ih2YpWZyKLsuqhyERUqsRG
Rlrpwb5gQuofBDDKmUqs8jyYYQ4qDO9GD+U2Acu9qDpj4hosyKqHMbZDowaMVuFVL/f0sGSD/sEEHm4X
FPuyXawx0lCUGNWNHlrIpcqPHOmrCf5hjflZ9XCgTTDLYgyW5/2+wAH0DwIocahCFDvRiXFrfhDqskOF
AaBele0z2McVWW0Bo31OoWYPWiHNDpbJz5J57FH0hy1gtO06aM8eJYpAvom2zzgz39Iu7y7wJbvgPbeI
0IDJhvX0wGSD/kAAm3Sw2I/oxvpWIB+UGN5KfTPD6i7v3s2XFWjwV9PAGs0m2rWnByYb9A8CaF9XX9EN
AigLK0Cx1VZgRbx8v9OlP2CRzxuNJ10d2McmkTKfUNjTQ9M1+gMPMLYDMm7uhhg2LHz3kff8xmSLnC8P
dd7o8t5NHYBmM+1quWr1NpOHvY0zvacHpyv0fQJIdbjXrtSYdS/jwgqwxlKXyvOpoBZeZGqX9+5gNPKc
6kS1ajUaKIXxtssRwPpHXitPgLWYm7VDRsrEMOELVIk0KQ2rynvmdnn35LDUFyjIkB8Ku6WK6iH0Bx6g
/QDXpiy+3RaU2SL8NTVI76Wh17e7ZAHzY4ex2WYjirmHKm/19NB0jb6/AjR3oHBZmsXu3YIRNgVNXgir
RrkUIlO75COKgwppqjMUONR4BwU/gMVZrB49jr5PAJEZ7ba/7f2s+9giCJILPBda0oakuiwiAooNQqM/
eQIr/VVlOLNAVU8PTtfoD1vAA94EM7wWt0UetzLrHnYOguTz3gst6Ulck4UWsEgZar2BfGfaPh7TxVn7
EvYg+gMBvOV+MN0vLAltqz2VtRBYbg8pNLgnuJDkBdNwbRZKoGKlKHWIcfaxT+JMn4go7A8EkBe+18h9
vuoxzZgbdHLZYJOgSp7l6dBSECwDjVkIkqVKkO9cD/l74CXSmNsXzMF9nweg1EdAg3o3Ym95FndjA9g3
uH+9YFZoyQ88QCqLFDrlSkCJLTRZZGhQKjf2jYjC/rACjAzf3UpNGBgmIFtUOlI+mjwZ+/AVBt1CYVAP
dX5/SfirwSU+6cnwv1W9XwlE/yCAFh5+rkaMl8LwmBfvCgf5KKjyatxWHFaA0rAVdIYRMQE87SJjbBoW
/nlm9/TAZIP+QAC7KEOzqSJ5BpstMjp4+HSFSl8Kk70s4fhREqSC4ix0eRsHPWCdKy2zUyBA3rK4pwcm
G/R9AigPUYGLvQJuc7lmlXbJ6u7RJqPJNLcnJqws3gK6IoD82Jf4HY8QawGbPNEXnML7AxM43tbgae+g
2UMqNMm3u+Is5PDhBuAF/8+cxNUjwtKf1+UWMNS24a/HLCQW/BZ7pqcHJjv0fQLY3ihEnotjeBdYo8gW
BmfhzjlECQb7sQFecqcZGgx1WuAgUl1a9Lc1EdR6QjOx+Wl6LFH0cvR1AkjZRSGihOPWfEsMMsroLAhg
gAJsaUvs5/PmqTPUuLCPR13EFuU5NKwRC7wdnieNGX3DJbTvE0BF8OBLGRq3LTXLZiqMTvD1HaE8gwsa
mugFarv4jic4NPw1JyiNW8ZzUTd8EXoUfZ0JHBN0ACkHxJO32nwUh9DOzlHWqapnqtc7vfvwsAGwKrB8
xdIG4RX+E5TY0p4bJra4r68Am8T+QAe4xrNWiQy1O/Ky8gruLH6w0bXmdXJ+pJMUoMF8lUrUSCnDcvX/
AQdQ7ACn2kulv7hg/UsSfZ0ANo+nsMjhDs84NzKLAPHOCGChhzq9/zA7gre8a40a5BuIqQoSdsnuodC5
zlfpDdU+5wEPr+8B7NsEkLJxJ0v4MAVd2uNaXMCbLbfUSnUaNRpjS7zfqS5vqFODovhpV1qkFoWGYop3
A0vYfezlG5p9z9U2cYuzPKe6R0a2jyDfdRm5wTKPBzv0FlyL34RrH7K78YYaaIBy3xWJXN4ph3SiNeHe
8+O2Yf4t8tNuBqavRblbNfm+fOS5xEoHru8h7NtMYHOnAdgDu8zQkYqNPS953ixLrbBKdWAn3+8ktGuA
k+JpblEWFdrBOJxmm3V8n7183HMu14Rm/5LvyPU9Q32bAKJ2UsFFGtRoJqsULS2KnuUZbWPR2Ckjt7u9
8KZvecmEsJFO8htDMc4B6/Q2xU5R6I+x9mKpOkPX9wz1bR5AQn8/xws+tMRyy+T7uY8oi+10HSEVTMdR
htqm2AjUdKJGKvBJA/Gav/hHbP9rMChwJBO6mZ8oje0d4jH3xv+fpMhD61uf0NcJ4DVP2spQTX7hb7E2
f7DzfERJl3vxWgJIbiXlhmJ1J/6AG4X8YccY7iZPyNOEOWaEiOTCdSCAPMercEWsQci3nwWxd8F6Q18n
gGcd5VInQcKY06xOi7de50gTQFNGLtAKlVjZiU/RzjYG5Q6xvw+95BXTlcU6iVXrEBi+pxM9kxD7RtnT
U+vfp6CvE0CTPCW4Ovbng0Y1KMx6BWjOsBuWK8XyDh1CU3ZNcBeFJproM+qJWcruxwNs42LlLk04ku9s
rAfXv0K5bzOBcKZD8V6G0rZRNfK75AFajDdNrQigGMs6NAQVm9ROa1E8/fU+6OY7bOcyu3rUg3FLvkMt
88L6H76+TwCLFePAjBxfTaqR16VHXyq8f3OGwqhCEZZ2qIYtM6LTXpd0wyOZlANdYU8rXJXgRMbY1wsh
Y/F6Rd8ngMd8iN3tZ0C8MDdZrTsrQCYBVCrEsg5DS4vifASvuchdbVy/3u2GJSDlSH+zkyZ/9QBSYVPe
w3iPbwifor7OAzDDkzZV4Ry7ed+VIkRhBehaD9BCAMm9tlI+lnV4T37QHlT5rvuU2dE5jk64jjzTDV+A
SX5hgsit/k+dTZ1jtZ9pdKTqDbEB9AcCaPSEUxTYx+6mezRECq5GXhZMYAsBJL/2CnmiTgigOBDWW57D
Gk97R73PhL5WeDRrETDPqbbU7HbnWYKDnOMJKZv6mDe6zUmsE/r+FsAUy6S/y8HBP5A1yMsizXsLD5BJ
ADR1Ui+4IvS7NhHcUr+NdZKvZuGG0oJRDhP5h/9nLvLsgg/VOMRYj2URlvZfQN9fAdJx+SOwzNmeDW3p
wevaGNTi+pWU28vR2IkWYHAggAUJsplmmlFocmc3YoK3NtGTLreXMo02dQRmG+hYKz2yYQLL+gMBrDTd
TqiwOvYMXKVZXhbZglsIIDnYA9DQCQGMCsxl8gutD/+b6b5uPPkOlnrQxbZGJF8Kyx1hV091I7vBf4T+
sAXUhyCsUpvHbas00iUBpNpZAdJkU9cJIzc2MHxJT4SSIIY+0Y2AsDwTPWgfozxgjYKQkmKkzyt014Zy
Ku0PBMBMEVKJMu+rNWJAl+/XdgXIV46aTvSAEzLuTWOsjVHr3m7o7spsZCN7ed7Jzo0D2z9hd9NDwPsG
QP8ggLlBYl5rPK3WiEFdbnHtrQClqOmwUlhRnBMo+Y3uZSSmd0t0G2JjByr1qOVuDNxLyiQlbu8g68l6
QP8ggEVBh7Y2Mjhd6WtwF7rAtZrAtQSQHwigIyXMgGDxa0oogEp9XAGe7tSJtDU2M0aeVV5GnZ/6Wpj2
6a7bcAXn+gcBVAXPufIEAdRiUBe6wLXGoLUDXqAYazoMKxsWYpFrEsGk4+2Aeo92a+L2VIEiGyHysmc0
osGf19mjcB3QH6QAVgcCKE0QQDUqlcd7a3tItaMHKFCC6g7dSTcyGKxIEMD2RmN2tyoEDHeoFEp9V6E5
dvc5E3GbKzZklvH+QQA1YT8uid8nnd2n0uBO83S0EEBjggAKlWBNh8zcZkG/uDDeAlJ2VYRXumW9P8wO
4a/tXKlOhRRe9sNOdJDrAf2DAFqEtsJ4BaizEhVd2O1aTC/1ie+9SDHBq7C9OzYPRPNhrCkYYEc0e6ob
xpsJ/l/Ynpo0xMnqn/H1blkS/wvoHzxAY9gC1hJAveW6Dg/LCwTQ0IYAOqoVWBLrGqbFXMJYm9Et632Z
b9kp/P2aD8NfU5zlxQ09dP2DAFpcuvLj92mwGPld5AnJDwRQkyCAYkXSCd/bw5CQkKoxwahNMhzTsk5M
medUnw1POsu1QV212s9N2fBD1z+2gBaXrryYAKLg07uZwk6igwriHOFrrylRSIfxRuOCDLDCu3Hbtorx
YtY2gN2cH6wJi3yHkKPsgVCxfAOjf6wAUdh98xMTN0sTNuuwGiAtIh+r2hBAUQcjs0Xob27s9FFkG9R7
IUvjzTDfD6qkGc5xi+0Votq1PRME1l8IIM2z5ydSxM1Vh/HGdXJfcWDElid4/jKFqGg32VzK1qF9asyr
DzERi7JcvvN83oGod59T3KwoGLCn9FRKmf5BAC3JmQpjv5zJTlaAIZ2GaZWEeP4PE2LgAIUY1K43UWno
LfJazPGPMxbvZSkC7uwshRb6lpM8g+E2A49tWOFvLfoLAaRRFE9bhcMVocAenSSOrFSGD9yWaBsUCKc9
S+KoMF01CaePSQbi1azcNyp8zXistkyFIsUONwFrPNtTaWX7BxOYimt+tTiBTfOGj4GPGtmhhn6EMqyO
g8BSIsPkYYgh7dy1eZyScmp8xw4KNPp3VhN4uCPBpi433Tsi+yjGogRLuYHRP1aAlmxepXHRxxWhjCwT
7dbhfRsrxoi4yOxhdgmmnoHtlp3cMfgYvRWTzAA7YLl3snjKkc6OfZSKbemTjg2/vKIbmY3/y+gvBJBe
+kudHmcOnxr29VJHd2ATzLetlEUWxYziEL9zSLhrszbXl4Tkk5Hn46CRj5iEmVk5gh/fYSXBqi6yka1H
bBgCGGgnexu/3uro5YfvPpWI6Fsac/YHxckcMzHczmh2WxyA8bzRoXpQypZtdAFjQz8rEzq/vQzHO1no
AMY5PX7/1R5PBH1EntkwDqA9g0pf9KjFVprmRidkncS5Oyj3cMjW8ft42k7SFOcK+UO7pHekapHIB74a
zhe5Pr7noTZs4AnqRCIvBwtDnlO8IxL5VhbPeLaG0PNqXzfQ59WG/8/ogED7CU5QY64L/cA9qtS6qltV
vbPDEC+GwfxO3Ha66TEJLLBXm3sKXRFP9q0x83hiPC3TYtevluuvDGd+F9bN4V4WiaxplZyqPQzzTPxr
1yjDRDNFIk0u7GaC+z6Gz2jw7WD5PtSTGt3Urbre2WC8d0WafeiouG2ASf7sHY0ikRvaxAhsYXqYkPn2
jltHeym0LrdnxvWTzBCJVAdOnl0tEYnMMbnLJzzM6tDv4kCMI70uEpkep5vup9jce/4Wi5tjXKrGg7Et
7L+DbS0QWeCAVuxeiXM0i0SWhZQOa/HFQBqRvyY2iJSz1ItEGkLWgRZ8I1z/YmxiPj5c+WKr/KLt4Tvx
939PkAQmeC+sJz36/a9/JvA9lzs8zpozz3fd4CDXBH+Y/w7GGIA3PN/KIl9rvissxGBHZwx0kf3C/1e7
PWEJiNzkZk0oCHa/NEY4Tj6aE2nlNwqEM7tLF+5ULGc0eUC1gYY6wFhUuXPD+f/1FHax1HuOiid8R1NF
5jgji8CN7HCGZpHftiGpSuUKXB6+02SN4bHeCl/ky6F9rSVxfNgG/pL4PE5SIxKZHQefcVHo4ZIuSXmw
p8K1M00yyb1etEAk8linxqoNgA2hCXzTlb7mD2o9AF71RRfa228c5AYvWdppsrdsMFZK5H0R8mxlgCXy
bedz3nd+8LHZyKiEf+DYmBV9RaGj7WQ0Fnrdc2a5z87SiSbTK0qlk4PZ6O3YYTsVT938LrWA28dk86D3
/SROMR156D/MKtxHMMjPrfRWYuffyI/NE1ljqnucEevi1gUpfxCpdzwY5gnLzTJHjUi9L/mxSGRlUA2n
cUic5vFZT8d/RxpNcbIvaxJ5MGYcj7EqnP9L/LXnuUK1Bs2+0MXzFfpTuHuZfW3kjfjXlrUjnfRTFDvN
HE8l9Gt59vN0GIh69/0HsnCaAGodgVI/jAW59HF/+JWa+LuDg4MOYO2xykvudpeH3eNOTSIPBXZtgLtF
IlVecFnMSeS72kxrNDihi+fb2ZzwGzcr9pVYHxB5pi/UF//v4RgL/DMRvsVE9wUuPXJjFukcOsL3RRp9
2WgXt5nYlWHAaxyRuGMb81pd12SlaR51u6eCyHZTYPIOtVKk3o+MCwEgkO8WL1qp3ic7fbbiwINEltrf
iFhjEan3lf8iI9wHkOccNf6WUYdnsqkWqxK59T8ggEOtEnnP87Fo1/aozSCAcnd1eGX6aHYeKPQ3kcjj
GR7GY5zidTdbpsGxnT7b4ZaHHi9XGAuZkchTwRnsfwiVblfn7Ji7LsBP3Giueqf/B/0Oj9U3HR91js64
5xNWtFkDkv+rDmahj5gm0uzsjLu3Nt1qP7REUyt9QSZGeyL0N922hns+7n+1T/f0dLChrYErXarauSaj
1Jn+ZLIrzTHcO92Kq2+NZe06ZFVbltAL5LcSOp+JbfpEXvdjp/uO52J38PrAn29nnHRMcHKFmur/3OZV
Os1CUOgrQZ/Y4I/esHeoUgz39YwTaE+j1C0iP1PkPKtF3vQvS0Ved6qDMviD7uG8mJeIAsP2Fx+3q5M8
HG8L52bcUeHR+OrXY2XuODeGnlYEBXFahnjOVSaj2HhbqJCOIt7FUpFvdvhUR1sa6/+GSvlt/Ivz/3f4
/9b4tDqv+p5lrRbgBqu9uM76weOCpa6F3fpS/L2OcXuY0l9n9L1RrAqK/C1xZvNg4at1FApcL9LkNMPs
5iv+YarZbrczBAL4aQfPtFXQ9kdm2A0F/hFvNhf1E1+sdcAEUzUlRKFmc0yxKPzvlXU0FO0Rs1qth3df
1wUt3j8zYoX3S/AAVyfUxHl+H57rHJS6V6TZHa7xfuKp33QQdrVM5JJ2n2i4O+Ld/otSChzrsdDyYitL
Yw9iw3sEzfPvOCQLXnGUg33WuxoxOZSB6y6WJVwq5ro+4eb9MScEE9EWGYbo3RLSyIiEOShdgzidqiEv
xA2nHGxzs70bu5ts5a+OVSyPdkPQy3w3WA2bXO56kWYHhE2lyi97T2n5DU8ADZ7PUJ1WeccC9znGT9Uq
Wked4KqEQWZRInA77eadfsvxCU1ksV3iZf8DN2RED60MjOBkFepNCcUndrOXiYm8Yxv7k6+GMLLWKHCG
L4VV5S4XqVHgZNvLR+S6/032by22NDWDXTsmtKct5F9epz6HeCHucZFDEnv6bxO/dW1sLh5tStz6fKsK
fQcExe9Mm2NiQnXb/vH9Vs+SckLwFIg8Guoa7m+hFkeTSf7HkXKoO1WLNFui0WuBBy90SzvDmR3KPZSY
ktcT+cIuSbR/GA/+tsEaF6n3ga0y+hrh8bB3H4ShCd1de8dKB7d6lr18EM49GXpOyz5pzuLH/cQR9z9E
pdtFml3kV2rcFPbjS0RuXCfX0cJ4iNMSxXHxmd9lKINatHb7Whnabve1UP9vbV+fMFOkyedwoKp48mqt
bqVqbnZFq3SUm8bOXw/FwuWe8YowM2FO7hXoKWFkpX87RsqmzrDKuY5xrXTppm2NXIc06Y0Z5aOaYy4j
laG+KYo1DRWBzBrd6YZW3+ThvhJSzQ5W5KRg9p3m92arlm9fZ4Q0MTzlJxlBnYP81B6oc7MfBFav2Gmx
z9BDPRcC0tuwr2Uiyx2h0M88ZjTOE1nTSmWbLb6RUAWtsn9oLUj4+UYiXwvtRwab4dI2YSMl/iEKfZ1r
L4vDnRfHVxT4RhAsV8b+gS1nLlAvMsvXEt7Pn4pF1OpW1/cC9Nx+9JJHMMiPHeLPHrOTND9d6sh12gTe
S+T1KozVs4UGW5sFMIqFxZaMADVtYnI2tmvIEdZgmZODv1C9obGTaKMrPQdmeCnj3gN9VaGXnOq3od/x
zvd/MZP5zobPANIVeo4Aqv3ZUuzoejv6lee0pGU4aJ38ZKclqnwVxT2UGWVqvOzWx9csCqRQ2CZqaLLh
XlSNBeqDQYh8n074Dq8ICWGXZQR0jHK+4aY60+PxFtRoi4TS58k2xSV6HD3JkT7lepF0RH6NpVrKOG7k
M+vgKTvLm/HfKXsFb57RRrkjPrMmjumbG1y7Bjs2zvyZxsZmeVI5/m1c7MyZL+W9+JqjHQYKEuOXcqI9
8Jq3Er3N8+tYK1HjiQ2ZAK4v4CNeFGn2gC/bSp79XGulyIfrpA/8asKguzgs2J/ztq1dFlo/iHMGpXw/
XF3v0QzF7F6O9F2RZj/KqEz8ZkwMo2PB8PWERb/F1Lvczc53jEkh2GS418LV73eRseh/Ep8I9rImM3xL
ucEeDOaZ7hdgnhTL35HInxXiaMdK+WVoezah8pkY1FG15jg/w0yUcoVItdM8m+jvb/GqdEhgASPTE1P6
0QzzVq2Z/ulsWyh2QbB0/Gudi0r3YxT5TfzdrnEKPm6RyEondruvfL9KSALz7aKFq7gglvnXCoUtRp96
f3JpRmhHWqk006HeTcj7X43Pb+vp8DtzEtzKJ1r5IqbJ+gO/MMZ5mmTjPt4D6GmtVL1LY2eOUvvI87Df
qDPA91upZ7pGk+viRC1zlPi0/MCMtdgJFiYcRFoSOxaqcmlGXtCBRmO+pQktSUMiAHyKH4YemxL3bdpO
EHqejY2RL5LCXD2UBaQz9DQBMN0f4uj47Q3V6I+u1mxLv+12Gfa33R3+etJXFcdu3WsC87UkYwreCjz5
GO9meOcPNRQzLUmQS11cQ6jQgHjclsX3lTug3e+72uVqHCulsZNi1D2InicAbvd4+GsL22OVn3gMe7vO
l7vlJdTo9jAlo9zu/FhH15L4tSrj6nlBUzeklTvqCAOkCWBRouc0kVY63+H2D+rfaXGPe7cKJW1BmW2d
aWfM2DBl4LqL3kAAVf4U1CYDHCoP8/zcEmzn0sTemw3+HUrIjjcsUcK5VrOWaoJrsSoIdoNaLd5jlIjM
tCpDbRthuP9zpp2dJiWZHXiYcw1CsxlezjBG5/umryvU5JoNUwauu+gNBCBRNfegkN33Rc+rRoGj7NMN
5mlFKCI9PCM/YAsBZIagNQUCGNDKpWOMfPXmibwY2/rz5ONUXzLCWeEZ53osnPtcrHpe6Vqf8JMExzDB
IDy+YZPAZ4/eQQDVrghL9+YhjrjeT5xtObZwnbOzKAKbRksGvwoTE611mrSuEQ4zNKK8Ve+jUWMhXoj3
7XQSmgdc5IG4NvjDgYAm+kJcRiqyxqt+5DMZ1cynuaB3cgC9B+WxB90/Y/NqievUqRJZ7dysdYP7B3eO
ixJte1shUtcmhmdvVSKzEt4DFLpZZKaJKI3DR2pjM06pnwVD0GGh5ZuxIPteIsBtcqwuWpowTvc69I4V
gGrXhwV6j1gLWOtCz5prtnLfztqNuqXWx0cSJqU6jYjaOG8tshJFGStAsWFYYRVqPKYZDWriaxpDfONr
wSBU4aBEqaoFYVRPV+6y8KtXu6unh7dj9BYC4LFQcGVIwqFrqi970muWGpXIsdc5VgRWb1zi+rogr7eW
w6ssR1GGhq7MECwLvbxiFRb7Zyzxj7Y9Ig8GwXBkIIjI2xaEXxjqKy4LGRFmu6qTfOU9jt5DAMvcFjxw
P5awpU9znh+4Ewd0IGi1xsrATQxPpF6o72AKqi1GQQYBDDAQi4PYN9dS1PtrXJR2a+NQFYuug8LTTneF
u0PG3xKldnKUfLycMCL1QvQeAuD+IJdvlhEb0GC2lRjkrFbOm+1jdZiEwYmMIOmKIKk2fESdJVrKRLWg
UgWWhC9+jTXSesAWj6NdlWFanBu0OUgYt7jaNWGTWeCC+Px7HdYf6xXoTfEpMzxmExQrxTB72Mh4m5sQ
OPpD/dA13uyiNmdLObfyRDRvfQcE0Ggp8jMIYJBSLIu3i0iyimBpiAl6JdYMLlNluFovqooFvQZ32DvY
CXosCWx26E0E0OB+JynxivkG+5nTWolnRc7xKb9LqI7b7yUtphUbHbfVq0NeG219ZAnyMjSBQxQRO26k
84+vjOuIjrIFmrwcT/Yib5mo0Dflub3N00S9PQVMb9oCeMlMTHWSnzqgHdk/z1g/cHIXiqE54dq1SuQG
NVo7iKaxHKkMwhiqUFOcvb9COZbHK8DmRmNFIjl02s2jwB4OSYxmWUg5W7vhisCuG3oXAcz3GsY7wJc6
jJ6r8J0ujEQzw3SNigmlXjVS7ZDUSs1xrvE0hkhpjL/boSqwKCaAbZVhUYbf8hthfRiZ6Ocj4RkX9m4W
sLcRQL3XsJcdE7U/2mJTZ3ZaE3heEOFGx300dEgA1Zpb8QaD0RAbkEcqxYKw4BfYTgoLMhb2FjIrT2yo
B4f159VuFZPsAfQuAuAddYZlZPRrD0fHVTfbw8LAoI2IxbvGMKFtNQm1mjJGIc8Q1MfOnmMUimLzzqAQ
WTQ3UVu81PHB7Ly2ZNUYJ8pHg3/1XCL47ND7CGB+m7ZlbQZxlE91ohpeHsy4g+MJb4qtja1Rp1kqwVMU
GIS62G44XkpDXDukxUn0w4QkspWj4yL06R62cF4g0DdCZsRejN5GADPjSh9pNHncI+3E3x7aSR6B6jBh
A2OFUgsvXtmGfUwXiFyrISw0ELXhCy80zloFLxMNRlNGici1ZFanUb7Pu89XFKDRtbHhqNeitxFAnesT
bhsNrjPFQe0s3Zv5aId91Id9tyIO4BK4+oFt1o08RBkEUIG6oLwpNxYr4wyjk0ONv+mJHkbH/Mhy9fbw
w9gK8bY7eqMTWNsB6F142B9jzf117nVyu/q/Ivt3sgmkv7uShKvnMs0Y2Ia1LJEvGeFfrNxa28FAI7E4
8BRFIdhzcYKxS9kpZv3mKnJGrH1odktvZwDpjQRQ5+qgEn7HhYZk5NKsT3xRO3WSpH2uRjKSTSzXhIFt
pIcKBaLEjl6iDPWhZaTBmB9YwoEh1n9mIufw4FBHiCZv29nH4zMz3d77v//eSADMCbE1d5vuATeYbal5
XnCJU4MJFsZ3kmdnoVrkJZTB6YRxA9uUjRgkL8NRpFSptQQwzgDMCudHB0+gqQnXsi3jjAPLvOukBLne
29s1AGn0JlVwC+rMR6Mp+NCXjFdhjYWWiYz30cDIDbRJq9DMtViqRgUJcXKZNcpVGtBKyhgmpTkhZZQp
RmOQ+9O7+YzwJX8k+P29mXDu+li8QU1RmCgds9w/urBZ9BL0RgKIgtSeHuY1iYSOvK0uqHMKO6kKXGWl
4RgmL/YHXmW48lbZ+VNGoDFDqi9Eg2bkmSiViAjYXDFWJ9TAlbEzeLOH7JeQTJ4N3g29Hr1xC+B9zQra
jRGek9DBdVxqYXWQJIbGe366payViqkwEMDaJb1UgZYEE2U2w+rAyuUFx7H5CRlgm9h7abY3Yn0A9f7R
VwrB9U4CeMFCHB723CQWJjKBdOwoWhvIZGh8Tdr1o7hVxbISIyXVPpQp0KLcHWECqoJaqSzEAU6LLYUp
h8SC5r9slCgdNc0jPT2E2aJ3EsBUj2M7Z7YR25YlfPUHdGgVrAty/1qH7zRfkdeKpCoNR23CXbxMvhal
7iZGWqtYHhIW+NfjDWN47Ly21H0+kZAw7u39CqAW9E4CqHWV5Qp8xRdacSn1XoyFq7EdJphvDARQEXP9
TcF+Ny7jjYcYhDUZK0AeihRge+WSpqVhqEvUDf9onPDpIVHCYW2pf/bOGID20DsJgKfcgYF+5nOtFD7P
x5rCCQlNXyai8NWWJ7T/MzVjfMbGMUolqhIrQKk8lCtUbI/g1Jn2JxwXDMNvhyuLHBPIa41bHZRQV70Q
opP6BHorAdT6nQ8wxIWOj5f6yfb2VsyFj88I/shEmgcoTTCKs9RiTEbp2nFKpIXGFqTJY6BSE0Op51mx
EFiE9+PFfVJcCu9Fc+IYARrd1VcYQHovAfCGS9RhmJ/HMQGlLjDcQ2FKKjvxE05b/woTBDBXFUZmVOnY
WJ6ku4dgQB7hwBCW2hgMSykbgylhclOOCfxEk9vsbFwsnczoOwwgvZkAItf7F9jYj4OG/W1VzvRY2OFT
Du7QT3i1ZhQkvvdFFmBQohxkQeDr52TYAqDCJb4kZW1aqWLj0eS1QHzjHRfWpXle8Ukfxk5kj/aeRNDZ
oPcSACtcHL6/nUOljRpXO1R5rBDe0e4d3FutCfmJFSCd2as4IaxVmIDmRCDnWtEybTVo9Egw/VYYhRVB
KZVyQqyleMkwW3kzWCaq3d03NIAt6M0EwIuuDTq5rYJA+LgXnOr+oJ2vdFIHkkBNCDJZuwLUB95h21hc
G2YsanyYuC8zi889vhjIY6BhWBCUQtv4gnzMs8D1DrJAYfilN3pnFoCO0bsJoMk1pqPcdwIfUOt3Jiv2
Rrji0A74gPogiCV9gKaox9axjXC8YViWYdxNygjz/DJWOw1VSVjoB/ueiZjjAZd7x/7+HZJCR+63tKcH
rXvo3QTAe+4HwwJPzmtucoyXw7491Fcy+PoWtJhzkl/0OxZjQiy9T1KG2QndYn7i+shNCX3+ECWYrkaF
7zgaTa50td/bS776YJlc6oG+YAJOorcTQFNsvTss7LLN/maVSTHX/XGfbkcj2OLlk7T/zzLV2mjePNvK
w1uJ2J28hLl4tmsTu/lgRWiwlV86RyH+7W+eVO0oU2wbNqiXEskq+wh6OwFwV3Cs2jUu/brYL20Sf/el
vpmoBNKCVDtEsdoz4EgTMdB20jE+a2WAZJjo3bHKBypDhpD7nBm2iVJ7YlubmBPWlCb39SUNQBq9nwDe
8k2vocQX4937aZclltrNXNjGRbQovFkyKUzkEcsx0S/sbh+TsCTDp2BtlOBSN2dw84VSGGpcbP7dTIRD
zYiVS/M82tOD1V9xulqROmfFLUPcnpGQ8bpWtYaOCyVav5XROsC/tJSVmS8SuTej7OPguLLnba18h87K
SAD5jg88YJAhHvC9OJ3kzf9B8dseQ+9fAeBuL6DImcErj2V+nHDMyHOi32Q4iIwKjtmZVrlVrgyL9HCj
0OSejEW7MKwANW5qlVAqaZV8yE1S/qDKjlaoCTrCBvf17kDwvo3T1Ig0+VXCOniCZXFph0izR+wXmL5B
oURjVZvEMhUZRaPntirgMi58zU+2cTj9Qbij0U129bjLlUj5tlNdG6eC3qynB6k/Y7AHRCIL44RsFPqh
GvMTOXoXutrnfdYtoe2ddtzGjrMmvv6pVl5Fm5sl0uicVvek/DkQ2d8Nc64ptkSBfW0V1x+9Zp3KXOSQ
NY4MxZvuT7h1DXKNJR6O646m+YG1SeNvaCeINFnB+4ZW3gY7WCRZW6wFlaHm5zzbG+Npn43P7BrKwdT5
TE8P0Lqhb/AA8JB/gP3jkoxU+Z5XjPZ7ryXeqOWd6tyTsPO1YIl7YwlicSu9fYUSPJcR+QOTbSXCcvPs
6Ak3g5TtHBCYxQ8TDus5rCdM9nZIBH9IonWSx/3drq6IC8G1HFM6iB/8aFzE7Setzoxyv0ZfSLRUOsGx
blPrMh+YbyvDYg1EysXxdnJlr/Sv7nf4XBjwN3wysbhv5uc2U+o4jyfKO0d+18H6NjAUhox8t825zX0j
Iz31fharFXnQcJepd1TG1aeH0vR161DdIId1QKV/xvx7MkNAfpjqkX4c1+1Y4xMd9JJyYbjm213+4kB/
FlnpKHxWs+9lnN03ZCV9r+8Wg+k7PADpVMzpKJ4hGQ7eTcH0s9DPfCO4cMxM8AWZiLwQeun67VdYgn94
SDpEbIsMD8Xm8LvP94Uw0PbRtwiA54ODRmFw52qNBtf4sTV4u51UEy2YFsI7O0s0k0a+CZ53kTWokFKR
QQBDQyDZI705F2j/Ql5c7Wtqh5XFSv1MtXtNMrZdUzFDvCIS+XmXv5eyZxAK9/OqJhdkGJm+q1lk5jrV
OcxhHTEhTN4Kn+7wCy51ume8611P+rVDDECRcTY32Y72d7a5IpFfZ/2r+5kmckvGxlMeLAt35qqBbVh8
xiqRZlOCFr59jHGs35khssKd9lDpMN93qzdUBd498ocsf3Gs50TuSKSehI9aJNLk7J4ekP81lPmrZpHp
XWrfU7YPIt+9RtnJWa70SkJ1/Mcsa5Ecolbkeb9wpvMcCAr9USQyu7cVhP9fwGZeFmnw/XbSxFTa3DaJ
vX9fSzR5yr9CHfBaa2Jtwe+z/L3x7goCXyRyrQIcGBTQ1/dFI3DfxxEWiSxyQsY3vIULPGam+f4vNs2U
+rtIg8h8f/V5h/u4U0M514uy/r0hDvZNf3S7V71mrM08IxKp6c3VQPozCnxHncgcJ8VK2MNiy1zk4URm
sT18IDLNwQl17dc1qXJKt393sI/5i+95KPzOCxmRRjlsQFS6WrPIUhfaWL5StyTUwL/OqOu9r5/ZJ+Pu
L3jDoe0kjuwKR3nfO1bHlsfzs+QiclgP2DgweE3ecJWbYxNPZKm9kdfJ5PzEYhe24uqzwUTXqI5/58MQ
D5BDD2GXYB9sfbxnYxMc1yYnWAsGelQk8qusa5El730y/p0/5WyAPY3DzGmHANa4w90+3uEKcLxVIh/6
2TqocLb3frzOfKynXz+HlJMTS3/yuKHDr3OXIAP8MQtbQAvyjTHUWMcl/Ilu7XCF6UPo60tY5CYD/bwd
nf9IgxIZPWGorWxtU0fYHJH32/EX6gh5DvMp40yIJ73aja08h3PoIRT5npo2K0CjL6PSab6g0CTf8bTl
sQ9x5INElc9sUOw47yT6f6TDBDV9Cn19BYB6vzXalxOegg8Ya4DFNnKRT7rNJo6zWSuO4M5uxvFtZ9dE
6qc6N8Z1w3LoBRjlnvBlvu0nRtvOOEPcKNLcxlcwfXTPhLN/HP/TIgBu3q37c1jv2ME0kcgS93vUw0Y7
MiGxtz3O6kbfk7zc6u4a5/Y5Z5p+jpQLEjv8Mld6NWPKmkxzlT+F6ILI17Lsd5KjPdwOAc3sMD1NDj2E
0S4xs4Pvfapv20yBiliL/8Mu+0spUuyyRCRR5nFPJxULcugRFNjBXYl1oEUtdEUiNdR3w/nfddJPnlEK
FDnDP0IUcXtHvfNy20DvwwRPZ0zTUl/LqDm0p6UikZs6kYDGuN0u2CfeMNKCZWsSmN5FCcscegSfTDhv
rHZ2q4ke5EmRZo934DAKm5juFHxZXdzPb51tXhsSuDC3BvQ+DAqhnJHIVW20/Sk/Ue9tb3VYcGJTR3jd
z+0Z+xdU+YYSfCMmiJbjiU7IKIcew/fDPt/k2+18oftZ4A5z7NbB3Sd7y0zLgudwZLlzgtVgpBdbEcDL
XVY57eXonwvYK3Hkz9dc2EZl87r3rFDVoTf/eJONNzjECFb5ocuC1WBRSDO1FvMSqeb7JPonAcyKU8qP
9B13tsoluNyDBrnXTu16A4x3TOJ/6elvifuJWpmXIs8kMo3n0GswtpWjSK1LM5JBbesJ+/l+O4Xnxrgu
IUYud3ZG3o88l2b0O7fTItY59BiGheihtcdKRyTOF/iW3Q01RJEv+L0jlCDPzq7ySEKZ9KrRmBRnGB/d
qt+ruuFRkMMGRFsCiDxpfOKK0pAPbGtzRVa41FjF9neMr5iR0Pifju39wfkmKXF2hhRQ5aCeftEc2seY
hIN4WoVTL3J1Oxb8/WIP3+uUKXSa+8xJqHyeMRIf8VsvuLOVHuC2dopa59ArMMnsxEQ1q3W/t9S7uM2U
beMDDSLVLlQsXWFgS1/xZqzu/boUCny+lW1xeaJOcA69DAfEusAm/3S2Z811mQes8t1WydwK7eFu9X7Q
yr9v+9j3b45PGWEfd2akn2n2h07qFubQwzgncPLNbjASm7rbSne437y41AsUGokzvN+Of/9+sRlouddC
XOFa0/I/2ilqmUMvQZG/a/EOmqjEfsYY61p1pnrZ9Ylt4CjPO1ilfdopQ1vg123siunJf9f3EnXJc+h1
2Dzm438npdLtXvV5E1xgiWr/jC14RW4WebrD6L5dLGxjAH7GOSbmwsF6Nz6r2oNWanYG2MsH6txiN4d7
WpN3nWs08hzrAvN8q4MJrYzTyaWP9301FwraF/BLV/qUVRqdHFoO9pbIh75uBz8wS6MXfNXW8nGJ2fZu
t59CNycEyX+2U5Yih16JLQ31WU0anRS37eBWy9V5zKfs7fcWicz2V7vY2tteaTdGYECIIIxUu7hVPYIc
ejl+KlLryETLAHv4iVXWuMXhDnadVSKznO9EU73UzipweEg6udx5uTRQfQuF/i7yUlxeogVFTvGseivd
6mRf8LhGjW73Wfd73zcS4eKFDjFF2r+4dRH7Mls62CG27BdhNf0SQ72ozvHtnhvh024yW5VHfNNFpou8
4Hjf8YbnnGdnkxzp8iABrPa1jGkuc6w7zFKt2gyf6ukXzaF9bGuBpZ2YaotN8gW3muKP9nWtNWY5x+4u
8KSppsdK3yZ/SCz+Ax3ghoS/YeSa3BrQO3GcRne0o9zJRJFN7aJQmVO8rta/nGgf+zvez8Lu/4Et5Rtg
Ywf6nkdCcYjIMvdZIXJPTh3cO7GL73Wzgs9El1mt3iy/VanE/cGl/CY3eMS0jO9+rs8a6gGRB/pDhoD+
ioJu6utKnGCKSKMzlcTxQ22P2Y6SwqUiD/V9g3D/9Amkwjnd1NfXutmJ7pbnS77eTiLqOa73siapUJ2g
tqdfMYeOke+L3k2Eg2WP8Z4SJcpOzXKNX7rCLT6lwFg/stQS31DpitwW0HtxmIUWrmMO33MTNsA37KUA
ebEmoMDxZqhxq6ki9+YURL0RBa7S7PUOSkZ1hVPj778+GJMykXJKHDJyZ9/PE9wfeYBKW7vLWRas090V
MfO4rN1ScCmjvRUCRaoTlcf7KPonAQyz2uutagJmi4ExAVRb2c75ZvV2DyEly3IE0BtRqsix/mzIOt29
1nM4apeECtUqDwQwT5Rlr70W/VGVmZJS6ig3erCDVSAlT0qefIWKlCgzwDAjjDDKofFVZT5uuWJFihQp
DteNsGv4bJrM6OlX/W8MVv/Dph62scj7XrZQtTrN0mSRr0ChYsVKlChWqky5cmXKlSpuEyvYiPx2x6jB
Gm/4nPd6+mX/U/RHAhjkrlbJ4bNDiydxs2ZN4WjUqFGDOrXWWG2VKsssstBc083PbQG9EStcrMYwheHr
jeIJbVCvQX181GUc6baG0J6+tkGDRo2Jv5v6/qQn0R9XAChXoiBUDGj5rpvCv/TRouzJIYcccsghhxxy
yCGHHHLIIYcccsghhxxyyCGHHHLIIYcccsghhxxyyCGHHHLIIYf+gf8P5Bdrsf1iwxYAAAAASUVORK5C
YII=
</value>
</data>
</root>

ثنائية
IPAddressControlLib.dll Normal file

ملف ثنائي غير معروض.

عرض الملف

@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using Pingerino.Services;
using Pingerino.Services.Interfaces;
namespace Pingerino.Infrastructure
{
public class ServiceContainer : IDisposable
{
private readonly Dictionary<Type, object> _services = new Dictionary<Type, object>();
private readonly List<IDisposable> _disposables = new List<IDisposable>();
private bool _disposed;
public static ServiceContainer Instance { get; private set; }
public static void Initialize()
{
Instance?.Dispose();
Instance = new ServiceContainer();
Instance.RegisterServices();
}
private void RegisterServices()
{
// Register logging service first
var loggingService = new LoggingService();
RegisterSingleton<ILoggingService>(loggingService);
// Register other services
RegisterSingleton<IConfigurationService>(new ConfigurationService(loggingService));
RegisterSingleton<IPingService>(new PingService(loggingService));
RegisterSingleton<INetworkService>(new NetworkService(loggingService));
RegisterSingleton<ISystemService>(new SystemService(loggingService));
}
public void RegisterSingleton<T>(T instance) where T : class
{
_services[typeof(T)] = instance;
if (instance is IDisposable disposable)
{
_disposables.Add(disposable);
}
}
public T GetService<T>() where T : class
{
if (_services.TryGetValue(typeof(T), out var service))
{
return service as T;
}
throw new InvalidOperationException($"Service of type {typeof(T).Name} is not registered.");
}
public bool TryGetService<T>(out T service) where T : class
{
service = null;
if (_services.TryGetValue(typeof(T), out var serviceObj))
{
service = serviceObj as T;
return service != null;
}
return false;
}
public void Dispose()
{
if (_disposed) return;
foreach (var disposable in _disposables)
{
try
{
disposable?.Dispose();
}
catch
{
// Ignore disposal errors
}
}
_services.Clear();
_disposables.Clear();
_disposed = true;
}
}
}

12
NetworkStatistics.cs Normal file
عرض الملف

@@ -0,0 +1,12 @@
// This file is now obsolete - NetworkStatistics functionality has been moved to:
// - Services/Interfaces/IPingService.cs (NetworkStatistics class)
// - Services/PingService.cs (implementation)
//
// The new architecture provides:
// - Better separation of concerns
// - Async/await patterns
// - Proper error handling and logging
// - Thread-safe operations
// - Dependency injection support
//
// This file is kept for reference but should not be used in the new architecture.

151
Pingerino.csproj Normal file
عرض الملف

@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{69F90891-89F7-4EDB-8C35-91D372E1F30C}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Pingerino</RootNamespace>
<AssemblyName>Pingerino</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<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' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<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' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject>
</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>xray_drawing_1_origi_fETdd.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="IPAddressControlLib, Version=1.2.4446.28646, Culture=neutral, PublicKeyToken=64ca5a4287aa7107, processorArchitecture=MSIL">
<HintPath>packages\IPAddressControl.1.2.4446.28646\lib\IPAddressControlLib.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Win32.TaskScheduler, Version=2.10.1.0, Culture=neutral, PublicKeyToken=e25603a88b3aa7da, processorArchitecture=MSIL">
<HintPath>packages\TaskScheduler.2.10.1\lib\net452\Microsoft.Win32.TaskScheduler.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Design" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="FormPinger.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FormPinger.Designer.cs">
<DependentUpon>FormPinger.cs</DependentUpon>
</Compile>
<Compile Include="NetworkStatistics.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Settings.cs" />
<Compile Include="Infrastructure\ServiceContainer.cs" />
<Compile Include="Services\ConfigurationService.cs" />
<Compile Include="Services\LoggingService.cs" />
<Compile Include="Services\NetworkService.cs" />
<Compile Include="Services\PingService.cs" />
<Compile Include="Services\SystemService.cs" />
<Compile Include="Services\Interfaces\IConfigurationService.cs" />
<Compile Include="Services\Interfaces\ILoggingService.cs" />
<Compile Include="Services\Interfaces\INetworkService.cs" />
<Compile Include="Services\Interfaces\IPingService.cs" />
<Compile Include="Services\Interfaces\ISystemService.cs" />
<Compile Include="Utilities\UIHelper.cs" />
<Compile Include="Utilities\ValidationHelper.cs" />
<EmbeddedResource Include="FormPinger.resx">
<DependentUpon>FormPinger.cs</DependentUpon>
</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.manifest" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Untitled.png" />
<None Include="Resources\Untitlemd.png" />
<Content Include="xray_drawing_1_origi_fETdd.ico" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.7.2 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

25
Pingerino.sln Normal file
عرض الملف

@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.6.33829.357
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pingerino", "Pingerino.csproj", "{69F90891-89F7-4EDB-8C35-91D372E1F30C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{69F90891-89F7-4EDB-8C35-91D372E1F30C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{69F90891-89F7-4EDB-8C35-91D372E1F30C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{69F90891-89F7-4EDB-8C35-91D372E1F30C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{69F90891-89F7-4EDB-8C35-91D372E1F30C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A1640B14-6E09-47C1-AC9C-CBC9D973B6A1}
EndGlobalSection
EndGlobal

32
Program.cs Normal file
عرض الملف

@@ -0,0 +1,32 @@
using System;
using System.Windows.Forms;
using Pingerino.Infrastructure;
namespace Pingerino
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Initialize dependency injection container
ServiceContainer.Initialize();
try
{
Application.Run(new FormPinger());
}
finally
{
// Clean up services on application exit
ServiceContainer.Instance?.Dispose();
}
}
}
}

عرض الملف

@@ -0,0 +1,35 @@
using System.Reflection;
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("Pingerino")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Pingerino")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[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("69f90891-89f7-4edb-8c35-91d372e1f30c")]
// 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")]

ثنائية
Properties/IPAddressControlLib.dll Normal file

ملف ثنائي غير معروض.

83
Properties/Resources.Designer.cs مولّد Normal file
عرض الملف

@@ -0,0 +1,83 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Pingerino.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", "17.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("Pingerino.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;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Untitled {
get {
object obj = ResourceManager.GetObject("Untitled", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Untitlemd {
get {
object obj = ResourceManager.GetObject("Untitlemd", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

127
Properties/Resources.resx Normal file
عرض الملف

@@ -0,0 +1,127 @@
<?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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Untitled" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Untitled.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Untitlemd" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Untitlemd.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

86
Properties/Settings.Designer.cs مولّد Normal file
عرض الملف

@@ -0,0 +1,86 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Pingerino.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.9.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0, 0")]
public global::System.Drawing.Point FormPosition {
get {
return ((global::System.Drawing.Point)(this["FormPosition"]));
}
set {
this["FormPosition"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("1000")]
public string TextBoxIntervalValue {
get {
return ((string)(this["TextBoxIntervalValue"]));
}
set {
this["TextBoxIntervalValue"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("8.8.8.8")]
public string IpAddressValue {
get {
return ((string)(this["IpAddressValue"]));
}
set {
this["IpAddressValue"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool AutoPingEnabled {
get {
return ((bool)(this["AutoPingEnabled"]));
}
set {
this["AutoPingEnabled"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("8.8.8.8")]
public string LastUsedIpAddress {
get {
return ((string)(this["LastUsedIpAddress"]));
}
set {
this["LastUsedIpAddress"] = value;
}
}
}
}

عرض الملف

@@ -0,0 +1,21 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Pingerino.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="FormPosition" Type="System.Drawing.Point" Scope="User">
<Value Profile="(Default)">0, 0</Value>
</Setting>
<Setting Name="TextBoxIntervalValue" Type="System.String" Scope="User">
<Value Profile="(Default)">1000</Value>
</Setting>
<Setting Name="IpAddressValue" Type="System.String" Scope="User">
<Value Profile="(Default)">8.8.8.8</Value>
</Setting>
<Setting Name="AutoPingEnabled" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="LastUsedIpAddress" Type="System.String" Scope="User">
<Value Profile="(Default)">8.8.8.8</Value>
</Setting>
</Settings>
</SettingsFile>

ثنائية
Resources/Untitled.png Normal file

ملف ثنائي غير معروض.

بعد

العرض:  |  الارتفاع:  |  الحجم: 18 KiB

ثنائية
Resources/Untitlemd.png Normal file

ملف ثنائي غير معروض.

بعد

العرض:  |  الارتفاع:  |  الحجم: 9.8 KiB

عرض الملف

@@ -0,0 +1,117 @@
using System;
using System.Drawing;
using Pingerino.Services.Interfaces;
namespace Pingerino.Services
{
public class ConfigurationService : IConfigurationService
{
private readonly ILoggingService _logger;
public ConfigurationService(ILoggingService logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
Load();
}
public T GetValue<T>(string key, T defaultValue = default)
{
try
{
var property = Properties.Settings.Default.GetType().GetProperty(key);
if (property != null)
{
var value = property.GetValue(Properties.Settings.Default);
if (value != null && value is T)
{
return (T)value;
}
}
return defaultValue;
}
catch (Exception ex)
{
_logger.LogError($"Error getting configuration value for key: {key}", ex);
return defaultValue;
}
}
public void SetValue<T>(string key, T value)
{
try
{
var property = Properties.Settings.Default.GetType().GetProperty(key);
if (property != null && property.CanWrite)
{
property.SetValue(Properties.Settings.Default, value);
}
}
catch (Exception ex)
{
_logger.LogError($"Error setting configuration value for key: {key}", ex);
}
}
public void Save()
{
try
{
Properties.Settings.Default.Save();
_logger.LogInformation("Configuration saved successfully");
}
catch (Exception ex)
{
_logger.LogError("Error saving configuration", ex);
}
}
public void Load()
{
try
{
Properties.Settings.Default.Reload();
_logger.LogInformation("Configuration loaded successfully");
}
catch (Exception ex)
{
_logger.LogError("Error loading configuration", ex);
}
}
public string LastUsedIpAddress
{
get => GetValue(nameof(Properties.Settings.Default.LastUsedIpAddress), "8.8.8.8");
set => SetValue(nameof(Properties.Settings.Default.LastUsedIpAddress), value);
}
public int PingInterval
{
get => GetValue("PingInterval", 300);
set => SetValue("PingInterval", value);
}
public bool AutoPingEnabled
{
get => GetValue(nameof(Properties.Settings.Default.AutoPingEnabled), false);
set => SetValue(nameof(Properties.Settings.Default.AutoPingEnabled), value);
}
public Point FormPosition
{
get => GetValue(nameof(Properties.Settings.Default.FormPosition), Point.Empty);
set => SetValue(nameof(Properties.Settings.Default.FormPosition), value);
}
public string IpAddressValue
{
get => GetValue(nameof(Properties.Settings.Default.IpAddressValue), "8.8.8.8");
set => SetValue(nameof(Properties.Settings.Default.IpAddressValue), value);
}
public string TextBoxIntervalValue
{
get => GetValue(nameof(Properties.Settings.Default.TextBoxIntervalValue), "300");
set => SetValue(nameof(Properties.Settings.Default.TextBoxIntervalValue), value);
}
}
}

عرض الملف

@@ -0,0 +1,21 @@
using System;
using System.Drawing;
namespace Pingerino.Services.Interfaces
{
public interface IConfigurationService
{
T GetValue<T>(string key, T defaultValue = default);
void SetValue<T>(string key, T value);
void Save();
void Load();
// Specific application settings
string LastUsedIpAddress { get; set; }
int PingInterval { get; set; }
bool AutoPingEnabled { get; set; }
Point FormPosition { get; set; }
string IpAddressValue { get; set; }
string TextBoxIntervalValue { get; set; }
}
}

عرض الملف

@@ -0,0 +1,20 @@
using System;
namespace Pingerino.Services.Interfaces
{
public interface ILoggingService
{
void LogInformation(string message);
void LogWarning(string message);
void LogError(string message, Exception exception = null);
void LogDebug(string message);
}
public enum LogLevel
{
Debug,
Information,
Warning,
Error
}
}

عرض الملف

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Pingerino.Services.Interfaces
{
public interface INetworkService : IDisposable
{
System.Threading.Tasks.Task<string> GetPublicIpAddressAsync(CancellationToken cancellationToken = default);
System.Threading.Tasks.Task<List<NetworkAdapterInfo>> GetNetworkAdaptersAsync();
System.Threading.Tasks.Task<bool> ResetNetworkAdapterAsync(string adapterName, IProgress<int> progress = null, CancellationToken cancellationToken = default);
System.Threading.Tasks.Task<NetworkAdapterInfo> GetActiveEthernetAdapterAsync();
System.Threading.Tasks.Task<bool> IsNetworkAvailableAsync();
}
public class NetworkAdapterInfo
{
public string Name { get; set; }
public string Description { get; set; }
public string PhysicalAddress { get; set; }
public bool IsDhcpEnabled { get; set; }
public string IpAddress { get; set; }
public string SubnetMask { get; set; }
public string DefaultGateway { get; set; }
public string DhcpServer { get; set; }
public List<string> DnsServers { get; set; } = new List<string>();
public bool IsActive { get; set; }
public string InterfaceType { get; set; }
}
}

عرض الملف

@@ -0,0 +1,67 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Pingerino.Services.Interfaces
{
public interface IPingService : IDisposable
{
event EventHandler<PingResultEventArgs> PingCompleted;
event EventHandler<NetworkStatisticsEventArgs> StatisticsUpdated;
System.Threading.Tasks.Task StartPingingAsync(string ipAddress, int intervalMs, CancellationToken cancellationToken = default);
System.Threading.Tasks.Task StopPingingAsync();
System.Threading.Tasks.Task<PingResult> PingOnceAsync(string ipAddress, CancellationToken cancellationToken = default);
void ClearStatistics();
NetworkStatistics GetCurrentStatistics();
bool IsRunning { get; }
}
public class PingResultEventArgs : EventArgs
{
public PingResult Result { get; }
public DateTime Timestamp { get; }
public PingResultEventArgs(PingResult result, DateTime timestamp)
{
Result = result;
Timestamp = timestamp;
}
}
public class NetworkStatisticsEventArgs : EventArgs
{
public NetworkStatistics Statistics { get; }
public NetworkStatisticsEventArgs(NetworkStatistics statistics)
{
Statistics = statistics;
}
}
public class PingResult
{
public string IpAddress { get; set; }
public bool IsSuccess { get; set; }
public long RoundTripTime { get; set; }
public string Status { get; set; }
public string ErrorMessage { get; set; }
}
public class NetworkStatistics
{
public double Jitter { get; set; }
public double PacketLoss { get; set; }
public long MaxPing { get; set; }
public long MinPing { get; set; }
public double AveragePing { get; set; }
public double MaxJitter { get; set; }
public double MinJitter { get; set; }
public double AverageJitter { get; set; }
public double MaxPacketLoss { get; set; }
public double MinPacketLoss { get; set; }
public double AveragePacketLoss { get; set; }
public int TotalPings { get; set; }
public int SuccessfulPings { get; set; }
}
}

عرض الملف

@@ -0,0 +1,16 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Pingerino.Services.Interfaces
{
public interface ISystemService : IDisposable
{
System.Threading.Tasks.Task<bool> CleanTemporaryFilesAsync(IProgress<int> progress = null, CancellationToken cancellationToken = default);
System.Threading.Tasks.Task<bool> CreateStartupTaskAsync(string taskName, string executablePath);
System.Threading.Tasks.Task<bool> RemoveStartupTaskAsync(string taskName);
System.Threading.Tasks.Task<bool> IsStartupTaskExistsAsync(string taskName);
void OpenNetworkAdaptersControl();
System.Threading.Tasks.Task<bool> RunExternalScriptAsync(string scriptPath);
}
}

عرض الملف

@@ -0,0 +1,59 @@
using System;
using System.IO;
using Pingerino.Services.Interfaces;
namespace Pingerino.Services
{
public class LoggingService : ILoggingService
{
private readonly string _logFilePath;
private readonly object _lockObject = new object();
public LoggingService()
{
var logDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Pingerino", "Logs");
Directory.CreateDirectory(logDirectory);
_logFilePath = Path.Combine(logDirectory, $"pingerino_{DateTime.Now:yyyyMMdd}.log");
}
public void LogInformation(string message)
{
WriteLog(LogLevel.Information, message);
}
public void LogWarning(string message)
{
WriteLog(LogLevel.Warning, message);
}
public void LogError(string message, Exception exception = null)
{
var fullMessage = exception != null ? $"{message} - Exception: {exception}" : message;
WriteLog(LogLevel.Error, fullMessage);
}
public void LogDebug(string message)
{
WriteLog(LogLevel.Debug, message);
}
private void WriteLog(LogLevel level, string message)
{
try
{
lock (_lockObject)
{
var logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{level}] {message}";
File.AppendAllText(_logFilePath, logEntry + Environment.NewLine);
// Also write to console for debugging
Console.WriteLine(logEntry);
}
}
catch
{
// Ignore logging errors to prevent infinite loops
}
}
}
}

195
Services/NetworkService.cs Normal file
عرض الملف

@@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;
using Pingerino.Services.Interfaces;
namespace Pingerino.Services
{
public class NetworkService : INetworkService
{
private readonly HttpClient _httpClient;
private readonly ILoggingService _logger;
private bool _disposed;
public NetworkService(ILoggingService logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(10)
};
}
public async System.Threading.Tasks.Task<string> GetPublicIpAddressAsync(CancellationToken cancellationToken = default)
{
try
{
var response = await _httpClient.GetStringAsync("http://ipinfo.io/ip");
var publicIp = response.Trim();
_logger.LogInformation($"Retrieved public IP: {publicIp}");
return publicIp;
}
catch (Exception ex)
{
_logger.LogError("Failed to retrieve public IP address", ex);
throw;
}
}
public async System.Threading.Tasks.Task<List<NetworkAdapterInfo>> GetNetworkAdaptersAsync()
{
return await System.Threading.Tasks.Task.Run(() =>
{
var adapters = new List<NetworkAdapterInfo>();
try
{
foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
{
if (nic.NetworkInterfaceType == NetworkInterfaceType.Loopback)
continue;
var properties = nic.GetIPProperties();
var adapter = new NetworkAdapterInfo
{
Name = nic.Name,
Description = nic.Description,
PhysicalAddress = nic.GetPhysicalAddress().ToString(),
IsActive = nic.OperationalStatus == OperationalStatus.Up,
InterfaceType = nic.NetworkInterfaceType.ToString()
};
// Get IPv4 properties if available
try
{
var ipv4Properties = properties.GetIPv4Properties();
adapter.IsDhcpEnabled = ipv4Properties.IsDhcpEnabled;
}
catch
{
adapter.IsDhcpEnabled = false;
}
// Get IP addresses
var ipv4Address = properties.UnicastAddresses
.FirstOrDefault(ip => ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
if (ipv4Address != null)
{
adapter.IpAddress = ipv4Address.Address.ToString();
adapter.SubnetMask = ipv4Address.IPv4Mask?.ToString();
}
// Get gateway
var gateway = properties.GatewayAddresses.FirstOrDefault();
if (gateway != null)
{
adapter.DefaultGateway = gateway.Address.ToString();
}
// Get DHCP server
var dhcpServer = properties.DhcpServerAddresses.FirstOrDefault();
if (dhcpServer != null)
{
adapter.DhcpServer = dhcpServer.ToString();
}
// Get DNS servers
adapter.DnsServers = properties.DnsAddresses.Select(dns => dns.ToString()).ToList();
adapters.Add(adapter);
}
_logger.LogInformation($"Retrieved {adapters.Count} network adapters");
}
catch (Exception ex)
{
_logger.LogError("Error retrieving network adapters", ex);
}
return adapters;
});
}
public async System.Threading.Tasks.Task<bool> ResetNetworkAdapterAsync(string adapterName, IProgress<int> progress = null, CancellationToken cancellationToken = default)
{
try
{
progress?.Report(10);
_logger.LogInformation($"Starting network reset for adapter: {adapterName}");
var processInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c ipconfig /release \"{adapterName}\" && ipconfig /renew \"{adapterName}\"",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
Verb = "runas"
};
progress?.Report(30);
using (var process = Process.Start(processInfo))
{
if (process == null)
{
_logger.LogError("Failed to start network reset process");
return false;
}
progress?.Report(60);
process.WaitForExit();
progress?.Report(90);
var success = process.ExitCode == 0;
if (success)
{
_logger.LogInformation($"Network reset completed successfully for {adapterName}");
}
else
{
_logger.LogError($"Network reset failed with exit code: {process.ExitCode}");
}
progress?.Report(100);
return success;
}
}
catch (Exception ex)
{
_logger.LogError("Error during network reset", ex);
return false;
}
}
public async System.Threading.Tasks.Task<NetworkAdapterInfo> GetActiveEthernetAdapterAsync()
{
var adapters = await GetNetworkAdaptersAsync();
return adapters.FirstOrDefault(a =>
a.InterfaceType == NetworkInterfaceType.Ethernet.ToString() &&
a.IsActive);
}
public async System.Threading.Tasks.Task<bool> IsNetworkAvailableAsync()
{
return await System.Threading.Tasks.Task.Run(() => NetworkInterface.GetIsNetworkAvailable());
}
public void Dispose()
{
if (_disposed) return;
_httpClient?.Dispose();
_disposed = true;
}
}
}

255
Services/PingService.cs Normal file
عرض الملف

@@ -0,0 +1,255 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;
using Pingerino.Services.Interfaces;
namespace Pingerino.Services
{
public class PingService : IPingService
{
private readonly ILoggingService _logger;
private readonly List<long> _pingRoundTripTimes = new List<long>();
private readonly List<double> _jitterValues = new List<double>();
private readonly List<double> _packetLossValues = new List<double>();
private readonly object _lockObject = new object();
private Timer _pingTimer;
private string _currentIpAddress;
private bool _disposed;
private CancellationTokenSource _cancellationTokenSource;
public event EventHandler<PingResultEventArgs> PingCompleted;
public event EventHandler<NetworkStatisticsEventArgs> StatisticsUpdated;
public bool IsRunning { get; private set; }
public PingService(ILoggingService logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async System.Threading.Tasks.Task StartPingingAsync(string ipAddress, int intervalMs, CancellationToken cancellationToken = default)
{
if (IsRunning)
{
await StopPingingAsync();
}
_currentIpAddress = ipAddress;
_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
_pingTimer = new Timer(async _ => await PingCallback(), null, 0, intervalMs);
IsRunning = true;
_logger.LogInformation($"Started pinging {ipAddress} with interval {intervalMs}ms");
}
public async System.Threading.Tasks.Task StopPingingAsync()
{
if (!IsRunning) return;
_pingTimer?.Dispose();
_cancellationTokenSource?.Cancel();
IsRunning = false;
_logger.LogInformation("Stopped pinging");
await System.Threading.Tasks.Task.CompletedTask;
}
public async System.Threading.Tasks.Task<PingResult> PingOnceAsync(string ipAddress, CancellationToken cancellationToken = default)
{
try
{
if (!NetworkInterface.GetIsNetworkAvailable())
{
return new PingResult
{
IpAddress = ipAddress,
IsSuccess = false,
Status = "No network connection available",
ErrorMessage = "Network unavailable"
};
}
using (var ping = new Ping())
{
var reply = await ping.SendPingAsync(ipAddress);
var result = new PingResult
{
IpAddress = ipAddress,
IsSuccess = reply.Status == IPStatus.Success,
RoundTripTime = reply.RoundtripTime,
Status = reply.Status.ToString()
};
if (result.IsSuccess)
{
UpdateStatistics(reply.RoundtripTime);
}
return result;
}
}
catch (Exception ex)
{
_logger.LogError($"Error pinging {ipAddress}", ex);
return new PingResult
{
IpAddress = ipAddress,
IsSuccess = false,
Status = "Error",
ErrorMessage = ex.Message
};
}
}
public void ClearStatistics()
{
lock (_lockObject)
{
_pingRoundTripTimes.Clear();
_jitterValues.Clear();
_packetLossValues.Clear();
}
_logger.LogInformation("Statistics cleared");
}
public NetworkStatistics GetCurrentStatistics()
{
lock (_lockObject)
{
var stats = new NetworkStatistics();
if (_pingRoundTripTimes.Count > 0)
{
stats.MaxPing = _pingRoundTripTimes.Max();
stats.MinPing = _pingRoundTripTimes.Min();
stats.AveragePing = _pingRoundTripTimes.Average();
stats.TotalPings = _pingRoundTripTimes.Count;
stats.SuccessfulPings = _pingRoundTripTimes.Count;
}
if (_jitterValues.Count > 0)
{
stats.MaxJitter = _jitterValues.Max();
stats.MinJitter = _jitterValues.Min();
stats.AverageJitter = _jitterValues.Average();
stats.Jitter = stats.AverageJitter;
}
if (_packetLossValues.Count > 0)
{
stats.MaxPacketLoss = _packetLossValues.Max();
stats.MinPacketLoss = _packetLossValues.Min();
stats.AveragePacketLoss = _packetLossValues.Average();
stats.PacketLoss = stats.AveragePacketLoss;
}
return stats;
}
}
private async System.Threading.Tasks.Task PingCallback()
{
if (_cancellationTokenSource?.Token.IsCancellationRequested == true)
return;
try
{
var result = await PingOnceAsync(_currentIpAddress, _cancellationTokenSource?.Token ?? CancellationToken.None);
PingCompleted?.Invoke(this, new PingResultEventArgs(result, DateTime.Now));
// Calculate and update network statistics periodically
await CalculateNetworkStatisticsAsync();
}
catch (Exception ex)
{
_logger.LogError("Error in ping callback", ex);
}
}
private void UpdateStatistics(long roundTripTime)
{
lock (_lockObject)
{
_pingRoundTripTimes.Add(roundTripTime);
// Calculate jitter if we have previous measurements
if (_pingRoundTripTimes.Count > 1)
{
var previousTime = _pingRoundTripTimes[_pingRoundTripTimes.Count - 2];
var jitter = Math.Abs(roundTripTime - previousTime);
_jitterValues.Add(jitter);
}
}
}
private async System.Threading.Tasks.Task CalculateNetworkStatisticsAsync()
{
try
{
// Calculate packet loss over the last 10 pings
var packetLoss = await CalculatePacketLossAsync(_currentIpAddress, 10);
lock (_lockObject)
{
_packetLossValues.Add(packetLoss);
}
var stats = GetCurrentStatistics();
StatisticsUpdated?.Invoke(this, new NetworkStatisticsEventArgs(stats));
}
catch (Exception ex)
{
_logger.LogError("Error calculating network statistics", ex);
}
}
private async System.Threading.Tasks.Task<double> CalculatePacketLossAsync(string ipAddress, int count)
{
int failedPings = 0;
var tasks = new List<System.Threading.Tasks.Task<bool>>();
for (int i = 0; i < count; i++)
{
tasks.Add(TestSinglePingAsync(ipAddress));
}
var results = await System.Threading.Tasks.Task.WhenAll(tasks);
failedPings = results.Count(r => !r);
return (double)failedPings / count * 100;
}
private async System.Threading.Tasks.Task<bool> TestSinglePingAsync(string ipAddress)
{
try
{
using (var ping = new Ping())
{
var reply = await ping.SendPingAsync(ipAddress);
return reply.Status == IPStatus.Success;
}
}
catch
{
return false;
}
}
public void Dispose()
{
if (_disposed) return;
_pingTimer?.Dispose();
_cancellationTokenSource?.Cancel();
_cancellationTokenSource?.Dispose();
_disposed = true;
}
}
}

238
Services/SystemService.cs Normal file
عرض الملف

@@ -0,0 +1,238 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Win32.TaskScheduler;
using Pingerino.Services.Interfaces;
namespace Pingerino.Services
{
public class SystemService : ISystemService
{
private readonly ILoggingService _logger;
private bool _disposed;
public SystemService(ILoggingService logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async System.Threading.Tasks.Task<bool> CleanTemporaryFilesAsync(IProgress<int> progress = null, CancellationToken cancellationToken = default)
{
try
{
_logger.LogInformation("Starting temporary files cleanup");
var folders = new[]
{
Environment.ExpandEnvironmentVariables(@"%systemroot%\temp"),
Environment.ExpandEnvironmentVariables(@"%systemroot%\Prefetch"),
Environment.ExpandEnvironmentVariables(@"%userprofile%\LocalS~1\Temp"),
Environment.ExpandEnvironmentVariables(@"%userprofile%\AppData\Local\Temp")
};
int totalSteps = folders.Length * 2;
int currentStep = 0;
foreach (var folder in folders)
{
if (cancellationToken.IsCancellationRequested)
return false;
await CleanFolderAsync(folder, progress, currentStep, totalSteps);
currentStep += 2;
}
progress?.Report(100);
_logger.LogInformation("Temporary files cleanup completed");
return true;
}
catch (Exception ex)
{
_logger.LogError("Error during temporary files cleanup", ex);
return false;
}
}
private async System.Threading.Tasks.Task CleanFolderAsync(string folderPath, IProgress<int> progress, int currentStep, int totalSteps)
{
try
{
if (!Directory.Exists(folderPath))
return;
var dirInfo = new DirectoryInfo(folderPath);
// Delete files
await System.Threading.Tasks.Task.Run(() =>
{
foreach (var file in dirInfo.GetFiles())
{
try
{
file.Delete();
}
catch
{
// Ignore individual file deletion errors
}
}
});
progress?.Report((currentStep + 1) * 100 / totalSteps);
// Delete directories
await System.Threading.Tasks.Task.Run(() =>
{
foreach (var dir in dirInfo.GetDirectories())
{
try
{
dir.Delete(true);
}
catch
{
// Ignore individual directory deletion errors
}
}
});
progress?.Report((currentStep + 2) * 100 / totalSteps);
}
catch (Exception ex)
{
_logger.LogWarning($"Error cleaning folder {folderPath}: {ex.Message}");
}
}
public async System.Threading.Tasks.Task<bool> CreateStartupTaskAsync(string taskName, string executablePath)
{
try
{
using (var ts = new TaskService())
{
var td = ts.NewTask();
td.RegistrationInfo.Description = taskName;
td.Principal.RunLevel = TaskRunLevel.Highest;
td.Principal.LogonType = TaskLogonType.InteractiveToken;
td.Triggers.Add(new LogonTrigger());
var execAction = new ExecAction(executablePath)
{
WorkingDirectory = Path.GetDirectoryName(executablePath)
};
td.Actions.Add(execAction);
var currentUserName = WindowsIdentity.GetCurrent().Name;
ts.RootFolder.RegisterTaskDefinition(taskName, td, TaskCreation.CreateOrUpdate,
currentUserName, null, TaskLogonType.InteractiveToken);
_logger.LogInformation($"Startup task '{taskName}' created successfully");
return await System.Threading.Tasks.Task.FromResult(true);
}
}
catch (Exception ex)
{
_logger.LogError($"Error creating startup task '{taskName}'", ex);
return await System.Threading.Tasks.Task.FromResult(false);
}
}
public async System.Threading.Tasks.Task<bool> RemoveStartupTaskAsync(string taskName)
{
try
{
using (var ts = new TaskService())
{
ts.RootFolder.DeleteTask(taskName, false);
_logger.LogInformation($"Startup task '{taskName}' removed successfully");
return await System.Threading.Tasks.Task.FromResult(true);
}
}
catch (Exception ex)
{
_logger.LogError($"Error removing startup task '{taskName}'", ex);
return await System.Threading.Tasks.Task.FromResult(false);
}
}
public async System.Threading.Tasks.Task<bool> IsStartupTaskExistsAsync(string taskName)
{
try
{
using (var ts = new TaskService())
{
var existingTask = ts.GetTask(taskName);
return await System.Threading.Tasks.Task.FromResult(existingTask != null);
}
}
catch (Exception ex)
{
_logger.LogError($"Error checking startup task '{taskName}'", ex);
return await System.Threading.Tasks.Task.FromResult(false);
}
}
public void OpenNetworkAdaptersControl()
{
try
{
Process.Start("control", "ncpa.cpl");
_logger.LogInformation("Opened network adapters control panel");
}
catch (Exception ex)
{
_logger.LogError("Error opening network adapters control panel", ex);
}
}
public async System.Threading.Tasks.Task<bool> RunExternalScriptAsync(string scriptPath)
{
try
{
if (!File.Exists(scriptPath))
{
_logger.LogWarning($"Script not found: {scriptPath}");
return false;
}
var processInfo = new ProcessStartInfo
{
FileName = scriptPath,
UseShellExecute = true
};
using (var process = Process.Start(processInfo))
{
if (process == null)
{
_logger.LogError("Failed to start external script");
return false;
}
process.WaitForExit();
var success = process.ExitCode == 0;
_logger.LogInformation($"External script execution completed with exit code: {process.ExitCode}");
return success;
}
}
catch (Exception ex)
{
_logger.LogError($"Error running external script: {scriptPath}", ex);
return false;
}
}
public void Dispose()
{
if (_disposed) return;
_disposed = true;
}
}
}

33
Settings.cs Normal file
عرض الملف

@@ -0,0 +1,33 @@
namespace Pingerino.Properties
{
// This class allows you to handle specific events on the settings class:
// The SettingChanging event is raised before a setting's value is changed.
// The PropertyChanged event is raised after a setting's value is changed.
// The SettingsLoaded event is raised after the setting values are loaded.
// The SettingsSaving event is raised before the setting values are saved.
internal sealed partial class Settings
{
public Settings()
{
// // To add event handlers for saving and changing settings, uncomment the lines below:
//
// this.SettingChanging += this.SettingChangingEventHandler;
//
// this.SettingsSaving += this.SettingsSavingEventHandler;
//
}
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e)
{
// Add code to handle the SettingChangingEvent event here.
}
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e)
{
// Add code to handle the SettingsSaving event here.
}
}
}

163
Utilities/UIHelper.cs Normal file
عرض الملف

@@ -0,0 +1,163 @@
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Pingerino.Utilities
{
public static class UIHelper
{
// Windows API constants and imports for form dragging
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
public static extern IntPtr CreateRoundRectRgn(
int nLeftRect, int nTopRect, int nRightRect, int nBottomRect,
int nWidthEllipse, int nHeightEllipse);
/// <summary>
/// Enables form dragging by mouse
/// </summary>
public static void EnableFormDragging(Form form, Control dragControl)
{
dragControl.MouseDown += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(form.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
};
}
/// <summary>
/// Applies rounded corners to a form
/// </summary>
public static void ApplyRoundedCorners(Form form, int radius = 30)
{
form.Region = Region.FromHrgn(CreateRoundRectRgn(0, 0, form.Width, form.Height, radius, radius));
}
/// <summary>
/// Safely updates UI control from any thread
/// </summary>
public static void SafeInvoke(Control control, Action action)
{
if (control == null || control.IsDisposed)
return;
if (control.InvokeRequired)
{
try
{
control.Invoke(action);
}
catch (ObjectDisposedException)
{
// Control was disposed while trying to invoke
}
catch (InvalidOperationException)
{
// Control handle was not created or is being destroyed
}
}
else
{
action();
}
}
/// <summary>
/// Safely updates UI control from any thread with return value
/// </summary>
public static T SafeInvoke<T>(Control control, Func<T> func)
{
if (control == null || control.IsDisposed)
return default(T);
if (control.InvokeRequired)
{
try
{
return (T)control.Invoke(func);
}
catch (ObjectDisposedException)
{
return default(T);
}
catch (InvalidOperationException)
{
return default(T);
}
}
else
{
return func();
}
}
/// <summary>
/// Shows an error message with consistent styling
/// </summary>
public static void ShowError(string message, string title = "Error")
{
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
/// <summary>
/// Shows an information message with consistent styling
/// </summary>
public static void ShowInformation(string message, string title = "Information")
{
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// Shows a confirmation dialog
/// </summary>
public static bool ShowConfirmation(string message, string title = "Confirm")
{
return MessageBox.Show(message, title, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes;
}
/// <summary>
/// Formats time span for display
/// </summary>
public static string FormatTimeSpan(TimeSpan timeSpan)
{
if (timeSpan.TotalDays >= 1)
return $"{timeSpan.Days}d {timeSpan.Hours}h {timeSpan.Minutes}m";
if (timeSpan.TotalHours >= 1)
return $"{timeSpan.Hours}h {timeSpan.Minutes}m {timeSpan.Seconds}s";
if (timeSpan.TotalMinutes >= 1)
return $"{timeSpan.Minutes}m {timeSpan.Seconds}s";
return $"{timeSpan.Seconds}.{timeSpan.Milliseconds:000}s";
}
/// <summary>
/// Formats bytes for display
/// </summary>
public static string FormatBytes(long bytes)
{
string[] suffixes = { "B", "KB", "MB", "GB", "TB" };
int counter = 0;
decimal number = bytes;
while (Math.Round(number / 1024) >= 1)
{
number /= 1024;
counter++;
}
return $"{number:n1} {suffixes[counter]}";
}
}
}

عرض الملف

@@ -0,0 +1,90 @@
using System;
using System.Net;
using System.Text.RegularExpressions;
namespace Pingerino.Utilities
{
public static class ValidationHelper
{
private static readonly Regex IpAddressRegex = new Regex(
@"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$",
RegexOptions.Compiled);
private static readonly Regex HostnameRegex = new Regex(
@"^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)*[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$",
RegexOptions.Compiled);
public static bool IsValidIpAddress(string ipAddress)
{
if (string.IsNullOrWhiteSpace(ipAddress))
return false;
return IPAddress.TryParse(ipAddress, out _) || IpAddressRegex.IsMatch(ipAddress);
}
public static bool IsValidHostname(string hostname)
{
if (string.IsNullOrWhiteSpace(hostname))
return false;
if (hostname.Length > 253)
return false;
return HostnameRegex.IsMatch(hostname);
}
public static bool IsValidIpAddressOrHostname(string address)
{
return IsValidIpAddress(address) || IsValidHostname(address);
}
public static bool IsValidPingInterval(string intervalText, out int interval)
{
interval = 0;
if (string.IsNullOrWhiteSpace(intervalText))
return false;
if (!int.TryParse(intervalText, out interval))
return false;
return interval >= 100 && interval <= 60000; // 100ms to 60 seconds
}
public static bool IsValidPingInterval(int interval)
{
return interval >= 100 && interval <= 60000;
}
public static string SanitizeInput(string input)
{
if (string.IsNullOrEmpty(input))
return string.Empty;
return input.Trim();
}
public static string GetValidationErrorMessage(string fieldName, string value)
{
if (string.IsNullOrWhiteSpace(value))
return $"{fieldName} cannot be empty.";
switch (fieldName.ToLower())
{
case "ip address":
case "ipaddress":
if (!IsValidIpAddressOrHostname(value))
return "Please enter a valid IP address or hostname.";
break;
case "interval":
case "ping interval":
if (!IsValidPingInterval(value, out _))
return "Ping interval must be between 100 and 60000 milliseconds.";
break;
}
return null;
}
}
}

5
packages.config Normal file
عرض الملف

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="IPAddressControl" version="1.2.4446.28646" targetFramework="net472" />
<package id="TaskScheduler" version="2.10.1" targetFramework="net472" />
</packages>

ثنائية
xray_drawing_1_origi_fETdd.ico Normal file

ملف ثنائي غير معروض.

بعد

العرض:  |  الارتفاع:  |  الحجم: 13 KiB