C# Multiple Ping start and overlap their Results - c#

I have created a code that will continously test the if the connection is available and is supposed to be able to change the IP and always needs to run so it can show in a notificion if the connection is available or not. I can execute it with no errors but when I click the send button again it starts another ping that will also put the results in the label box overlapping each other. I am open to all sugestions to fixing this.
private async void Button1_Click(object sender, EventArgs e) //send button
{
int unterbrechung = 0;
await Task.Delay(12);
//Erstellen Variablen
string value = (comboBox1.SelectedItem as dynamic).Value;
double laufzeit = 0;
double delayins = 0;
int delay = 1000;
int onetimebubble = 1; //Zum verhindern von wieder erscheinen der Warnmeldung
//Zum verhindern das MiniIcon ein weiterers mal zu ändern.
int onetimeminired = 0;
int onetimeminigreen = 0;
//Ping Variablen deklarieren und setzen
Ping pingSender = new Ping();
PingOptions options = new PingOptions
{
DontFragment = true
};
pingSender.SendAsyncCancel();
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 120;
unterbrechung = 1;
//Ping senden und bei fehler entsprechende meldung anzeigen
while (unterbrechung == 1)
{
try
{
//Ping ausführen und Ausgabe meldung
PingReply reply = pingSender.Send(value, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
labelOutput.Text = "Address :" + reply.Address.ToString() + " " + Environment.NewLine +
"Status :" + reply.Status + " " + Environment.NewLine +
"Laufzeit in s :" + laufzeit;
labelOutput.BackColor = System.Drawing.Color.Green;
//Reset der Variable
if (onetimeminigreen == 0)
{
//ändern Symbol + vorheriger test
minIcon.Icon = Properties.Resources.Symbol2;
onetimeminigreen = 1;
onetimeminired = 0;
}
if (onetimebubble == 0)
{
onetimebubble = 1;
}
}
}
catch(PingException)
{
//Reset Laufzeit
laufzeit = 0;
//ausgabe fehlermeldung
labelOutput.Text = "Address :" + value + " " + Environment.NewLine +
"Status :Failed" + Environment.NewLine +
"Laufzeit in s :" + laufzeit;
labelOutput.BackColor = System.Drawing.Color.Red;
await Task.Delay(10);
if (onetimeminired == 0)
{
//ändern Symbol + vorheriger test
minIcon.Icon = Properties.Resources.Symbol1;
onetimeminigreen = 0;
onetimeminired = 1;
}
if (onetimebubble == 1)
{
//ausgabe Warnmeldung + vorheriger test
minIcon.BalloonTipIcon = ToolTipIcon.Error;
minIcon.BalloonTipTitle = "Ping Failed!";
minIcon.BalloonTipText = "Sie haben keine verbindung zu ihrem Host";
minIcon.ShowBalloonTip(1000);
onetimebubble = 0;
}
}
//Ausführen delay
await Task.Delay(delay);
//erechnen des Delay in sekunden und laufzeit berechnung
delayins = delay / 1000;
laufzeit = laufzeit + delayins;
}
}
EDIT Forgot the Question. How do I change my programm in the way that if I click the button again it cancels all other pings I started before. that "unterbrechung" was something I tried to achieve that but failed.
Encapsulate pinging
As Fildor suggested I added a new class for the Ping that simply returns the result
public bool Ping(string ipaddress)
{
Ping pingSender = new Ping();
PingOptions options = new PingOptions
{
DontFragment = true
};
int timeout = 120;
pingSender.SendAsyncCancel();
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
try
{
PingReply reply = pingSender.Send(ipaddress, timeout, buffer, options);
if(reply.Status == IPStatus.Success)
{
return true;
}
else
{
return false;
}
}
catch (PingException)
{
return false;
}
}
METHOD PING AND UI CHANGES As Fildor also suggested I now added a method that will execute the ping and also the change the UI according to the Pings Result
private void ExecPingAndChangeUI()
{
runtime = 0; //reset runtime
delayins = interval / 1000; // umwandeln in Sekunden
if (comboBox1.SelectedItem != null) //Überprüfen ob ein Element in der Combobox ausgewählt wurde
{
value = (comboBox1.SelectedItem as dynamic).Value; //Auslesen der Combobox
status = Ping(value); //Auslesen des Ping ergebnisses
if (status == true)
{
//Ausgabe an OutputLabel
labelOutput.Text = "Address : " + Environment.NewLine + value + Environment.NewLine + Environment.NewLine +
"Status : " + Environment.NewLine + "Success" + Environment.NewLine + Environment.NewLine +
"Laufzeit in s: " + Environment.NewLine + runtime + "s";
labelOutput.BackColor = System.Drawing.Color.Green;
if (minIcon.Icon != Properties.Resources.Symbol2) //ändern Symbol + Test ob symbol schon das ausgewählte ist
{
minIcon.Icon = Properties.Resources.Symbol2;
}
if (onetimebubble == false)
{
onetimebubble = true;
}
runtime = runtime + delayins; //laufzeit berechnung
}
else if (status == false)
{
runtime = 0; //Reset Laufzeit
//Ausgabe an OutputLabel
labelOutput.Text = "Address : " + Environment.NewLine + value + Environment.NewLine + Environment.NewLine +
"Status : " + Environment.NewLine + "Failed" + Environment.NewLine + Environment.NewLine +
"Laufzeit in s: " + Environment.NewLine + runtime + "s";
labelOutput.BackColor = System.Drawing.Color.Red;
if (minIcon.Icon != Properties.Resources.Symbol1) //ändern Symbol + vorheriger test
{
minIcon.Icon = Properties.Resources.Symbol1;
}
if (onetimebubble == true) //ausgabe Warnmeldung + vorheriger test
{
minIcon.ShowBalloonTip(1000);
onetimebubble = false;
}
runtime = runtime + delayins; //laufzeit berechnung
}
}
else
{
labelOutput.Text = "Bitte ein Element auswählen!"; //falls nichts in der Combobox ausgewählt wurde
}
}

I would like to recommend a "little" refactoring of that code:
Encapsulate pinging
Write a class that has only one purpose: Send a ping and return the result.
If the Ping class is a high enough abstraction for you, I would make an instance a private class property, that will be configured by the method of point 1 in next paragraph.
Introduce a Timer
Since you want to do recurring ping, it seems reasonable to use a Timer for that. This implies following steps:
Have a method that uses above mentioned ping class to execute the ping and updates the UI according to the delivered result. It should gather all needed information to execute the ping ( target, data ... ) so you can change ping target on the fly and it will be reflected accordingly when the next tick fires.
Change the contents of the button_click handler and the containing class as such:
2.1. have a property of type Timer. (default = null)
2.2. on button click:
2.2.1. check if timer property is not null:
True - stop timer and null property ( = stop pinging ),
False - go on
2.2.2. Create a Timer , set timer property to reference that and start it. The timer's tick shall execute the method of point 1.
Remarks
You may want to have a second button to explicitly stop pinging without starting a new ping. Hint: You could use a ToggleButton and use its state information to decide whether to start or stop pinging.
Note: The timer may execute it's tick handler (method from point 1.) on a separate thread depending on what timer implementation you use. So you may need to marshal UI-Updates to the UI thread. There are several possible methods to do that. I advise you to do the research yourself, as you stated you are a novice coder. You will learn a lot in the course.
Also, you may want to make sure that when the timer fires a tick, the last ping has returned (so they won't overlap).
Note: In order to improve this answer, I will add some references for you to start with later, when I'm at home.
Timer: see https://msdn.microsoft.com/en-us/library/system.windows.forms.timer(v=vs.110).aspx (Code example inside)

You can add a line of code at the beginning and at the end of your method to enable/disable
private async void Button1_Click(object sender, EventArgs e)
{
Button1.Enabled = false;
....
....
....
Button1.Enabled = true;
}
This should work fine with async/await.

Related

How to fix issue of zkemkeeper.dll realtime events inside windows service?

i'm setting up windows service and want it to sync the device attendance to SQL Server database using zkemkeeper real time event. i have successfully created service as well as tested the service on my local system which run windows 10 and another one window 8 service work fine and sync the attendance record to DB server at real time. Now after successful testing on local system i deployed service over production server where service successfully established the connection with device but it didn't respond to Real time event for testing purpose i have created winform app and run it over the server and find out it is working and listening to real time event but i need service to work properly not win form application any help will be appreciated thanks below is my code !
public partial class AttendanceSyncService_405 : ServiceBase
{
public AttendanceSyncService_405()
{
InitializeComponent();
}
System.Timers.Timer timer = new System.Timers.Timer();
public zkemkeeper.CZKEMClass axCZKEM1 = new zkemkeeper.CZKEMClass();
private bool bIsConnected = false;//the boolean value identifies whether the device is connected
private int iMachineNumber = 1;//the serial number of the device.After connecting the device ,this value will be changed.
protected override void OnStart(string[] args)
{
//var thread = new Thread();
//thread.SetApartmentState(ApartmentState.STA);
//thread.Start();
WriteToFile("Service is started at " + DateTime.Now);
Connect();
// LoadCurrentMonthAtt();
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 900000; //number in milisecinds
timer.Enabled = true;
}
protected override void OnStop()
{
WriteToFile("Service is stopped at " + DateTime.Now);
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
if (bIsConnected == true)
{
WriteToFile("Service recall at " + DateTime.Now);
WriteToFile("Device Status Connected at " + DateTime.Now);
}
else
{
WriteToFile("Device Status DisConnected at " + DateTime.Now);
WriteToFile("Service recall at " + DateTime.Now);
Connect();
}
}
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);
}
}
}
private void Connect()
{
try
{
int idwErrorCode = 0;
bIsConnected = axCZKEM1.Connect_Net("192.168.0.177", 4370);
if (bIsConnected == true)
{
this.axCZKEM1.OnAttTransactionEx += new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(axCZKEM1_OnAttTransactionEx);
iMachineNumber = 1;
if (axCZKEM1.RegEvent(iMachineNumber, 65535))//Here you can register the realtime events that you want to be triggered(the parameters 65535 means registering all)
{
this.axCZKEM1.OnAttTransactionEx += new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(axCZKEM1_OnAttTransactionEx);
}
else
{
WriteToFile("RT Events didn't registered at " + DateTime.Now);
}
axCZKEM1.RegEvent(iMachineNumber, 65535);//Here you can register the realtime events that you want to be triggered(the parameters 65535 means registering all)
WriteToFile("Device Connection Established Successfully at " + DateTime.Now);
}
else
{
axCZKEM1.GetLastError(ref idwErrorCode);
WriteToFile("Unable to connect the device,ErrorCode=" + idwErrorCode.ToString() + " at " + DateTime.Now);
}
}
catch(Exception ex)
{
WriteToFile("Exception :" + ex.Message + " at " + DateTime.Now);
}
}
private void axCZKEM1_OnAttTransactionEx(string sEnrollNumber, int iIsInValid, int iAttState, int iVerifyMethod, int iYear, int iMonth, int iDay, int iHour, int iMinute, int iSecond, int iWorkCode)
{
DateTime Attendancedate = new DateTime(iYear, iMonth, iDay, iHour, iMinute, iSecond);
string row = sEnrollNumber + "," + Attendancedate.ToString();
WriteToFile("Attendane :" + row + " Marked At: " + DateTime.Now);
if (bIsConnected == false)
{
Connect();
return;
}
decimal empserial = decimal.Parse(sEnrollNumber);
attInsert(empserial, Attendancedate);
}
private void attInsert(decimal empserial, DateTime Attendancedate)
{
try
{
WriteToFile("Attendance Entry Arrived for EMP-Serial :" + empserial + " At: " + DateTime.Now + " for Insertion");
DBAccess db = new DBAccess();
DataSet attCount = db.GetDataSetFromQuery("select Count(att.[todayCount]) as attCount from tblAttendance att where (att.attDate = Convert(date,GETDATE()) AND att.fkSerial ='" + empserial.ToString() + "')");
int count = int.Parse(attCount.Tables[0].Rows[0]["attCount"].ToString());
Boolean INOUT = (count % 2 == 0) ? true : false;
WriteToFile("Attendane Count :" + count + " & In/Out : " + INOUT + " Marked At: " + DateTime.Now);
db.Parameters.AddWithValue("fkSerial", empserial);
db.Parameters.AddWithValue("attTerminalId", "Time1");
db.Parameters.AddWithValue("attDateTime", Attendancedate);
db.Parameters.AddWithValue("attTgId", 3);
db.Parameters.AddWithValue("attINOUT", INOUT);
db.Parameters.AddWithValue("attEmpCode", "no need");
db.ExecuteNonQuery("spInsertAttendance");
WriteToFile("Attendance Inserted of EMP-Serial :" + empserial + " At: " + DateTime.Now);
}
catch (Exception ex)
{
WriteToFile("Exception in insert method :" + ex.Message + " At: " + DateTime.Now);
}
}
}
Type This Code in Your IntializeComponent and it will respond to realtime events
private void InitializeComponent()
{
Thread createComAndMessagePumpThread = new Thread(() =>
{
axCZKEM1 = new zkemkeeper.CZKEMClass();
bool connSatus = axCZKEM1.Connect_Net(192.168.0.177, 4370);
if (connSatus == true)
{
this.axCZKEM1.OnAttTransactionEx -= new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(axCZKEM1_OnAttTransactionEx);
if (axCZKEM1.RegEvent(1, 65535))//Here you can register the realtime events that you want to be triggered(the parameters 65535 means registering all)
{
this.axCZKEM1.OnAttTransactionEx += new zkemkeeper._IZKEMEvents_OnAttTransactionExEventHandler(axCZKEM1_OnAttTransactionEx);
}
}
Application.Run();
});
createComAndMessagePumpThread.SetApartmentState(ApartmentState.STA);
createComAndMessagePumpThread.Start();
components = new System.ComponentModel.Container();
this.ServiceName = "Service1";
}

Best way to handle changing nodes? - C# File Watcher and Clustered File Server

We recently went to a CSVFS clustered file server. I have a file watcher that's monitoring 4 directories for OnCreated and OnRenamed events but whenever the node changes, it causes a buffer overflow with the error
Too many changes at once in directory
The the watchers are automatically restarted and the process continues to work but begins writing errors when the OnCreated/OnRenamed events are fired.
Cannot access a disposed object.
Object name: 'FileSystemWatcher'.
at System.IO.FileSystemWatcher.StartRaisingEvents()
at System.IO.FileSystemWatcher.set_EnableRaisingEvents(Boolean value)
In the OnCreated method below, if I was to do this, should it work?
watchit = source as FileSystemWatcher;
I don't actually assign the newly created FileSystemWatcher to watchit anywhere else.
More details/code
The watchers are created via a foreach loop when the process initially starts. FileChange is simply a method that determines the type of change, does a bit of work, then triggers the correct action for the change type.
foreach (string subDir in subDirs)
{
string localFolder = $"{subDir}";
watchit = new FileSystemWatcher
{
Path = localFolder,
EnableRaisingEvents = true,
IncludeSubdirectories = false,
NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime,
Filter = watchFor,
InternalBufferSize = 65536,
SynchronizingObject = null //,
};
watchit.Changed += FileChange;
watchit.Created += FileChange;
watchit.Deleted += FileChange;
watchit.Renamed += OnRename;
watchit.Error += OnError;
watchit.EnableRaisingEvents = true;
watchers.Add(watchit);
Console.WriteLine($"watching {subDir} for {watchFor}");
}
watchit is a static FileSystemWatcher set globally.
private static async Task<int> OnCreated<T>(object source, FileSystemEventArgs e, string ext)
{
int insertResult = 0;
try
{
watchit.EnableRaisingEvents = false;
EventLogWriter.WriteEntry("File: " + e.FullPath + " " + e.ChangeType);
Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType + " " + DateTime.Now);
insertResult = await FileHandler.FileHandlers().ConfigureAwait(false);
watchit.EnableRaisingEvents = true;
// if (insertResult > 0) File.Delete(e.FullPath);
}
catch (Exception ex)
{
Logger.Trace($"{ex.Message} {ex.StackTrace} {ex.InnerException}");
EventLogWriter.WriteEntry($"{ex.Message} {ex.StackTrace} {ex.InnerException}",
EventLogEntryType.Error);
watchit.EnableRaisingEvents = true;
}
finally
{
watchit.EnableRaisingEvents = true;
}
return insertResult;
}
These are my error handling methods.
private static void OnError(object source, ErrorEventArgs e)
{
if (e.GetException().GetType() == typeof(InternalBufferOverflowException))
{
EventLogWriter.WriteEntry($"Error: File System Watcher internal buffer overflow at {DateTime.Now}", EventLogEntryType.Warning);
}
else
{
EventLogWriter.WriteEntry($"Error: Watched directory not accessible at {DateTime.Now}", EventLogEntryType.Warning);
}
MailSend.SendUploadEmail($"ASSIST NOTES: {e.GetException().Message}", "The notes service had a failure and should be restarted.", "admins", e.GetException(), MailPriority.High);
NotAccessibleError(source as FileSystemWatcher, e);
}
/// <summary>
/// triggered on accessible error.
/// </summary>
/// <param name="source">The source.</param>
/// <param name="e">The <see cref="ErrorEventArgs"/> instance containing the event data.</param>
private static void NotAccessibleError(FileSystemWatcher source, ErrorEventArgs e)
{
EventLogWriter.WriteEntry($"Not Accessible issue. {e.GetException().Message}" + DateTime.Now.ToString("HH:mm:ss"));
int iMaxAttempts = 120;
int iTimeOut = 30000;
int i = 0;
string watchPath = source.Path;
string watchFilter = source.Filter;
int dirExists = 0;
try
{
dirExists = Directory.GetFiles(watchPath).Length;
}
catch (Exception) { }
try
{
while (dirExists == 0 && i < iMaxAttempts)
{
i += 1;
try
{
source.EnableRaisingEvents = false;
if (!Directory.Exists(source.Path))
{
EventLogWriter.WriteEntry(
"Directory Inaccessible " + source.Path + " at " +
DateTime.Now.ToString("HH:mm:ss"));
Console.WriteLine(
"Directory Inaccessible " + source.Path + " at " +
DateTime.Now.ToString("HH:mm:ss"));
System.Threading.Thread.Sleep(iTimeOut);
}
else
{
// ReInitialize the Component
source.Dispose();
source = null;
source = new System.IO.FileSystemWatcher();
((System.ComponentModel.ISupportInitialize)(source)).BeginInit();
source.EnableRaisingEvents = true;
source.Filter = watchFilter;
source.Path = watchPath;
source.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime;
source.Created += FileChange;
source.Renamed += OnRename;
source.Error += new ErrorEventHandler(OnError);
((System.ComponentModel.ISupportInitialize)(source)).EndInit();
EventLogWriter.WriteEntry(
$"Restarting watcher {watchPath} at " + DateTime.Now.ToString("HH:mm:ss"));
dirExists = 1;
}
}
catch (Exception error)
{
EventLogWriter.WriteEntry($"Error trying Restart Service {watchPath} " + error.StackTrace +
" at " + DateTime.Now.ToString("HH:mm:ss"));
source.EnableRaisingEvents = false;
System.Threading.Thread.Sleep(iTimeOut);
}
}
//Starts a new version of this console appp if retries exceeded
//Exits current process
var runTime = DateTime.UtcNow - Process.GetCurrentProcess().StartTime.ToUniversalTime();
if (i >= 120 && runTime > TimeSpan.Parse("0:00:30"))
{
Process.Start(Assembly.GetExecutingAssembly().Location);
Environment.Exit(666);
}
}
catch (Exception erw) { }
}
You are trying to do too much work in the FileSystemWatcher events. The watchers are backed by unmanaged buffers that need to be emptied as quickly as possible to keep up with changes.
Ideally, all the events should be doing is reading some very basic data, like the path that was changed, and the type of change, and throwing that in to queue to be processed on another thread. That other thread can do the heavy lifting, since it won't be blocking the unmanaged change buffer.

How to get the newly opened apps WPF

Is there any way to get the newly open apps? I have a function that gets the running apps every 10 seconds, place them on a listbox and sends them to the other window if you click the send button.
What I wanted to happen is to get the newly opened app and send it to the other window. For example:
for the first 10 secs, I have opened notepad and chrome, after clicking send, those two will be sent to the other window. For the next 10 secs, I opened another app which is firefox. So my opened apps are now notepad, chrome and firefox so when I click send, I only want firefox to be sent to the other window so it wouldn't be redundant. Is this even possible?
There's the codes, in case if it brings of any help.
private void SendData()
{
String processID = "";
String processName = "";
String processFileName = "";
String processPath = "";
string hostName = System.Net.Dns.GetHostName();
listBox1.BeginUpdate();
try
{
for (int i = 0; i < listBox1.Items.Count; i++)
{
piis = GetAllProcessInfos();
try
{
processID = piis[i].Id.ToString();
processName = piis[i].Name.ToString();
processFileName = piis[i].FileName.ToString();
processPath = piis[i].Path.ToString();
output.Text += "\n\nSENT DATA : \n\t" + processID + "\n\t" + processName + "\n\t" + processFileName + "\n\t" + processPath + "\n";
}
catch (Exception ex)
{
wait.Abort();
output.Text += "Error..... " + ex.StackTrace;
}
NetworkStream ns = tcpclnt.GetStream();
String data = "";
data = "--++" + " " + processID + " " + processPath + " " + processFileName + " " + hostName;
if (ns.CanWrite)
{
byte[] bf = new ASCIIEncoding().GetBytes(data);
ns.Write(bf, 0, bf.Length);
ns.Flush();
}
}
}
finally
{
listBox1.EndUpdate();
}
}
Store the Id of previously sent processes in a list and only send the process info of a process if it's id is not in the list.
private List<int> listedProcesses = new List<int>();
//...
try
{
if(!listedProcesses.Contains(piis[i].Id)
{
listedProcesses.Add(piis[i].Id);
processID = piis[i].Id.ToString();
processName = piis[i].Name.ToString();
processFileName = piis[i].FileName.ToString();
processPath = piis[i].Path.ToString();
output.Text += "\n\nSENT DATA : \n\t" + processID + "\n\t" + processName + "\n\t" + processFileName + "\n\t" + processPath + "\n";
}
}
//...
Also: when you close processes these two lines will no longer be valid:
for (int i = 0; i < listBox1.Items.Count; i++)
{
piis = GetAllProcessInfos();
Because the number of processes can now be lower than the number of items in the listbox.
To keep them in sync you will also have to remove items from the listbox when processes are closed.
To fix it even more efficient (and easier) you could simply clear the listbox and add a new item for each process returned by GetAllProcessInfos();
Have a hook as described here: How to hook into application and process startup in windows?
using System.Management;
// Run this in another thread and make sure you dispose the event watcher before exit
var start = new ManagementEventWatcher(new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
start.EventArrived += new EventArrivedEventHandler(delegate (object sender, EventArrivedEventArgs e) {
console.WriteLine("Name: {0}, Command Line: {1}", e.NewEvent.Properties["ProcessName"].Value, e.NewEvent.Properties["Commandline"].Value);
});
start.Start()

Windows Services (error 1053) event log trigger

I am new to programming and I have this project due on coming Tuesday. What I am trying to do is if a user enters a wrong password on the logon screen the cam takes the picture. I tried to implement my code in services but it gives me error 1053. I was wondering if somebody could fix this code for me or if file watcher is of use in my code. Please help!
namespace SampleWS
{
public partial class Service1 : ServiceBase
{
private WebCam camera;
public Service1()
{
InitializeComponent();
}
public void OnDebug()
{
OnStart(null);
}
protected virtual void OnPause(string[] args)
{
bool infinite = false;
LogonChecker(infinite);
}
protected virtual void OnContinue(string[] args)
{
bool infinite = true;
LogonChecker(infinite);
}
protected override void OnStart(string[] args)
{
bool infinite = true;
LogonChecker(infinite);
}
protected override void OnStop()
{
bool infinite = false;
LogonChecker(infinite);
}
DateTime mytime = DateTime.MinValue;
public void LogonChecker(bool infinity)
{
string queryString =
"<QueryList>" +
" <Query Id=\"\" Path=\"Security\">" +
" <Select Path=\"Security\">" +
" *[System[(Level <= 0) and" +
" TimeCreated[timediff(#SystemTime) <= 86400000]]]" +
" </Select>" +
" <Suppress Path=\"Application\">" +
" *[System[(Level = 0)]]" +
" </Suppress>" +
" <Select Path=\"System\">" +
" *[System[(Level=1 or Level=2 or Level=3) and" +
" TimeCreated[timediff(#SystemTime) <= 86400000]]]" +
" </Select>" +
" </Query>" +
"</QueryList>";
camera = new WebCam();
while (infinity)
{
EventLogQuery eventsQuery = new EventLogQuery("Security", PathType.LogName, queryString);
eventsQuery.ReverseDirection = true;
EventLogReader logReader = new EventLogReader(eventsQuery);
EventRecord eventInstance;
Int32 eventexists3 = new Int32();
EventLog mylog = new EventLog();
for (eventInstance = logReader.ReadEvent(); null != eventInstance; eventInstance = logReader.ReadEvent())
{
eventexists3 = eventInstance.Id.CompareTo(4625);
if (eventexists3 == 0)
{
if (eventInstance.TimeCreated.Value > mytime)
{
mytime = eventInstance.TimeCreated.Value;
camera.Connect();
Image image = camera.GetBitmap();
image.Save(#"D:\Audio\testimage3.jpg");
camera.Disconnect();
eventInstance = null;
break;
}
}
EventLogRecord logRecord = (EventLogRecord)eventInstance;
LogonChecker(infinity);
}
}
}
}
}
Despite my comment, this is easy. Check what the error 1053 means:
ERROR_SERVICE_REQUEST_TIMEOUT
1053 (0x41D)
The service did not respond to the start or control request in a timely fashion.
Your overrides of ServiceBase methods like OnStart need to return as soon as possible. If you want to perform any ongoing work either subscribe to events or spin up a worker thread.
The .NET documentation on MSDN doesn't really cover much about the execution model of services, for this you need to look at the Win32 documentation: About Services.

I get a lot of noise over the serial port in C # only when you run the program on 64-bit PCs

I apologize for my English.
I'm building an application in C# that works with a serial port.
I used the DataReceived event to capture the data that sends a hadware external, in the event handler DataReceived I used the method ReadExisting to capture the the data sent by external hardware.
When I test the application with 32-bit computers all goes very well, but when I test it with 64-bit computers, approximately every 200 or 400 milliseconds the event DataReceived is triggered and the data returned by the method ReadExisting are many, question marks (?????????????)
Nota: para la comunicacion del hadware externo con el pc, yo utilizo conversor de puerto serial a usb == [Conversor]http://www.twistedtienda.com/images/prod/usbrs232-1.jpg
This is the method I use to create the com port:
private void CrearPuerto()
{
if (srpComunicacion == null)
{
srpComunicacion = new System.IO.Ports.SerialPort();
srpComunicacion.BaudRate = Globales.BaudiosPuertoCom;
srpComunicacion.Parity = System.IO.Ports.Parity.None;
srpComunicacion.DiscardNull = false;
srpComunicacion.StopBits = System.IO.Ports.StopBits.One;
srpComunicacion.DataBits = 8;
srpComunicacion.DtrEnable = false;
srpComunicacion.ParityReplace = 63;
srpComunicacion.ReadBufferSize = 4096;
srpComunicacion.ReadTimeout = 3000;
srpComunicacion.ReceivedBytesThreshold = 4;
srpComunicacion.RtsEnable = false;
srpComunicacion.WriteBufferSize = 2048;
srpComunicacion.WriteTimeout = -1;
srpComunicacion.Handshake = System.IO.Ports.Handshake.None;
srpComunicacion.DataReceived +=(a,b)=>{
System.IO.Ports.SerialPort srp = ((System.IO.Ports.SerialPort)a);
if ( System.Threading.Monitor.TryEnter(srp,1000) )
{
try
{
DatosImpresion d = new GenerarTurno().GenerarTurno1(((System.IO.Ports.SerialPort)a).ReadExisting(), true);
if (d != null && Globales.MostrarNotificacion[Globales.MostrarNotificacion.Length - 1])
notifyIcon1.ShowBalloonTip(10000, "Informacion del Turno Generado", "Turno " + d.Turno + " del Grupo " + d.Grupo + "\r\nRango : " + d.RangoIni + " - " + d.RangoFin + "\r\nTurnos en Espera : " + d.TurnoEspera + "\r\nTaquillas Principales : " + d.Taquillas, ToolTipIcon.Info);
}
catch (Exception ex)
{
try
{
bool errorDeRed = ex.ErrorDeRedToString();
if (ex.GetType().Name.ToLower().Equals("exception") || errorDeRed)
{
PrintDocument pr = new PrintDocument();
pr.PrinterSettings.PrinterName = Globales.RutaImpresora;
if (pr.PrinterSettings.IsValid)
{
RawPrinterHelper.SendStringToPrinter(Globales.RutaImpresora, (errorDeRed ? string.Format(Globales.ErrorRed, DateTime.Now.ToLongDateString(), DateTime.Now.ToShortTimeString()) : ex.Message));
pr.Print();
}
}
}
catch (Exception exc) { ex = new Exception(ex.ToString(), exc); }
Herramientas.Genericas.AdminErrores.GenerarLogErrores("srpComunicacion_DataReceived -- " + ex.ToString());
}
finally
{
System.Threading.Monitor.Exit(srp);
}
}
if (++recolectar >= 10)
{
recolectar = 0;
ClsGenerica.ForzarRecolector();
Application.DoEvents();
}
};
}

Categories