ManagementEventWatcher character limit? - vb.net

I'm trying to use eventwathcer but its not working with 11 characters process name (AbcdEfghIII.exe). If I write 10 characters process name (AbcdEfgIII.exe) its working. Is there character limit or am I doing something wrong? Here is my code:
Imports System.Management
Public Class Form1
Dim WithEvents StopWatch As New ManagementEventWatcher(New WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace"))
Private Sub StopWatch_EventArrived(ByVal sender As Object, ByVal e As System.Management.EventArrivedEventArgs)
If e.NewEvent.Properties("ProcessName").Value.ToString = "AbcdEfghIII.exe" Then
MsgBox("Closed")
End If
End Sub
Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
StopWatch.Stop()
RemoveHandler StopWatch.EventArrived, AddressOf StopWatch_EventArrived
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
AddHandler StopWatch.EventArrived, AddressOf StopWatch_EventArrived
StopWatch.Start()
Catch g As Exception
MsgBox("Please, run as admin.", MsgBoxStyle.Critical, "Error")
Me.Close()
End Try
End Sub
End Class

As there doesn't seem to be a way to make this work properly, I suppose you'll just have to use a hacky workaround: Checking if the process name starts with Customization.
Doing so will of course make it react to processes like CustomizationWHATEVER.exe, but since the code you're using for some reason doesn't return the full name there is no other way if you want it to work.
Using your initial code:
If check.StartsWith("Customization", StringComparison.OrdinalIgnoreCase) Then
MessageBox.Show("Closed")
End If
PREVIOUS ANSWER:
Here is a workaround:
Get the ProcessID field instead of ProcessName, and use that together with Process.GetProcessById() to get a .NET friendly Process class instance (from which you can extract the name).
Private Sub StopWatch_EventArrived(ByVal sender As Object, ByVal e As System.Management.EventArrivedEventArgs)
Dim PID As Integer = CType(CType(e.NewEvent.Properties("ProcessID").Value, UInteger) And Integer.MaxValue, Integer)
Dim p As Process = Process.GetProcessById(PID)
'NOTE: The ".exe" part is excluded in Process.ProcessName.
If String.Equals(p.ProcessName, "Customization", StringComparison.OrdinalIgnoreCase) Then
MessageBox.Show("Closed")
End If
End Sub

Related

Where to add the code for the regular expression to ensure that only numbers are accepted [duplicate]

This question already has answers here:
How do I make a textbox that only accepts numbers?
(41 answers)
Closed 8 years ago.
I am trying to add regular expression to the code below to ensure that only numbers are accepted. The code is very basic it calculates the area of a square and put the result in a RichTextBox.Text
I am using VB Visual Studio 2012. Any help will be greatly appreciated.
------------------------------------------------------
Public Class SquareArea
Inherits ShapeArea
Public Overrides Function Area() As Double
Return (Me.Lengh ^ 2)
End Function
End Class
------------------------------------------------------------
Public Class Square
Private Sub Square_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub ResultButton_Click(sender As Object, e As EventArgs) Handles ResultButton.Click
Dim area = New SquareArea
area.Lengh = SideTextBox.Text
ResultRichTextBox.Text = area.Area()
End Sub
Private Sub CloseSquareButton_Click(sender As Object, e As EventArgs) Handles CloseSquareButton.Click
Me.Close()
End Sub
End Class
There are several ways of doing this. But the best would be to use the Validating Event of the SideTextBox textbox.
Private Sub SideTextBox_Validating (ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles txtSideTextBox.Validating
'your code here
End Sub
or
You could also use its KeyPress Event so the user is prompted whenever they enter a non-numeric character.
Private Sub SideTextBox_KeyPress (ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtSideTextBox.KeyPress
'your code here
End Sub
Use this code...
Private Sub txtValue_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtValue.KeyPress
If Char.IsDigit(e.KeyChar) = False And Char.IsControl(e.KeyChar) = False Then
e.Handled = True
End If
End Sub
I don't usually write in Visual Basic but you are looking to add RegularExpression to your class as a Class Member (System.Text.RegularExpressions namespace). Regular Expression Pattern shown below will allow only digits. Calling the Match method on regex returns a Match class which you can call Success on for a Boolean result (true/false)
You may have to make slight changes as I don't normally write in VB, but the expression and class are correct
'Declare Regular Expression Class, Compile once
Dim RegularExpression regex As RegularExpression = New RegularExpression("^[0-9]*$", RegExOptions.Compile)
Private Sub Square_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub ResultButton_Click(sender As Object, e As EventArgs) Handles ResultButton.Click
Dim area = New SquareArea
' Insert Magic Here
If regex.Match(SideTextBox.Text).Success=False Then
MessageBox.Show("Invalid entry")
Return
End If
area.Lengh = SideTextBox.Text
ResultRichTe...
Private Sub CloseSquareButton_Click(sender As Object, e As EventArgs) Handles CloseSquareButton.Click
Me.Close()
End Sub
End Class

how to run a function/sub after loading the form window in VB?

I have a function that gets User ID from USB badge reader, used to log in an application.
when I run the app, the log in window does not appear until I swipe the tag.
I need to know if it`s possible to load the windows, then to start running the function that gets the data from the USB.
Thanks :)
Private Sub SerialPort1_DataReceived()
'Threading.Thread.SpinWait(1000)
OpenPort()
If SerialPort1.IsOpen() Then
byteEnd = SerialPort1.NewLine.ToCharArray
'read entire string until .Newline
readBuffer = SerialPort1.ReadLine()
readBuffer = readBuffer.Remove(0, 1)
readBuffer = readBuffer.Remove(8, 1)
WWIDTextBox.AppendText(readBuffer)
End If
End Sub
Private Sub Form1_Activated(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Activated
SerialPort1_DataReceived()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'SerialPort1_DataReceived()
End Sub
The problem is that you are calling the ReadLine method, which is a blocking (synchronous) method. In other words, when you call it, the method does not return the value until it has the value to return. Because of that, it stops execution on the current thread until a complete line is read (when the badge is swiped). Since you are on the UI thread when you call it, it will lock up the UI until the badge is swiped.
Instead of calling your SerialPort1_DataReceived method from the UI thread, you can do the work from a different thread. The easiest way to do that is to drag a BackgroundWorker component onto your form in the designer. Then you can add code like this:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
OpenPort()
If SerialPort1.IsOpen() Then
byteEnd = SerialPort1.NewLine.ToCharArray
Dim readBuffer As String = SerialPort1.ReadLine()
readBuffer = readBuffer.Remove(0, 1)
readBuffer = readBuffer.Remove(8, 1)
e.Result = readBuffer
End If
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
WWIDTextBox.AppendText(CStr(e.Result))
End Sub
Working on VS2013, I came across the same issue, I needed to to a datagridview refresh (colors in the gridrows). This worked for me.
Sub MyForm_VisibleChanged(sender As Object, e As EventArgs) Handles Me.VisibleChanged
If Me.Visible Then
'do action...
End If
End Sub
Try Form Activated Event
Private Sub Form1_Activated(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Activated
'Call your function here
End Sub
It call the function After the Form Loads...
Private Sub loadCombo()
Dim sqlconn As New OleDb.OleDbConnection
Dim connString As String
connString = ""
Dim access As String
access = "select slno from atable"
Dim DataTab As New DataTable
Dim DataAdap As New OleDbDataAdapter(access, connString)
DataAdap.Fill(DataTab)
ComboBox1.DataSource = DataTab
ComboBox1.DisplayMember = "slno"
End Sub

Iteration Not Working As Intended

I'm using a DO interation to loop a function I'm using to test for internet connectivity. The code is working fine, except that when one of the tests is satisfied the loop stops. I want this to continue in the background while the program is running. How can I get this to work?
Private Sub checkInternet()
Dim InetChecker As Boolean
InetChecker = CheckForInternetConnection()
Do While LabelCount.Text <> ""
Thread.Sleep(10)
If InetChecker = True Then
Dim image = My.Resources.greenbar
PictureBox4.Image = image
Else
Thread.Sleep(10)
Dim image = My.Resources.redbar
PictureBox4.Image = image
'NoInetConnError.Show()
End If
Loop
End Sub
Your assistance would be greatly appreciated, thanks.
Put a BackgroundWorker on your form (you will find it in the Components section of the Toolbox).
In the Properties window set WorkerReportsProgress to True for your BackgroundWorker.
Insert the following code to your form
Private connected As Boolean
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) _
Handles BackgroundWorker1.DoWork
While True
Dim online = CheckForInternetConnection()
If online <> connected Then
connected = online
BackgroundWorker1.ReportProgress(CInt(online))
End If
Thread.Sleep(500)
End While
End Sub
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) _
Handles BackgroundWorker1.ProgressChanged
Dim online As Boolean = CBool(e.ProgressPercentage)
If online Then
PictureBox4.Image = My.Resources.greenbar
Else
PictureBox4.Image = My.Resources.redbar
End If
End Sub
Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
' Start the background worker
BackgroundWorker1.RunWorkerAsync()
End Sub
Note that Sub BackgroundWorker1_DoWork runs on a separate thread and does not freeze your form while it is running.
It would be best to do something like this in a Timer and not in a loop.
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
If CheckForInternetConnection Then
PictureBox4.Image = My.Resources.greenbar
Else
PictureBox4.Image = My.Resources.redbar
End If
End Sub
If you have access to .Net framework 3+ then you could use the DispatcherTimer class which essentially creates an interval (set at whatever length you require) which you can handle the tick event for. When the tick event is raised, you can do your internet connection check.
Modifying the MSDN example for your situation, you could do something like this:
' DispatcherTimer setup
dispatcherTimer = New Threading.DispatcherTimer()
AddHandler dispatcherTimer.Tick, AddressOf dispatcherTimer_Tick
dispatcherTimer.Interval = New TimeSpan(0,0,1) ' Or however long you want
dispatcherTimer.Start()
Private Sub dispatcherTimer_Tick(ByVal sender As Object, ByVal e As EventArgs)
' Checks to see whether an internet connection is still available etc
checkInternet()
' Forcing the CommandManager to raise the RequerySuggested event
CommandManager.InvalidateRequerySuggested()
End Sub

Second form not showing value stored in first form when called

Hey all i am trying to figure out why my 2nd form is not displaying the value i recived in my first form.
The code for the first form is:
Private Sub scannerOnCom_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
responceBack = scannerOnCom.ReadLine
Call frm1110.clickButton(responceBack)
End Sub
The second form code is this:
Public Sub clickButton(ByRef theResponse As String)
txtNumber.Text = theResponse
'Call cmdNextFinish_Click(Nothing, Nothing)
End Sub
However, when i debug it to make sure there is something stored for theResponse, there is but for some reason it does not put it into the textbox. It's blank.
Any help would be great!
David
UPDATE
Ok so Form1:
Dim tmpForm3020 As New frm3020
Private Sub cmd3020_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmd3020.Click
tmpForm3020.Show()
Me.WindowState = FormWindowState.Minimized
End Sub
Private Sub scannerOnCom_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
responceBack = scannerOnCom.ReadLine
tmpForm3020.txtNumber.Text = responceBack
End Sub
If thats correct then i get an error on line:
xForm.txtNumber.Text = responceBack
Saying:
Cross-thread operation not valid: Control 'txtNumber' accessed from a thread other than the thread it was created on.
Are you explicitly creating an instance of your second form, or relying on the default instance? I.e. is "frm1110" the second form's class name, or an instance that you have new'd up? Make sure in either case that it is the same instance that is actually being displayed.
Dim tmpForm3020 As New frm3020
Private Sub cmd3020_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmd3020.Click
tmpForm3020.Show()
Me.WindowState = FormWindowState.Minimized
End Sub
Private Sub scannerOnCom_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
responceBack = scannerOnCom.ReadLine
TestData(responceBack)
End Sub
Private Sub TestData(ByVal xVal As String)
If InvokeRequired Then
Me.Invoke(New MethodInvoker(AddressOf TestData))
' change Me to tmpForm3020 (if it does not work)
' tmpForm3020.Invoke(New MethodInvoker(AddressOf TestData))
Else
tmpForm3020.txtNumber.Text = xVal
End If
End Sub

VB.NET PictureBox scroll through images in a folder

I have a pictureBox on my form along with two buttons (Back and Forward) but I can not find a viable method of doing what I wish to do: Scrolling through images in a folder like the default Windows Picture Viewer does with Arrow Keys.
Is there an efficient way to do this?
I'm using Visual Basic .NET with Visual Studio 2010, if that matters.
You'll need to load the pictures using DirectoryInfo, then browse through them with an index. Here is an example:
Public Class Form1
Private files As List(Of FileInfo)
Private currentFileIndex As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
RefreshFolder("c:\path\to\your\pictures")
End Sub
Private Sub backButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles backButton.Click
Advance(-1)
ShowCurrentFile()
End Sub
Private Sub forwardButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles forwardButton.Click
Advance(1)
ShowCurrentFile()
End Sub
Private Sub Advance(ByVal delta As Integer)
currentFileIndex = ((currentFileIndex + files.Count) + delta) Mod files.Count
End Sub
Private Sub RefreshFolder(ByRef path As String)
Dim di As DirectoryInfo = New DirectoryInfo(path)
files = (From c In di.GetFiles()
Where IsFileSupported(c)
Select c).ToList()
If files.Count > 0 Then
currentFileIndex = 0
End If
ShowCurrentFile()
End Sub
Private Sub ShowCurrentFile()
If currentFileIndex <> -1 Then
Try
PictureBox1.Image = Image.FromFile(files(currentFileIndex).FullName)
Catch ex As Exception
' TODO: handle exceptions gracefully
Debug.WriteLine(ex.ToString)
End Try
End If
End Sub
Private Function IsFileSupported(ByRef file As FileInfo) As Boolean
Return file.Extension = ".jpg" Or file.Extension = ".png" ' etc
End Function
End Class
you should be more specific.
if it will help you you have to create two subrotines that assign the next and pervious image to the picture box and triggier these subrotines on the key down events and the bottons clicks.