Before coming to SO for an answer I've spent the last 2 or 3 days on Google trying different question forms to try and get this to work.
I need to get the color setting of the current print job to determine how many color or grayscale prints a user has performed. However every single color property I've tried to access (through ManagementObjectSearcher, ""Watcher, and the built-in printer classes of C#) always return color, never grayscale.
Any help would be greatly appreciated, since I've come to a stop on making progress with solutions. Thanks. Below is the code I have (keep in mind it's my prototyping code so there might be many issues apart from what I'm asking. Please only provide suggestions WITH your answer to my question).
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Printing;
using System.Management;
using System.Management.Instrumentation;
using System.Threading;
using System.Windows.Threading;
using System.Diagnostics;
namespace PrintPlus {
public partial class PrintPlus : Form {
#region Objects
// Mgmt
ManagementEventWatcher watcher;
ManagementObjectSearcher searcher;
// Thread
Thread jobCheck;
// Printer Objects
PrintQueue printQ;
PrintJobInfoCollection printJobCollection;
// Timer
private System.Windows.Forms.Timer timeLogged;
#endregion
#region Paths And Names
string localMachineName;
#endregion
#region Costs
private decimal timeCost;
private decimal printCost;
#endregion
#region Print Variables
private int color;
private bool jobIsProcessing;
private int numberOfPrints;
private int colorPrints;
private int greyScalePrints;
private int printJobCount;
#endregion
#region Time Variables
private float tSecs;
private float tMins;
private float tHrs;
#endregion
#region Constructor
public PrintPlus() {
InitializeComponent();
initObjects();
/* searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PrintJob");
watcher = new ManagementEventWatcher("SELECT * FROM __InstanceCreationEvent WITHIN 0.01 WHERE TargetInstance ISA \"Win32_PrintJob\"");
watcher.EventArrived += new EventArrivedEventHandler(getColorSetting);
watcher.Start();
localMachineName = Environment.MachineName;*/
}
#endregion
#region Initializers
private void initObjects() {
initPrinterObjects();
initTimer();
}
private void initPrinterObjects() {
LocalPrintServer lps = new LocalPrintServer();
printQ = new PrintQueue(lps, lps.DefaultPrintQueue.Name);
}
private void initTimer() {
timeLogged = new System.Windows.Forms.Timer();
timeLogged.Interval = 1000;
timeLogged.Tick += new EventHandler(onTick);
timeLogged.Start();
}
#endregion
#region Delegates
private void onTick(object sender, EventArgs e) {
updateTime();
updateInfo();
}
private void onMove(object sender, EventArgs e) {
this.Location = initialPosition;
}
private void onLoseFocus(object sender, EventArgs e) {
this.MinimizeBox = true;
}
#endregion
#region Updates
private void updateInfo() {
printJobCount = printQ.GetPrintJobInfoCollection().Count<PrintSystemJobInfo>();
if (printJobCount >= 1 && !jobIsProcessing) {
jobIsProcessing = true;
jobCheck = new Thread(new ThreadStart(processJobs));
jobCheck.Start();
}
numberOfPrints = (colorPrints + greyScalePrints);
timeCostLbl.Text = "Time: $" + timeCost.ToString();
printCostLbl.Text = "Print: $" + printCost.ToString();
totalCostLbl.Text = "Total: $" + (timeCost + printCost).ToString();
printedPagesLbl.Text = "Printed Pages: " + numberOfPrints.ToString() + " Colour: " + colorPrints.ToString() + " B&W: " + greyScalePrints.ToString();
}
private void updateTime() {
tSecs += timeLogged.Interval / 1000;
if (tSecs == 60) {
timeCost += FEES.COST_PER_MIN;
tMins += 1;
if (tMins == 60) {
tHrs += 1;
}
tSecs = 0;
}
int i = 0;
String hrs = ((tHrs >= 10) ? tHrs.ToString() : i + tHrs.ToString());
String mins = ((tMins >= 10) ? tMins.ToString() : i + tMins.ToString());
String secs = ((tSecs >= 10) ? tSecs.ToString() : i + tSecs.ToString());
this.timeElapsedLbl.Text = "Time Logged: " + hrs + " : " + mins + " : " + secs;
}
public void processJobs() {
LocalPrintServer lps = new LocalPrintServer();
PrintQueue printQ = new PrintQueue(lps, lps.DefaultPrintQueue.Name);
PrintJobInfoCollection printJobCollection = printQ.GetPrintJobInfoCollection();
PrintSystemJobInfo[] jobArray = printJobCollection.ToArray<PrintSystemJobInfo>();
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PrintJob");
ManagementObjectCollection searchCollection = searcher.Get();
foreach (ManagementObject job in searchCollection) {
foreach (PropertyData prop in job.Properties) {
Debug.WriteLine(prop.Name + ": " + prop.Value);
}
}
try {
for (int i = 0; i < jobArray.Length; ++i) {
if (jobArray[i].PositionInPrintQueue == 1) {
while (jobArray[i].JobStatus != PrintJobStatus.Deleted) {
jobArray[i].Refresh();
}
}
Debug.WriteLine(printQ.CurrentJobSettings.CurrentPrintTicket.OutputColor.Value);
/*if (jobArray[i].PropertiesCollection. == "Color") {
colorPrints += jobArray[i].NumberOfPagesPrinted;
}
else if (jobArray[i].PropertiesCollection["Color"].ToString() == "Monochrome") {
greyScalePrints += jobArray[i].NumberOfPagesPrinted;
}*/
}
}
finally {
jobIsProcessing = false;
lps.Dispose();
printQ.Dispose();
printJobCollection.Dispose();
jobCheck.Abort();
}
}
private void getPrintWatcher(int jobID) {
}
private void getColorSetting(object sender, EventArrivedEventArgs e) {
/* foreach (PropertyData data in e.NewEvent.Properties) {
ManagementBaseObject mbo = data.Value as ManagementBaseObject;
if (mbo.Properties["Color"].Value == "Color") {
color = COLOR_VALUES.COLOR;
}
else if (mbo.Properties["Color"].Value == "Monochrome") {
color = COLOR_VALUES.MONO;
}
}*/
}
#endregion
}
}
I believe the problem you are experiencing is because the printer is capable of printing in color and black and white. When you print a black letter text document via a color printer the WIN32_PrintJob will still say that the document is a color document UNLESS you explicitly tell the printer to print in black and white via the local machine's 'printer preferences' dialog.
Color counter of each printer maker and model works differently. Your best bet would be before processing the printing, go through the printing material and determine the colour pages and black pages. If not you will have to relay on the machine counter which only available for Multi functional printers, you can get this information through SNMP.
I spent a lot of time to weigh out how to get the real value of the defined color printing and discovered that Win32_PrintJob provides this information in this way:
public static bool PausePrintJob(string printerName, int printJobID)
{
bool isActionPerformed = false;
string searchQuery = "SELECT * FROM Win32_PrintJob";
ManagementObjectSearcher searchPrintJobs = new ManagementObjectSearcher(searchQuery);
ManagementObjectCollection prntJobCollection = searchPrintJobs.Get();
foreach (ManagementObject prntJob in prntJobCollection)
{
System.String jobName = prntJob.Properties["Name"].Value.ToString();
//Job name would be of the format [Printer name], [Job ID]
char[] splitArr = new char[1];
splitArr[0] = Convert.ToChar(",");
string prnterName = jobName.Split(splitArr)[0];
int prntJobID = Convert.ToInt32(jobName.Split(splitArr)[1]);
string documentName = prntJob.Properties["Document"].Value.ToString();
if (String.Compare(prnterName, printerName, true) == 0)
{
if (prntJobID == printJobID)
{
// MessageBox.Show("PAGINAS : " + prntJob.Properties["TotalPages"].Value.ToString() + documentName + " " + prntJobID);
prntJob.InvokeMethod("Pause", null);
MessageBox.Show(prntJob.Properties["Color"].Value.ToString());
//prntJob.InvokeMethod("Resume", null);
isActionPerformed = true;
break;
}
}
}
return isActionPerformed;
}
Related
Before i begin I know its messy, I'm getting it working before I clean it up. This is also just for my own knowledge growth I do not intend on rolling this out throughout the company. I have made a monitoring program to check the status of a couple of servers for one of my clients. I have managed to get all the relevant data I need from the ping to the servers, I take the data and send it to the "sort" method where it sends that to the next method which figures out which label I should change the text of, it makes it into these if statements however it just doesn't update the text.
I have already tried:
Application.doEvents();
Label.Refresh();
Label.Update();
I've tried using multithreading too see if that would perhaps force it through.
I have even tried using a button to manually update and that didn't work either.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Button1_Click(object sender, EventArgs e)
{
Synergy s = new Synergy();
s.Start();
}
private void Label2_Click(object sender, EventArgs e)
{
}
public void Sort(String Name, double P, long RTT, String Response)
{
Console.WriteLine(Name + ": Inside Sort");
if (Name.Contains("SYN-"))
{
SynergySort(Name, P, RTT, Response);
}
}
public void SynergySort(String Name, double P, long RTT, String Response)
{
Console.WriteLine(Name + ": Inside Synergy Sort");
if (Name.Equals("SYN-DC01"))
{
Console.WriteLine(Name + ": Inside DC01 SORT");
this.SD1R.Text = RTT.ToString();
this.SD1P.Text = P.ToString();
}
else if (Name.Equals("SYN-DC03"))
{
Console.WriteLine(Name + ": Inside DC03 SORT");
this.SD3R.Text = RTT.ToString();
this.SD3P.Text = P.ToString();
}
}
}
public class Synergy
{
private Form1 f = new Form1();
private Pinger ping = new Pinger();
public void Start()
{
NAS01Scan();
DC03Scan();
TRACKERScan();
DC01Scan();
VoiceScan();
NETAPPScan();
}
public void NAS01Scan()
{
Console.WriteLine("Pinging NAS01");
ping.IP("172.16.xx.xxx", 5, "SYN-NAS01");
}
public void DC03Scan()
{
Console.WriteLine("pinging DC03");
ping.IP("172.16.xx.xxx", 5, "SYN-DC03");
}
public void TRACKERScan()
{
Console.WriteLine("pinging TRACKER");
ping.IP("172.16.xx.xxx", 5, "SYN-TRACKER");
}
public void DC01Scan()
{
Console.WriteLine("pinging DC01");
ping.IP("172.16.xx.xxx", 5, "SYN-DC01");
}
public void NETAPPScan()
{
Console.WriteLine("pinging NETAPP");
ping.IP("172.16.xx.xxx", 5, "SYN-NETAPP");
}
public void VoiceScan()
{
Console.WriteLine("pinging AVAYA_Voice");
ping.IP("172.16.xx.xxx", 5, "SYN-AVAYA_Voice");
}
}
public class Pinger
{
private Form1 f = new Form1();
public void IP(String host, int echoNum, String Name)
{
long totalTime = 0;
PingReply reply = null;
int timeout = 120;
Ping pingSender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int failed = 0;
for (int i = 0; i < echoNum; i++)
{
reply = pingSender.Send(host, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
}
else
{
failed += 1;
Console.WriteLine(Name + ": " + reply.Status);
}
}
totalTime += reply.RoundtripTime;
Console.WriteLine(Name + ": RoundTrip time: {0}", reply.RoundtripTime);
Console.WriteLine(Name + ": Time in MS = " + totalTime / echoNum);
double percent = (failed / echoNum) * 100;
Console.WriteLine(Name + ": Percent Loss is " + percent);
f.Sort(Name, percent, reply.RoundtripTime, reply.Status.ToString());
}
}
I'm developing a sample program to connect multiple device using backgroundworker. Each device connected will be add to the list as new object. After finished connecting all the devices, i wanted to add an event handler for each connected devices. The problem that i'm facing now is the event handler doesn't firing at all. Below are the sample codes.
The Connect click button event :
private void btnConnect_Click(object sender, EventArgs e)
{
using (BackgroundWorker m_oWorker = new BackgroundWorker())
{
m_oWorker.DoWork += delegate (object s, DoWorkEventArgs args)
{
int iIpStart = 0;
int iIpEnd = 0;
string strIp1 = string.Empty;
string strIp2 = string.Empty;
list.Clear();
string[] sIP1 = txtIpStart.Text.Trim().ToString().Split('.');
string[] sIP2 = txtIpEnd.Text.Trim().ToString().Split('.');
iIpStart = Convert.ToInt32(sIP1[3]);
iIpEnd = Convert.ToInt32(sIP2[3]);
strIp1 = sIP1[0] + "." + sIP1[1] + "." + sIP1[2] + ".";
strIp2 = sIP2[0] + "." + sIP2[1] + "." + sIP2[2] + ".";
Ping ping = new Ping();
PingReply reply = null;
int iIncre = 0;
int iVal = (100 / (iIpEnd - iIpStart));
for (int i = iIpStart; i <= iIpEnd; i++)
{
Thread.Sleep(100);
string strIpconnect = strIp1 + i.ToString();
Console.Write("ip address : " + strIpconnect + ", status: ");
reply = ping.Send(strIpconnect);
if (reply.Status.ToString() == "Success")
{
if (ConnectDevice(strIpconnect))
{
strLastDevice = strIpconnect + " Connected";
isconnected = true;
}
else
{
isconnected = false;
}
}
else
{
isconnected = false;
}
m_oWorker.ReportProgress(iIncre);
iIncre = iIncre + iVal;
}
m_oWorker.ReportProgress(100);
};
m_oWorker.ProgressChanged += new ProgressChangedEventHandler(m_oWorker_ProgressChanged);
m_oWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_oWorker_RunWorkerCompleted);
m_oWorker.WorkerReportsProgress = true;
m_oWorker.WorkerSupportsCancellation = true;
m_oWorker.RunWorkerAsync();
}
}
ConnectDevice function method. Connected device will be added to the list :
protected bool ConnectDevice(string sIP)
{
try
{
NewSDK sdk = new NewSDK();
if (sdk.Connect() == true)
{
list.Add(new objSDK { sdk = sdk, ipaddress = sIP });
return true;
}
else
{
}
}
catch() {}
return false;
}
the Backgroundworker :
void m_oWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//If it was cancelled midway
if (e.Cancelled)
{
lblStatus.Text = "Task Cancelled.";
}
else if (e.Error != null)
{
lblStatus.Text = "Error while performing background operation.";
}
else
{
lblStatus.Text = "Task Completed...";
btnListen.Enabled = true;
}
}
void m_oWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//Here you play with the main UI thread
progressBar1.Value = e.ProgressPercentage;
lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";
if (isconnected)
{
listBox2.Items.Add(strLastDevice);
string[] ssplit = sDeviceInfo.Split(';');
foreach (string sword in ssplit)
{
listBox1.Items.Add(sword);
}
}
}
The function to attached event :
private void RegisterEvent()
{
foreach (objSDK obj in list)
{
obj.sdk.OnTransaction += () =>
{
listBox1.Items.Add("ip : " + obj.IP + " transaction");
};
}
}
You have declared m_oWorker as a local variable. I'm guessing this was a mistake ( the m_ prefix should only be used for class member variables)?
Also, you declared it within a using statement, meaning that it that the framework will call Dispose() on it at the end of the using block. Even if you held on to a reference to it (and I don't think you do) it still means its resources will be deallocated, which is probably why it isn't handling any events.
I try another workaround by using thread and task and work perfectly. Thanks for all response
Basically I need to communicate with a COM serial printer. There are 2 timers, one will print one ticket at time, and the others will hang up checking for errors and resuming the printing when the errors are gone.
For example: Printer is printing but if I press the pause button an error (read in the buffer) will get some booleans to 1 and after I read them I am able to tell what the error is and stop the printing.
My problem is in the method ErrorTimer_Elapsed() which is the timer elapsed event and probably is linked to the ErrorCheck and SendToCom (which is the printing method). The problem is that program detects errors well, but when in ErrorTimer_Elapsed() I try to repeatdly check for error status changes, I get IO errors like:
-Can't acces COM PORT
-The resource you required is in use
and so on.
Can you help me? Thanks, here's the code (about 180 lines), I'm bumping my head on this since 3 days :( :
using System;
using System.Collections;
using System.Configuration;
using System.IO;
using System.IO.Ports;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
#region Variabili di istanza
private ArrayList _filesToPrint = new ArrayList();
private static SerialPort _serialPort1 = new SerialPort();
private string _portName = ConfigurationSettings.AppSettings["COM"];
private string FilesPath = ConfigurationSettings.AppSettings["Path"];
private System.Timers.Timer PrintTimer = new System.Timers.Timer(2000);
private System.Timers.Timer ErrorTimer = new System.Timers.Timer(3500);
private bool PrintTimerIsActive = true;
private string HsCOMerrorStrings, PrintErrors;
#endregion
public Form1()
{
_serialPort1.PortName = _portName;
_serialPort1.ReadTimeout = 1000;
_IfFileExistsPrint();
}
private void _IfFileExistsPrint()
{
foreach (string file in Directory.GetFiles(FilesPath))
_filesToPrint.Add(file);
FileSystemWatcher SysWatch = new FileSystemWatcher(FilesPath, "*.*");
SysWatch.Created += new FileSystemEventHandler(SysWatch_Created);
SysWatch.EnableRaisingEvents = true;
PrintTimer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
PrintTimer.Start();
ErrorTimer.Elapsed += new System.Timers.ElapsedEventHandler(ErrorTimer_Elapsed);
}
private void SysWatch_Created(object Sender, FileSystemEventArgs w)
{
_filesToPrint.Add(w.FullPath);
}
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (_filesToPrint.Count > 0 && PrintTimerIsActive)
{
PrintTimer.Stop();
SendFilesToCom(_filesToPrint[0].ToString());
MessageBox.Show("Printing file :" + _filesToPrint[0].ToString());
File.Delete(_filesToPrint[0].ToString());
_filesToPrint.RemoveAt(0);
_filesToPrint.TrimToSize();
Console.Write(HsCOMerrorStrings);
PrintTimer.Start();
PrintErrors = ErrorCheck(HsCOMerrorStrings);
}
}
private void ErrorTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs d)
{
if (!_serialPort1.IsOpen)
{
try
{
_serialPort1.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.Data);
}
}
try
{
HsCOMerrorStrings = _serialPort1.ReadExisting();
_serialPort1.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Data);
}
Console.WriteLine(ErrorCheck(HsCOMerrorStrings));
}
private string ErrorCheck(string COMHostStatusReturn)
{
string ErrorsReturn = System.String.Empty;
string[] COMCode = COMHostStatusReturn.Split(',');
if (COMCode[1] == "1") { ErrorsReturn += "Carta Esaurita" + Environment.NewLine; }
if (COMCode[2] == "1") { ErrorsReturn += "Stampante in Pausa" + Environment.NewLine; }
if (COMCode[5] == "1") { ErrorsReturn += "Memoria Stampante Esaurita" + Environment.NewLine; }
if (COMCode[9] == "1") { ErrorsReturn += "Memoria RAM corrotta" + Environment.NewLine; }
if (COMCode[10] == "1") { ErrorsReturn += "Temperatura troppo bassa" + Environment.NewLine; }
if (COMCode[11] == "1") { ErrorsReturn += "Temperatura troppo alta" + Environment.NewLine; }
if (COMCode[7] == "1") { ErrorsReturn += "Partial Format Flag" + Environment.NewLine; }
if (ErrorsReturn != System.String.Empty)
{
if (PrintTimerIsActive == true)
{
PrintTimer.Stop();
if (!ErrorTimer.Enabled)
ErrorTimer.Start();
MessageBox.Show(ErrorsReturn);
}
PrintTimerIsActive = false;
}
else
{
if (PrintTimerIsActive == false)
{
ErrorTimer.Stop();
PrintTimer.Start();
PrintTimerIsActive = true;
}
}
return ErrorsReturn;
}
private void SendFilesToCom(string filePath)
{
if (!_serialPort1.IsOpen)
{
try
{
_serialPort1.Open();
}
catch (Exception ex)
{
}
}
try
{
using (System.IO.TextReader reader = File.OpenText(filePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
_serialPort1.WriteLine(line);
}
HsCOMerrorStrings = _serialPort1.ReadLine();
reader.Close();
_serialPort1.Close();
}
}
catch (Exception ex)
{
}
}
}
}
I have an application that scans the local network for connected PC's.
I want to get the client information (IP address, MAC address, Host name...) and the connection state (download rate, upload rate), and put them in the ListView, but the problem is that this information is not constant!
How could I get this information in real time? The info in the ListView changes every time the info of the client changes?
My current code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Collections;
using System.Text;
using System.Windows.Forms;
using NetUtils;
using System.Net;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
private IPScanner _scanner;
private class HostSorterByIP : IComparer
{
public int Compare(object x, object y)
{
byte[] bytes1 = ((IPScanHostState)((ListViewItem)x).Tag).Address.GetAddressBytes();
byte[] bytes2 = ((IPScanHostState)((ListViewItem)y).Tag).Address.GetAddressBytes();
int i = bytes1.Length - 1;
for (; i > 0 && bytes1[i] == bytes2[i]; i--)
;
return bytes1[i] - bytes2[i];
}
}
public Form1()
{
InitializeComponent();
_scanner = new IPScanner((int)_spnConcurrentPings.Value, (int)_spnPingsPerScan.Value, _cbContinuousScan.Checked,
(int)_spnTimeout.Value, (int)_spnTTL.Value, _cbDontFragment.Checked, (int)_spnBufferSize.Value);
_scanner.OnAliveHostFound += new IPScanner.AliveHostFoundDelegate(_scanner_OnAliveHostFound);
_scanner.OnStartScan += new IPScanner.ScanStateChangeDelegate(_scanner_OnStartScan);
_scanner.OnStopScan += new IPScanner.ScanStateChangeDelegate(_scanner_OnStopScan);
_scanner.OnRestartScan +=new IPScanner.ScanStateChangeDelegate(_scanner_OnRestartScan);
_scanner.OnScanProgressUpdate +=new IPScanner.ScanProgressUpdateDelegate(_scanner_OnScanProgressUpdate);
_lvAliveHosts.ListViewItemSorter = new HostSorterByIP();
_cmbRangeType.SelectedIndex = 0;
}
private void _scanner_OnAliveHostFound(IPScanner scanner, IPScanHostState host)
{
if (InvokeRequired)
{
BeginInvoke(new IPScanner.AliveHostFoundDelegate(_scanner_OnAliveHostFound), scanner, host);
return;
}
ListViewItem item = new ListViewItem();
item.Tag = host;
item.BackColor = Color.GreenYellow;
item.SubItems.Add(host.Address.ToString());
item.SubItems.Add("");
item.SubItems.Add("");
item.SubItems.Add("");
_lvAliveHosts.Items.Add(item);
_lvAliveHosts.Sort();
host.OnHostNameAvailable += new IPScanHostState.HostNameAvailableDelegate(host_OnHostNameAvailable);
host.OnStateChange += new IPScanHostState.StateChangeDelegate(host_OnStateChange);
if (!host.IsTesting())
{
item.ImageIndex = (int)host.QualityCategory;
item.SubItems[2].Text = host.AvgResponseTime.ToString("F02") + " ms";
item.SubItems[3].Text = ((float)(host.LossCount) / host.PingsCount).ToString("P");
item.SubItems[4].Text = host.HostName;
}
//AddLogEntry("Host [" + host.Address.ToString() + "] is alive.");
Timer newTimer = new Timer();
newTimer.Tag = item;
newTimer.Interval = 2000;
newTimer.Tick += new EventHandler(newTimer_Tick);
newTimer.Enabled = true;
}
void host_OnHostNameAvailable(IPScanHostState host)
{
if (InvokeRequired)
{
BeginInvoke(new IPScanHostState.HostNameAvailableDelegate(host_OnHostNameAvailable), host);
return;
}
ListViewItem item = FindListViewItem(host);
if (item != null)
item.SubItems[4].Text = host.HostName;
}
private ListViewItem FindListViewItem(IPScanHostState host)
{
foreach (ListViewItem item in _lvAliveHosts.Items)
{
if (item.Tag == host)
return item;
}
return null;
}
private void host_OnStateChange(IPScanHostState host, IPScanHostState.State oldState)
{
if (InvokeRequired)
{
BeginInvoke(new IPScanHostState.StateChangeDelegate(host_OnStateChange), host, oldState);
return;
}
if (!host.IsTesting())
{
ListViewItem item = FindListViewItem(host);
if (item != null)
{
if (host.IsAlive())
{
item.ImageIndex = (int)host.QualityCategory;
item.SubItems[2].Text = host.AvgResponseTime.ToString("F02") + " ms";
item.SubItems[3].Text = ((float)(host.LossCount) / host.PingsCount).ToString("P");
}
else
{
//AddLogEntry("Host [" + host.Address.ToString() + "] died.");
host.OnStateChange -= host_OnStateChange;
host.OnHostNameAvailable -= host_OnHostNameAvailable;
item.BackColor = Color.IndianRed;
Timer removeTimer = new Timer();
removeTimer.Tag = item;
removeTimer.Interval = 2000;
removeTimer.Tick += new EventHandler(removeTimer_Tick);
removeTimer.Enabled = true;
}
}
}
}
void newTimer_Tick(object sender, EventArgs e)
{
Timer timer = (Timer)sender;
timer.Stop();
timer.Tick -= newTimer_Tick;
ListViewItem item = (ListViewItem)timer.Tag;
item.BackColor = Color.White;
}
void removeTimer_Tick(object sender, EventArgs e)
{
Timer timer = (Timer)sender;
timer.Stop();
timer.Tick -= newTimer_Tick;
ListViewItem item = (ListViewItem)timer.Tag;
_lvAliveHosts.Items.Remove(item);
}
private void _scanner_OnStartScan(IPScanner scanner)
{
if (InvokeRequired)
{
BeginInvoke(new IPScanner.ScanStateChangeDelegate(_scanner_OnStartScan), scanner);
return;
}
foreach (ListViewItem item in _lvAliveHosts.Items)
{
((IPScanHostState)item.Tag).OnStateChange -= host_OnStateChange;
((IPScanHostState)item.Tag).OnHostNameAvailable -= host_OnHostNameAvailable;
}
_lvAliveHosts.Items.Clear();
_prgScanProgress.Value = 0;
EnableSettings(false);
}
private void EnableSettings(bool enable)
{
_cmbRangeType.Enabled = _tbRangeStart.Enabled = _tbRangeEnd.Enabled = _spnTimeout.Enabled = _spnTTL.Enabled = _spnBufferSize.Enabled = _cbDontFragment.Enabled =
_spnConcurrentPings.Enabled = _spnPingsPerScan.Enabled = _cbContinuousScan.Enabled = enable;
_btnStartStop.Text = enable ? "&Start" : "&Stop";
if (enable)
_prgScanProgress.Text = "Scanner is not running!";
}
private void _btnStartStop_Click(object sender, EventArgs e)
{
if (!_scanner.Active)
{
try
{
_scanner.Start(_cmbRangeType.SelectedIndex == 0
? new IPScanRange(IPAddress.Parse(_tbRangeStart.Text), IPAddress.Parse(_tbRangeEnd.Text))
: new IPScanRange(IPAddress.Parse(_tbRangeStart.Text), int.Parse(_tbRangeEnd.Text)));
}
catch (FormatException)
{
MessageBox.Show(this, "Cannot parse IP range or subnetmask!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
_scanner.Stop(false);
}
private void _scanner_OnStopScan(IPScanner scanner)
{
if (InvokeRequired)
{
BeginInvoke(new IPScanner.ScanStateChangeDelegate(_scanner_OnStopScan), scanner);
return;
}
EnableSettings(true);
_prgScanProgress.Value = 0;
}
void _scanner_OnRestartScan(IPScanner scanner)
{
if (InvokeRequired)
{
BeginInvoke(new IPScanner.ScanStateChangeDelegate(_scanner_OnRestartScan), scanner);
return;
}
_prgScanProgress.Value = 0;
}
void _scanner_OnScanProgressUpdate(IPScanner scanner, IPAddress currentAddress, ulong progress, ulong total)
{
if (InvokeRequired)
{
BeginInvoke(new IPScanner.ScanProgressUpdateDelegate(_scanner_OnScanProgressUpdate), scanner, currentAddress, progress, total);
return;
}
int prog = (int)((100 * progress) / total);
_prgScanProgress.Value = prog;
_prgScanProgress.Text = prog.ToString() + "%" + " [" + currentAddress.ToString() + "]";
}
private void _cmbRangeType_SelectedIndexChanged(object sender, EventArgs e)
{
if (_cmbRangeType.SelectedIndex == 0)
{
_lRangeSep.Text = "-";
_lRangeEnd.Text = "Range &End:";
_tbRangeEnd.Size = new Size(130, _tbRangeEnd.Size.Height);
}
else
{
_lRangeSep.Text = "/";
_lRangeEnd.Text = "Subnet &Mask:";
_tbRangeEnd.Size = new Size(32, _tbRangeEnd.Size.Height);
}
}
//private void _lvAliveHosts_DoubleClick(object sender, EventArgs e) { _btnAddHost_Click(sender, e); }
private void IPScanForm_FormClosing(object sender, FormClosingEventArgs e) { _scanner.Stop(true); }
private ListViewItem.ListViewSubItem _activeTooltipSubitem = null;
private static string[] QualityCategoryNames = { "Very Poor", "Poor", "Fair", "Good", "Very Good", "Excellent", "Perfect" };
private void _lvAliveHosts_MouseMove(object sender, MouseEventArgs e)
{
ListViewItem item = _lvAliveHosts.HitTest(e.Location).Item;
if (item != null)
{
ListViewItem.ListViewSubItem subitem = _lvAliveHosts.HitTest(e.Location).SubItem;
if (subitem != null && item.SubItems.IndexOf(subitem) == 0)
{
if (_activeTooltipSubitem != subitem)
{
_ttQuality.Show("Quality: " + QualityCategoryNames[item.ImageIndex], _lvAliveHosts, item.SubItems[1].Bounds.X, subitem.Bounds.Y);
_activeTooltipSubitem = subitem;
}
return;
}
}
_activeTooltipSubitem = null;
_ttQuality.Hide(_lvAliveHosts);
}
}
}
I would create the list of clients and show them in the listview.
Than, in a background thread, every X seconds, poll all of the current clients.
Next , compare the list of updated clients to a list of clients from last update.
What remain to do is to add any new client to the list, and remove any client which no longer exists.
Pay attention to the context, use InvokeRequired() to get access to the UI control from the background thread.
EDIT:
here is how to run a background thread:
static void Main(string[] args)
{
Thread worker = new Thread(DoBackgroundWork);
}
public static void DoBackgroundWork()
{
while (true)
{
//Sleep 10 seconds
Thread.Sleep(10000);
//Do some work and than post to the control using Invoke()
}
}
I want my application will show on my form my class properties so I started my class with BackgroundWorker and create ProgressChanged.
my class:
public class DumpFile
{
PacketDevice _device;
public int _packetsCount;
public double _bitsPerSecond;
public double _packetsPerSecond;
public DateTime _lastTimestamp;
public delegate void dlgPackProgress(int progress);
public event dlgPackProgress evePacketProgress;
public DumpFile(PacketDevice device, string pcapPath)
{
_device = device;
_pcapPath = pcapPath;
_packetsCount = 1;
}
public void startCapturing()
{
OnPacketProgress(_packetsCount++);
using (PacketCommunicator communicator = _device.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000)) //open the device
{
ThreadStart starter = delegate { openAdapterForStatistics(_device); };
new Thread(starter).Start();
using (PacketDumpFile dumpFile = communicator.OpenDump(_pcapPath)) //open the dump file
{
communicator.ReceivePackets(0, dumpFile.Dump); //start the capture
}
}
}
private void OnPacketProgress(int packet)
{
var handler = evePacketProgress;
if (handler != null)
{
handler(packet);
}
}
public void openAdapterForStatistics(PacketDevice selectedOutputDevice)
{
using (PacketCommunicator statCommunicator = selectedOutputDevice.Open(100, PacketDeviceOpenAttributes.Promiscuous, 1000)) //open the output adapter
{
ThreadStart start = delegate { test(selectedOutputDevice); };
new Thread(start).Start();
statCommunicator.SetFilter("tcp"); //compile and set the filter
statCommunicator.Mode = PacketCommunicatorMode.Statistics; //put the interface in statstics mode
statCommunicator.ReceiveStatistics(0, StatisticsHandler);
}
}
public void test(PacketDevice selectedOutputDevice)
{
using (PacketCommunicator communicator = selectedOutputDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000))
{
communicator.ReceivePackets(0, PacketHandler);
}
}
private void PacketHandler(Packet packet)
{
string result = _packetsCount.ToString() + ". " + packet.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff") + " length:" + packet.Length;
_packetsCount++;
}
private void StatisticsHandler(PacketSampleStatistics statistics)
{
DateTime currentTimestamp = statistics.Timestamp; //current sample time
DateTime previousTimestamp = _lastTimestamp; //previous sample time
_lastTimestamp = currentTimestamp; //set _lastTimestamp for the next iteration
if (previousTimestamp == DateTime.MinValue) //if there wasn't a previous sample than skip this iteration (it's the first iteration)
{
return;
}
double delayInSeconds = (currentTimestamp - previousTimestamp).TotalSeconds; //calculate the delay from the last sample
_bitsPerSecond = statistics.AcceptedBytes * 8 / delayInSeconds; //calculate bits per second
_packetsPerSecond = statistics.AcceptedPackets / delayInSeconds; //calculate packets per second
}
}
start button who start capturing:
private void btnStartCapture_Click(object sender, EventArgs e)
{
timerSniffer.Start();
btnStartTabSniffer.Enabled = false;
btnStopTabSniffer.Enabled = true;
groupBoxSelectTabSniffer.Enabled = false;
bgWorker = new BackgroundWorker();
bgWorker.WorkerReportsProgress = true;
bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWSniffer_ProgressChanged);
bgWorker.DoWork += new DoWorkEventHandler(
(s3, e3) =>
{
DumpFile dumpFile = new DumpFile(deviceForCapturing, pcapFilePathSniffer);
tshark.evePacketProgress += new DumpFile.dlgPackProgress(
(packet) =>
{
bgWorker.ReportProgress(packet, dumpFile);
});
dumpFile.startCapturing();
});
bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
(s3, e3) =>
{
groupBoxSelectTabSniffer.Enabled = true;
});
bgWorker.RunWorkerAsync();
}
ProgressChanged:
private void bgWSniffer_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
var dumpFile = (DumpFile)e.UserState;
lblNumberOfPacketsTabSniffer2.Text = dumpFile._packetsCount.ToString("#,##0");
lblTrafficRateTabSniffer2.Text = (dumpFile._bitsPerSecond * 0.000001).ToString("0.##") + " Mbit/sec" + " (" + dumpFile._bitsPerSecond.ToString("#,##0") + " Bits/sec" + ")";
lblPacketsRateTabSniffer2.Text = dumpFile._packetsPerSecond.ToString("#,##0") + " Packets/sec";
}
the problem is that my application "get into" ProgressChanged functions but only in one time.
I think I missed something in my class.
I can only find one call to OnPacketProgress(), and it's outside of any loop.
public void startCapturing()
{
OnPacketProgress(_packetsCount++);
....
}
So Yes, that will only be called once.
You need something inside ReceivePackets()