Make Ping request in Visual Studio C# - c#

so I'm very new to Visual Studio and C# but I'm having trouble making a Ping cmd in my app. I have included the code and images. Basically, when I run the app and try to make the ping request it just takes me to the App.g.i.cs file and highlights this code
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
#endif
}
}
}
So I don't know where I'm really going wrong. I know this might be a really dumb question but I'm just not familiar with Visual Studio yet. Would love any suggestions :)
Here is the code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using System.ComponentModel;
using System.Threading;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace Ping_IP
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Ping pingsender = new Ping();
PingReply reply = pingsender.Send(ip_address.ToString());
if (reply.Status == IPStatus.Success)
{
status_info.Text = "Sucess! - " + DateTime.Now.ToLocalTime(); //reply.Status.ToString();
} else
{
status_info.Text = "Failed... - " + DateTime.Now.ToLocalTime();
}
}
}
}

I referred to Klaus Gütter's opinion and successfully returned the data.
PingReply reply = pingsender.Send(ip_address.Text);
Complete code
private void Button_Click(object sender, RoutedEventArgs e) {
Ping pingsender = new Ping();
PingReply reply = pingsender.Send(ip_address.Text);
if (reply.Status == IPStatus.Success) {
status_info.Text = "Sucess! - " + DateTime.Now.ToLocalTime(); //reply.Status.ToString();
} else {
status_info.Text = "Failed... - " + DateTime.Now.ToLocalTime();
}
}
Try catch
private void Button_Click(object sender, RoutedEventArgs e) {
Ping pingsender = new Ping();
try {
PingReply reply = pingsender.Send(ip_address.Text);
if (reply.Status == IPStatus.Success) {
status_info.Text = "Sucess! - " + DateTime.Now.ToLocalTime(); //reply.Status.ToString();
} else {
status_info.Text = "Failed... - " + DateTime.Now.ToLocalTime();
}
} catch (Exception) {
MessageBox.Show("something wrong");
}
}
}
Prompt when try fails.

Related

Update IP Address Text Box If There Is A Change To The Network

I'm trying to do something that is probably very simple, but I can't seem to get it working. I'm writing small app that displays some information including the IP Address. Everything is working perfectly, except that when the IP address changes (Network disconnect, LAN to WiFi, etc), I can't get it to update the text field with a message saying disconnected, or with the new IP Address. I've tried so many things and nothing works. A workaround that I am using is to shut the program down, and then start it immediately.
Here is the workaround code that I am using:
`
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Management.Automation;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Threading;
using Microsoft.Win32;
using System.Diagnostics;
using System.Xml.Linq;
using System.Net;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Microsoft.TeamFoundation.Common.Internal;
using Microsoft.TeamFoundation.Framework.Common;
namespace JIC_BackgroundInfo
{
public partial class MainWindow : Window
{
private UserPreferenceChangedEventHandler UserPreferenceChanged;
public MainWindow()
{
InitializeComponent();
this.WindowStartupLocation = WindowStartupLocation.Manual;
this.Left = System.Windows.SystemParameters.WorkArea.Width - this.Width;
this.Top = System.Windows.SystemParameters.WorkArea.Height - this.Height;
NetworkChange.NetworkAddressChanged += new
NetworkAddressChangedEventHandler(AddressChangedCallback);
}
static void AddressChangedCallback(object sender, EventArgs e)
{
Process.Start(#"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\JIC_BackgroundInfo.exe");
Thread.Sleep(8500);
Application.Current.Shutdown();
}
`
I tried the following code, along with many other variations, but it just crashes the app:
`
public void AddressChangedCallback(object sender, EventArgs e)
{
using (PowerShell powerShell = PowerShell.Create())
{
try
{
var ps1 = $#"(Get-NetIPAddress -AddressFamily IPv4 -AddressState Preferred -PrefixOrigin Dhcp).IPv4Address";
powerShell.AddScript(ps1);
Collection<PSObject> PSOutput = powerShell.Invoke();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject pSObject in PSOutput)
{
stringBuilder.AppendLine(pSObject.ToString());
}
TxtBoxIPAddress.Text = stringBuilder.ToString();
}
catch { TxtBoxIPAddress.Text = "No Address Found!"; return; }
}
}
`
Look into the ManagementEventWatcher class.
https://learn.microsoft.com/en-us/dotnet/api/system.management.managementeventwatcher?view=dotnet-plat-ext-7.0
You can use it to look for IP Addr changes and then ship those to your window that displays it.
private void AddressChangedCallback(object sender, EventArgs e)
{
Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate
{
using (PowerShell powerShell = PowerShell.Create())
{
try
{
var ps1 = $#"(Get-NetIPAddress -AddressFamily IPv4 -AddressState Preferred -PrefixOrigin Dhcp).IPv4Address";
powerShell.AddScript(ps1);
Collection<PSObject> PSOutput = powerShell.Invoke();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject pSObject in PSOutput)
{
stringBuilder.AppendLine(pSObject.ToString());
}
TxtBoxIPAddress.Text = stringBuilder.ToString();
}
catch { TxtBoxIPAddress.Text = "No Address Found!"; }
}
});
}

How to connect a gsm modem AUTOMATICALLY to available COM ports (without combobox)

THIS QUESTION MAY SEAM A DUPLICATE, BUT NOT. after a long period of search on internet and no, result, then had to seek for assistance.
All solutions apply to loading available ports in a combo box and the user checks one at a go. But the automation feature then dies.
thus, im looking for assistance on how the modem can connect automatically from the available ports without user interaction (USER FRIENDLINESS)
FOR THE COMBO BOX, IT IS WORKING FINE AS BELOW,
using GsmComm.GsmCommunication;
using GsmComm.PduConverter;
using GsmComm.Server;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace COMM_All
{
public partial class Comm_F : Form
{
public Comm_F()
{
InitializeComponent();
}
private void COM_PORTS()
{
string[] ports = SerialPort.GetPortNames();
txtGPort1.Items.AddRange(ports);
txtGPort2.Items.AddRange(ports);
}
private void Form1_Load(object sender, EventArgs e)
{
COM_PORTS();
}
private void Modem1_Click(object sender, EventArgs e)
{
if (txtGPort1.Text == "") { MessageBox.Show("Invalid Port Name"); return; }
comm = new GsmCommMain(txtGPort1.Text, 9600, 8);
Cursor.Current = Cursors.Default;
bool retry;
do
{
retry = false;
try
{
Cursor.Current = Cursors.WaitCursor; comm.Open(); Cursor.Current = Cursors.Default;
//MessageBox.Show("Modem Connected Sucessfully");
txtGStatus1.Text = "Connected Sucessfully";
comm.EnableMessageNotifications();
MessageBox.Show("Message notifications activated.");
}
catch (Exception)
{
Cursor.Current = Cursors.Default;
if (MessageBox.Show(this, "GSM Modem is not available", "Check",
MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning) == DialogResult.Retry)
retry = true;
else { return; }
}
} while (retry);
}
}
}
Note: Computer has multiple usb devices;

CanStop = false, but I can't start the service

I am making a service to put on my kid's computer, to make sure that they can't stop Qustodio, and they are quite tech-savvy. They know how to stop a service by going to Run >> services.msc, and I need to make the service NOT_STOPPABLE, like Kaspersky. But when I add the line: CanStop = false;, I can't start the service and it gives me an error. This is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace MyFirstService
{
public partial class Service1 : ServiceBase
{
Timer timer = new Timer();
ServiceController qengine = new ServiceController("qengine");
protected override void OnStart(string[] args)
{
WriteToFile("Service is started at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 5000; //number in milisecinds
timer.Enabled = true;
CanStop = false;
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
qengine.Start();
WriteToFile("qengine attemped start at: " + DateTime.Now);
}
public void WriteToFile(string Message)
{
string path = AppDomain.CurrentDomain.BaseDirectory + "\\Logs";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
if (!File.Exists(filepath))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(filepath))
{
sw.WriteLine(Message);
}
}
else
{
using (StreamWriter sw = File.AppendText(filepath))
{
sw.WriteLine(Message);
}
}
}
}
}

How to run a task every n minutes

I wrote a code to update DDNS which works fine. I now need to run this code every n minutes: how would I go doing that?
I tried using:
while (true)
{
this.DoMyMethod();
Thread.Sleep(TimeSpan.FromMinutes(1));
}
and I am still having some trouble. What is the best way to run this task every n minutes?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Windows.Forms;
using System.Timers;
namespace GoogleDDNS
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (username.Text == "")
{
System.Windows.MessageBox.Show("Please enter the username");
username.Focus();
return;
}
if (password.Text == "")
{
System.Windows.MessageBox.Show("Please enter the password");
password.Focus();
return;
}
if (subdomain.Text == "")
{
System.Windows.MessageBox.Show("Please enter the subdomain");
subdomain.Focus();
return;
}
var client = new WebClient { Credentials = new NetworkCredential(username.Text, password.Text) };
var response = client.DownloadString("https://domains.google.com/nic/update?hostname=" + subdomain.Text);
responseddns.Content = response;
Properties.Settings.Default.usernamesave = username.Text;
Properties.Settings.Default.passwordsave = password.Text;
Properties.Settings.Default.subdomainsave = subdomain.Text;
Properties.Settings.Default.Save();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
username.Text = Properties.Settings.Default.usernamesave;
password.Text = Properties.Settings.Default.passwordsave;
subdomain.Text = Properties.Settings.Default.subdomainsave;
}
}
}
Why not using System.Threading.Timer to do so?
From the Microsoft documentation, say you have the following sample class:
class StatusChecker
{
private int invokeCount;
private int maxCount;
public StatusChecker(int count)
{
invokeCount = 0;
maxCount = count;
}
// This method is called by the timer delegate.
public void CheckStatus(Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
Console.WriteLine("{0} Checking status {1,2}.",
DateTime.Now.ToString("h:mm:ss.fff"),
(++invokeCount).ToString());
if (invokeCount == maxCount)
{
// Reset the counter and signal the waiting thread.
invokeCount = 0;
autoEvent.Set();
}
}
}
Then you can create a Timer to run CheckStatus every n seconds, like:
// Create an AutoResetEvent to signal the timeout threshold in the
// timer callback has been reached.
var autoEvent = new AutoResetEvent(false);
var statusChecker = new StatusChecker(5);
// creates a Timer to call CheckStatus() with autoEvent as argument,
// starting with 1 second delay and calling every 2 seconds.
var stateTimer = new Timer(statusChecker.CheckStatus, autoEvent, 1000, 2000);
autoEvent.WaitOne();
i use timer,
the code is
using System;
using System.Net;
using System.Timers;
static void Main(string[] args)
{
Console.WriteLine("The system is start at {0}", DateTime.Now);
Timer t = new Timer(10000);
t.Enabled = true;
t.Elapsed += T_Elapsed;
Console.ReadKey();
}
private static void T_Elapsed(object sender, ElapsedEventArgs e)
{
//write your code
}
This is what fixed for me.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Windows.Forms;
using System.Timers;
namespace GoogleDDNS
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (username.Text == "")
{
System.Windows.MessageBox.Show("Please enter the username");
username.Focus();
return;
}
if (password.Text == "")
{
System.Windows.MessageBox.Show("Please enter the password");
password.Focus();
return;
}
if (subdomain.Text == "")
{
System.Windows.MessageBox.Show("Please enter the subdomain");
subdomain.Focus();
return;
}
var client = new WebClient { Credentials = new NetworkCredential(username.Text, password.Text) };
var response = client.DownloadString("https://domains.google.com/nic/update?hostname=" + subdomain.Text);
//MessageBox.Show(response);
responseddns.Content = response;
Properties.Settings.Default.usernamesave = username.Text;
Properties.Settings.Default.passwordsave = password.Text;
Properties.Settings.Default.subdomainsave = subdomain.Text;
//Properties.Settings.Default.intervalsave = interval.Text;
Properties.Settings.Default.Save();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
username.Text = Properties.Settings.Default.usernamesave;
password.Text = Properties.Settings.Default.passwordsave;
subdomain.Text = Properties.Settings.Default.subdomainsave;
//interval.Text = Properties.Settings.Default.intervalsave;
System.Windows.Forms.Timer MyTimer = new System.Windows.Forms.Timer();
MyTimer.Interval = (1 * 60 * 1000); // 45 mins
MyTimer.Tick += new EventHandler(MyTimer_Tick);
MyTimer.Start();
}
private void MyTimer_Tick(object sender, EventArgs e)
{
var client = new WebClient { Credentials = new NetworkCredential(username.Text, password.Text) };
var response = client.DownloadString("https://domains.google.com/nic/update?hostname=" + subdomain.Text);
//MessageBox.Show(response);
responseddns.Content = response;
//this.Close();
}
}
}
Have a look at this. I recall a colleague using it a while ago:
FluentScheduler - [Project Site]
Usage:
// Schedule an IJob to run at an interval
Schedule<MyJob>().ToRunNow().AndEvery(2).Minutes();
Will fulfill your need.
somwhere met this code
class Program
{
static void Main(string[] args)
{
int Interval = 5;
CancellationTokenSource cancellation = new CancellationTokenSource();
Console.WriteLine("Start Loop...");
RepeatActionEvery(() => Console.WriteLine("Hi time {0}",DateTime.Now), TimeSpan.FromMinutes(Interval), cancellation.Token).Wait();
Console.WriteLine("Finish loop!!!");
}
public static async Task RepeatActionEvery(Action action, TimeSpan interval, CancellationToken cancellationToken)
{
while (true)
{
action();
Task task = Task.Delay(interval, cancellationToken);
try
{
await task;
}
catch (TaskCanceledException)
{
return;
}
}
}
}

Send Print job from PuTTY to Zebra ZXP 3 SDK (non.zpl printer)

What I have is a medical record database that is accessed via PuTTY (SSH client). The cards themselves will only have Client name, record number in a barcode format (still determining the barcode type to be used), and client registration date.
1) We can get the data output as .zpl for Zebra Barcode label printers or formats compatible with laser printers like HP or Brother in a RAW format.
2) What output WILL the ZXP 3 SDK accept?
3) Can the SDK be set up to wait for and accept data coming at it using a command line from something like RedMon?
The cards themselves will only have the printed data, no mag stripe, smart chips, laminates or anything like that.
Mahalo in advance.
I would not recommend using either RedMon nor the SDK, as neither are required for what you are trying to do, and they both are time-vampires. Instead, I would write a small Windows Forms application which listens on a TCP port to receive the print job and send it to the standard printer which uses the Zebra driver.
Have the MUMPS application send an XML document via the Remote Print support in VT100. The example I have been using is below:
^[[5i
<patient>
<name first="John" last="Smith" />
<mrn>A04390503</mrn>
<dob>1991-03-12</dob>
</patient>
^[[4i
Configure a printer on the windows client to redirect to TCP/IP:
Add Printer
Local printer
Create a new port
Standard TCP/IP Port
Hostname: 127.0.0.1
Port name: CardFormatter
Uncheck "Query the printer and automatically select the driver to use"
Device type: Custom
Protocol: Raw
Port: 9101
Driver: Generic / Text Only
Start the application at logon, and print from the server. The MUMPS application will send back the XML, which Putty prints to the Text printer, which gets sent to the C# application on localhost. The C# application interprets the XML and prints to the actual printer via the Zebra driver or SDK.
Note: This only assumes one interactive session per workstation. If you are using fast-user-switching or terminal services, further care must be taken to ensure things work properly.
Example App:
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new TrayApplicationContext());
}
}
}
TrayApplicationContext.cs
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
trayIcon.Dispose();
}
}
}
}
PrintHandler.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
namespace PassThroughPrinterTest
{
partial class PrintHandler : Form
{
public PrintHandler()
{
InitializeComponent();
}
public void HandlePrintData(object sender, PrintDataReceivedEventArgs args)
{
if (this.InvokeRequired)
{
this.Invoke(new EventHandler<PrintDataReceivedEventArgs>(HandlePrintData), sender, args);
return;
}
this.Show();
var sXml = Encoding.UTF8.GetString(args.PrintData);
this.PrintCard(XDocument.Parse(sXml));
this.Hide();
}
private void PrintCard(XDocument xDocument)
{
var nameElement = xDocument.Root.Element("name");
var lastName = nameElement.Attribute("last").Value;
var firstName = nameElement.Attribute("first").Value;
var mrn = xDocument.Root.Element("mrn").Value;
var printDoc = new PrintDocument()
{
PrinterSettings = new PrinterSettings()
{
PrinterName = "Adobe PDF"
},
DocumentName = "Patient ID Card"
};
var cardPaperSize = new PaperSize("Card", 337, 213) { RawKind = (int)PaperKind.Custom };
printDoc.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrinterSettings.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrintPage += (s, e) =>
{
var gfx = e.Graphics;
// print the text information
var fArial12 = new Font("Arial", 12);
gfx.DrawString(lastName, fArial12, Brushes.Black, new RectangleF(25, 25, 200, 75));
gfx.DrawString(firstName, fArial12, Brushes.Black, new RectangleF(25, 100, 200, 75));
// add a code39 barcode using a barcode font
// http://www.idautomation.com/free-barcode-products/code39-font/
// var fCode39 = new Font("IDAutomationHC39M", 12);
// gfx.DrawString("(" + mrn + ")", fArial12, Brushes.Black, new RectangleF(25, 200, 200, 75));
// or by using a barcode library
// https://barcoderender.codeplex.com/
// var barcode = BarcodeDrawFactory.Code128WithChecksum.Draw(mrn, 20, 2);
// gfx.DrawImage(barcode, 50, 200);
e.HasMorePages = false;
};
printDoc.Print();
}
}
}
PrintListener.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace PassThroughPrinterTest
{
sealed class PrintListener : IDisposable
{
private TcpListener listener;
public event EventHandler<PrintDataReceivedEventArgs> PrintDataReceived;
public PrintListener(int port)
{
this.listener = new TcpListener(IPAddress.Loopback, port);
this.listener.Start();
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
public void Dispose()
{
this.listener.Stop();
}
private void listener_AcceptClient(IAsyncResult iar)
{
TcpClient client = null;
bool isStopped = false;
try
{
client = this.listener.EndAcceptTcpClient(iar);
}
catch (ObjectDisposedException)
{
// this will occur in graceful shutdown
isStopped = true;
return;
}
finally
{
if (!isStopped)
{
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
}
Debug.Assert(client != null);
try
{
byte[] printData;
using (var clientStream = client.GetStream())
using (var buffer = new MemoryStream())
{
clientStream.CopyTo(buffer);
printData = buffer.ToArray();
}
OnPrintDataReceived(printData);
}
catch
{
// TODO: add logging and error handling for network issues or processing issues
throw;
}
finally
{
client.Close();
}
}
private void OnPrintDataReceived(byte[] printData)
{
var handler = PrintDataReceived;
if (handler != null)
{
handler(this, new PrintDataReceivedEventArgs(printData));
}
}
}
}
TrayApplicationContext.cs
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
listener.Dispose();
trayIcon.Dispose();
}
}
}
}
PrintDataReceivedEventArgs.cs
using System;
namespace PassThroughPrinterTest
{
class PrintDataReceivedEventArgs : EventArgs
{
public byte[] PrintData { get; set; }
public PrintDataReceivedEventArgs(byte[] data)
{
if (data == null)
throw new ArgumentNullException("data");
this.PrintData = data;
}
}
}

Categories

Resources