GRitchie Posted February 6, 2015 Posted February 6, 2015 (edited) Hello, I'm trying to create a loop for our system tray application to check if their system is backing up. So far I have this Private Sub BackupCheck_Tick(sender As Object, e As EventArgs) Handles BackupCheck.Tick If Diagnostics.Process.GetProcessesByName("SCHOOLNAMEBackup").Count = 1 Then NotifyIcon1.ShowBalloonTip("5000", "SCHOOLNAME Network Portal", "System backup started.", ToolTipIcon.Info) ElseIf Diagnostics.Process.GetProcessesByName("SCHOOLNAMEBackup").Count = 0 Then NotifyIcon1.ShowBalloonTip("5000", "SCHOOLNAME Network Portal", "System backup complete.", ToolTipIcon.Info) End If End Sub End Class It's not working quite right, but the basic idea is that: >Check every 10 seconds (the timer tick) if the process is running. >If so, show a tooltip 'started'. (if not start again) >When it stops show a tooltip 'stopped'. >end if - restart loop. Any ideas? Edited February 6, 2015 by GRitchie
LosOjos Posted February 6, 2015 Posted February 6, 2015 What isn't happening? On the face of it, this code only deals with the tooltip, no other calls are made here. If your timer is running, then every 10 seconds this will run, displaying a tooltip for 5 seconds - meaning the user will have a tooltip popup every 5 seconds! Is that what you want?
GRitchie Posted February 6, 2015 Author Posted February 6, 2015 What isn't happening? On the face of it, this code only deals with the tooltip, no other calls are made here. If your timer is running, then every 10 seconds this will run, displaying a tooltip for 5 seconds - meaning the user will have a tooltip popup every 5 seconds! Is that what you want? No it's not. I'm moving forward slowly, I think something like THIS is more what I'm looking for: Private Sub BackupCheck_Tick(sender As Object, e As EventArgs) Handles BackupCheck.Tick Dim BackupProc = Process.Start("C:\Backup\SCHOOLNAMEBackup.exe") If Diagnostics.Process.GetProcessesByName("SCHOOLNAMEBackup").Count = 1 Then NotifyIcon1.ShowBalloonTip("5000", "SCHOOLNAME Network Portal", "System backup started.", ToolTipIcon.Info) While Diagnostics.Process.GetProcessesByName("SCHOOLNAMEBackup").Count = 1 BackupProc.WaitForExit() End While ElseIf Diagnostics.Process.GetProcessesByName("SCHOOLNAMEBackup").Count = 0 Then NotifyIcon1.ShowBalloonTip("5000", "SCHOOLNAME Network Portal", "System backup complete.", ToolTipIcon.Info) End If End Sub End Class
LosOjos Posted February 6, 2015 Posted February 6, 2015 Problem is, doing this on a timer means you're now not only bombarding your user with tooltips, you're starting the process every 10 seconds too. I think you want to look at using the Process.Exited callback instead of a timer - this will get called when the process finishes running: https://msdn.microsoft.com/en-us/library/system.diagnostics.process.exited%28v=vs.110%29.aspx
GRitchie Posted February 6, 2015 Author Posted February 6, 2015 Problem is, doing this on a timer means you're now not only bombarding your user with tooltips, you're starting the process every 10 seconds too. I think you want to look at using the Process.Exited callback instead of a timer - this will get called when the process finishes running: https://msdn.microsoft.com/en-us/library/system.diagnostics.process.exited%28v=vs.110%29.aspx Yes that's the problem I want a tooltip when the application starts and a tooltip when it stops. I see the process.exited may be what I want but the process does not start from within the VB application itself (it's on a scheduled task within windows)
LosOjos Posted February 6, 2015 Posted February 6, 2015 You can actually get a pointer to an already running process, which in turn gives you a Process object you can watch for the Exited callback, should solve your problem - https://msdn.microsoft.com/en-us/library/z3w4xdc9%28v=vs.110%29.aspx So my flow would be: * start a timer * when timer ticks, collect process using GetProcessByName - no process? It isn't running, so exit. - got the process? Stop timer, assign Exited callback to it, popup tooltip * Exited gets called - pop up tooltip, release process, restart timer
GRitchie Posted February 6, 2015 Author Posted February 6, 2015 You can actually get a pointer to an already running process, which in turn gives you a Process object you can watch for the Exited callback, should solve your problem - https://msdn.microsoft.com/en-us/library/z3w4xdc9%28v=vs.110%29.aspx So my flow would be: * start a timer * when timer ticks, collect process using GetProcessByName - no process? It isn't running, so exit. - got the process? Stop timer, assign Exited callback to it, popup tooltip * Exited gets called - pop up tooltip, release process, restart timer I think that's exactly what I want. Could you help with the code for this?
LosOjos Posted February 6, 2015 Posted February 6, 2015 Sure, if you don't mind waiting until later? Once I get back home, I'll throw a sample application together for you and post up the code 1
GRitchie Posted February 6, 2015 Author Posted February 6, 2015 Sure, if you don't mind waiting until later? Once I get back home, I'll throw a sample application together for you and post up the code That would be brilliant! I won't be able to test it myself until Monday now mind, but I will be sure to reply either way. Thanks!
LosOjos Posted February 9, 2015 Posted February 9, 2015 (edited) I've knocked a little sample together for you, code below and project attached. Ended up doing it slightly differently as under inspection, it seems by default the Exited event only triggers for processes started from VB. The principle is still the same, it's just that we now manually add the event handler to the process once we capture it. One thing to note - make sure your NotifyIcon actually has an icon set, otherwise it will not display. Also, I tested using Notepad as my monitor process, change the PROCESS_NAME constant to whatever your backup process is called Imports System.Diagnostics Public Class Form1 Private Const PROCESS_NAME As String = "notepad" ' the name of the process Private Const BALLOON_TIMEOUT As Integer = 5000 ' time in millis to display balloon Private Const BALLOON_TITLE As String = "SCHOOLNAME Network Portal" ' title of the balloon Private Const BALLOON_STARTED As String = "System backup started." ' text to display when process starts Private Const BALLOON_FINISHED As String = "System backup complete." ' text to display when process exits Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick 'collect matching processes Dim runningProcesses As Process() = Process.GetProcessesByName(PROCESS_NAME) ' collecting processes by name means it's possible we might get multiple matches ' I will assume the first match is correct, however you may want to think ' about how to handle the event that more than one match is found. ' If the process is found, display a balloon to inform the user ' and stop the timer as there's no longer a need to monitor for new ' processes. We also add an event handler to the process's Exited ' event, so that we will get an interrupt when the process completes. If runningProcesses.Length > 0 Then runningProcesses(0).EnableRaisingEvents = True AddHandler runningProcesses(0).Exited, AddressOf p_Exited NotifyIcon1.ShowBalloonTip( _ BALLOON_TIMEOUT, _ BALLOON_TITLE, _ BALLOON_STARTED, _ ToolTipIcon.Info) Timer1.Stop() End If End Sub ' This event is triggered when the process we find on Timer_Tick is closed or ' otherwise exits for any reason. We will display a balloon to inform the user ' the process is complete, then restart the timer to continue monitoring ' for the process to be started again. Private Sub p_Exited(ByVal sender As Object, ByVal e As System.EventArgs) NotifyIcon1.ShowBalloonTip( _ BALLOON_TIMEOUT, _ BALLOON_TITLE, _ BALLOON_FINISHED, _ ToolTipIcon.Info) Timer1.Start() End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Timer1.Start() End Sub End Class EDIT: this is the first thing I've coded in VB.NET in about 10 years - bloody painful language! Notifier.zip Edited February 9, 2015 by LosOjos
GRitchie Posted February 9, 2015 Author Posted February 9, 2015 Hello, I've given that a shot this morning but there are some build errors. I've adjusted names for things that don't match up etc. and this is the result: The on hovers say: Handles clause requires a WithEvents variable defined in the containing type or one of its base types. AND Reference to a non-shared member requires an object reference. Any idea as to why this might be?
LosOjos Posted February 9, 2015 Posted February 9, 2015 Looks like your BackupCheck object is actually called BackupTimer (going off the Tick event's name), so change BackupCheck to BackupTimer. Also, check the name of your NotifyIcon, the underline suggests it's not called NotifyIcon1. Looking at where the highlighted errors are, that should fix it.
GRitchie Posted February 9, 2015 Author Posted February 9, 2015 It seems that the timer is called 'BackupCheck' under the properties of it, and the NotifyIcon is 'NotifyIcon1' FYI - I'm usually sensible with naming items, with this one I just decided not to bother.
LosOjos Posted February 9, 2015 Posted February 9, 2015 (edited) It seems that the timer is called 'BackupCheck' under the properties of it, and the NotifyIcon is 'NotifyIcon1' FYI - I'm usually sensible with naming items, with this one I just decided not to bother. I'm really not sure then - have you tried running the project I attached and if so, does that work? Which version of VS are you using? EDIT: are you absolutely certain about those object names? Everything points to them being wrong... also, have you just tried running it anyway? I noticed myself that the IDE seemed to be a little slow at times, but building/running the project caused a full update, clearing any no longer existing errors. Edited February 9, 2015 by LosOjos
GRitchie Posted February 9, 2015 Author Posted February 9, 2015 Your attached file works with no problem. I'm running VS Ultimate 2013.
LosOjos Posted February 9, 2015 Posted February 9, 2015 Your attached file works with no problem. I'm running VS Ultimate 2013. Is the code making up the body of the form that contains the NotifyIcon and Timer? If you want, I'll take a look at your project for you? If you don't want to post it here, PM me for my email address.
LosOjos Posted February 9, 2015 Posted February 9, 2015 Turns out there appears to be a bug in the implementation of Forms.Timer, meaning once stopped, it will not restart. So here's an updated version using Sytem.Timer instead: Imports System.Diagnostics Imports System.Timers Public Class Form1 Private Const PROCESS_NAME As String = "notepad" ' the name of the process Private Const BALLOON_TIMEOUT As Integer = 5000 ' time in millis to display balloon Private Const BALLOON_TITLE As String = "SCHOOLNAME Network Portal" ' title of the balloon Private Const BALLOON_STARTED As String = "System backup started." ' text to display when process starts Private Const BALLOON_FINISHED As String = "System backup complete." ' text to display when process exits Private Const TIMER_INTERVAL As Integer = 10000 ' time in milis to run each check for the process Private timer As New Timer() Private Sub timer_Elapsed(sender As Object, e As EventArgs) 'collect matching processes Dim runningProcesses As Process() = Process.GetProcessesByName(PROCESS_NAME) ' collecting processes by name means it's possible we might get multiple matches ' I will assume the first match is correct, however you may want to think ' about how to handle the event that more than one match is found. ' If the process is found, display a balloon to inform the user ' and stop the timer as there's no longer a need to monitor for new ' processes. We also add an event handler to the process's Exited ' event, so that we will get an interrupt when the process completes. If runningProcesses.Length > 0 Then runningProcesses(0).EnableRaisingEvents = True AddHandler runningProcesses(0).Exited, AddressOf p_Exited NotifyIcon1.ShowBalloonTip( _ BALLOON_TIMEOUT, _ BALLOON_TITLE, _ BALLOON_STARTED, _ ToolTipIcon.Info) timer.Stop() End If End Sub ' This event is triggered when the process we find on Timer_Tick is closed or ' otherwise exits for any reason. We will display a balloon to inform the user ' the process is complete, then restart the timer to continue monitoring ' for the process to be started again. Private Sub p_Exited(ByVal sender As Object, ByVal e As System.EventArgs) NotifyIcon1.ShowBalloonTip( _ BALLOON_TIMEOUT, _ BALLOON_TITLE, _ BALLOON_FINISHED, _ ToolTipIcon.Info) timer.Start() End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load AddHandler timer.Elapsed, AddressOf timer_Elapsed timer.Interval = TIMER_INTERVAL timer.Start() End Sub End ClassNotifier.zip 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now