Kill all processes in a listBox? (VB.NET) - vb.net

I'm trying to create a small productivity program to keep myself focused when programming; specifically, to close any processes that might distract me from doing my job. I'm writing it in VB.NET for simplicity.
What is the easiest way to kill all processes listed in a listBox? I already know how to add the processes to my listBox with this code:
Dim newProc As New OpenFileDialog
'// Settings for the open file dialog. (I like how I use ' to start the comment, but // so I recognize it! :)
newProc.Filter = "Executable files (*.exe)|*.exe"
newProc.FileName = "..choose a file.."
newProc.Multiselect = True
newProc.CheckFileExists = True
newProc.CheckPathExists = True
newProc.AutoUpgradeEnabled = True
newProc.AddExtension = True
If (newProc.ShowDialog = Windows.Forms.DialogResult.OK) Then
ListBox1.Items.AddRange(newProc.SafeFileNames)
End If
This adds the processes to the listBox very neatly and all, exactly how I want it. I have a timer that gets enabled with the press of a button that should close all processes in the listBox, but I'm unsure what I should use. Can I get some help? :(

Dim pProcess() As Process = System.Diagnostics.Process.GetProcessesByName("notepad")
For Each p As Process In pProcess
p.Kill()
Next
You can try the above. Please view this link for further infomation.

Related

Using Filewatcher for a progress bar with subdirectories, Wont Update Properly

I'm trying to copy Files from a local Computer to a Network device. I'm trying to get a Progress Bar working for the File copy, and got it working for a Single Directory with no Subdirectory:
Private Sub CopyPictures()
Try
If Not Directory.Exists(DestinationPath) Then
My.Computer.FileSystem.CreateDirectory(DestinationPath)
End If
Dim counterLocalFiles = My.Computer.FileSystem.GetFiles(SourcePath)
UpdateProgressBarMaximum1(CInt(counterLocalFiles.Count))
UpdateLabelText2(CStr(counterLocalFiles.Count)) 'is a label which shows copied X files of Label2 Files
fsw1 = New IO.FileSystemWatcher(DestinationPath)
fsw1.EnableRaisingEvents = True
My.Computer.FileSystem.CopyDirectory(SourcePath, DestinationPath)
GetSettingsFromFile()
Catch Exec As System.IO.IOException
Dim dr As DialogResult = MessageBox.Show("Some Random Error Code", "Exception Title", MessageBoxButtons.OKCancel)
If (Not DialogResult.OK = dr) Then
Exit Sub
Return
End If
End Try
End Sub
Private Sub fsw1_Created(sender As Object, e As FileSystemEventArgs) Handles fsw1.Created
Dim counterRemoteFiles = My.Computer.FileSystem.GetFiles(DestinationPath)
UpdateProgressBar1(CInt(counterRemoteFiles.Count))
UpdateLabelText1(CStr(counterRemoteFiles.Count))
End Sub
The Update ObjectX Subs are just invoke Functions since the CopyPictures is raised by a backgroundworker as well looking all like this one for example
Private Sub UpdateProgressBar1(Value As Int32)
If ProgressBar1.InvokeRequired Then
ProgressBar1.Invoke(New Action(Of Integer)(AddressOf UpdateProgressBar1), Value)
Else
'We are on the UI thread so update the control.
ProgressBar1.Value = Value
End If
End Sub
This code works perfectly fine for me, but I have to deal with SubDirectories which contain the Images, and the names of the subs are random so i cant predetermine them so I came up with slight changes:
The Counter is looking now like this:
Dim counterLocalFiles = System.IO.Directory.GetFiles(SourcePath, "*.jpg*", SearchOption.AllDirectories).Length
UpdateProgressBarMaximum1(CInt(counterLocalFiles))
UpdateLabelText2(CStr(counterLocalFiles))
And this:
Dim counterRemoteFiles = IO.Directory.GetFiles(DestinationPath, "*.jpg", SearchOption.AllDirectories).Length
UpdateProgressBar1(CInt(counterRemoteFiles))
UpdateLabelText1(CStr(counterRemoteFiles))
And I added:
fsw1.IncludeSubdirectories = True
Now the weired Problems started: It would properly count the file in the source Directory setting label2 to the correct amount of files in all subdirectories and then start copying. It would NOT update the Progressbar though in real time. It just updated it once when it was done with the first directory and just adding the amount of files to it which it contained. After that it completly stoppedd nored the second directory and didn't add that at all to the progressbar. What am I doing wrong here? I hope my english is fine, If you have any question or If I was not clear enough, please let me know. Thank you
You don't have an event consumer that triggers your progressbar update routine - you call it once when your filesystemwatcher is instantiated.
You need to declare an event that handles the copy event and fires off your progress update code. Because Filesystemwatcher cannot monitor network drives, you may want to declare an event that fires off your progress update method when the counterRemoteFiles count increments.
Turns out I just made a mistake with correctly putting the
fsw1.IncludeSubdirectories = True
I was setting it to true in the Form Editor instead of doing it in the code. Once i actually put that in the code after initialising the fsw, it would work just fine

Wait for UI to load new window before continuing

I am novice of VB.Net trying to create a plugin for a program with a fairly lacking API. Essentially what I am trying to accomplish is press a button in the interface, which will create a new window. Once this window loads, I have a couple other buttons to press to eventually print out an HTML file it generates.
I attempted to use Windows UI Automation, but was unable to manipulate the first control (it appeared as a "pane" element for some reason, and had no supported control patterns)
I eventually was able to use PostMessage to send a MouseDown and MouseUp message to the control to activate it.
My question is: What is the best way for me to wait for this window to finish loading before continuing my code execution?
I tried using Thread.Sleep after I sent the click to my control, but my code seemed to trigger the sleep before it even started to load the window. I suspect there may be some kind of event-driven options, but I don't even know where I would begin with that.
Side note: I do have access to the program's Process ID if that helps.
EDIT:
To be more explicit about what I have done, here is some code for you to look at:
' These variables declared further up in my program, when plugin is loaded
Private aeDesktop As AutomationElement
Private aeRadan As AutomationElement
Private aeBlocksBtn As AutomationElement
Private Sub UITest1()
Dim rpid As Integer
Dim intret As Integer
' Note: mApp is declared further up in the code, when the plug in initializes
' It sets a reference to the application object (API command from the software)
rpid = mApp.ProcessID
aeDesktop = AutomationElement.RootElement
Dim propcon As New PropertyCondition(AutomationElement.ProcessIdProperty, rpid)
Dim propcon2 As New PropertyCondition(AutomationElement.NameProperty, "big_button_blocks.bmp")
aeRadan = aeDesktop.FindFirst(TreeScope.Children, propcon)
aeBlocksBtn = aeRadan.FindFirst(TreeScope.Descendants, propcon2)
' MAKELONG is a function that concatenates given x and y coordinates into an appropriate "lparam" value for PostMessage.
' Coordinates 20, 20 are chosen arbitrarily
Dim lParam As Long = MAKELONG(20, 20)
intret = PostMessage(CInt(aeBlocksBtn.GetCurrentPropertyValue(AutomationElement.NativeWindowHandleProperty)), &H201, &H1, lParam)
intret = PostMessage(CInt(aeBlocksBtn.GetCurrentPropertyValue(AutomationElement.NativeWindowHandleProperty)), &H202, &H0, lParam)
Dim bwinprop As New PropertyCondition(AutomationElement.NameProperty, "Radan Block Editor")
Dim aeblockwin As AutomationElement
Dim numwaits As Integer = 0
Do
numwaits += 1
Thread.Sleep(100)
aeblockwin = aeRadan.FindFirst(TreeScope.Children, bwinprop)
Loop While (numwaits < 50) AndAlso (aeblockwin Is Nothing)
If numwaits >= 50 Then
MessageBox.Show("ERROR: Block Editor Window Not found")
End If
I am fairly sure what is happening has to do with the code moving to the Do While loop before the PostMessage is processed by the program. I have tried using SendMessage to try to bypass this, but unfortunately that does not seem to work.
I feel like there is a pretty simple solution here, like maybe some kind of alternate wait or sleep command that I don't know about, so maybe someone could help guide me to it?
EDIT 2:
Screenshot of the inspect.exe output for this control.
Also, a screenshot of the user interface. This is from Radan, a CAM software I use for nesting and processing sheet metal parts to be laser cut. I put a red box around the control I would like to activate.

VB 2013 Application Out of Memory

I'm new to VB but recently created my first working app :) Anyway it just compresses files and little bit more. The latest thing that I added was a marquee style progress bar to animate while the operation was in progress and stop when it ends and the user can do the next zip operation. The progress bar wasn't updating, so I used a background worker to do the actual task while the button click just did the animation. Since then I've notcied serious degredation in the app. It struggles to load. I even got an out of memory error. Not sure if the background worker is related, but I thought I'd mention as it was the last update. Has anyone experienced anything similar? If I can provide and specific info, please ask me for it! Many thanks.
UPDATE: So I understand that I'm not using the BGWorker correctly. I will change that. But I found even with that removed, I still had issues. So I created a new form and started adding in bits of my code one by one. Anyway, I fell at the first hurdle with my form load sub. So I added that in slowly. I found that when ever I have any statements that load a variable from settings for persistent settings that the app falls over. Below is my code. Can anyone see what's up?????
UPDATE: I've found that if I load from settings the memory useage shoots up. I tried this too with saving settins on form closed. Below is the error received. The same out of memory occurs when trying to load settings too. I never experienced this on the first form I created. So perhaps I have missed some settings on the second, because the implementation in the code hasn't changed.
System.Configuration.ConfigurationErrorsException: Failed to save settings: An error occurred executing the configuration section handler for userSettings/Backup_Tool.My.MySettings. ---> System.Configuration.ConfigurationErrorsException: An error occurred executing the configuration section handler for userSettings/Backup_Tool.My.MySettings. ---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown
This is when I added in the code below:
Private Sub Form1_Closed(sender As Object, e As EventArgs) Handles MyBase.FormClosed
' TAB PAGE 1.
' Save controls to settings.
My.Settings.StartPathTextBox1 = StartPathTextBox1.Text
My.Settings.ZipPathTextBox1 = ZipPathTextBox1.Text
My.Settings.CopyPathTextBox1 = CopyPathTextBox1.Text
My.Settings.ZipSelectCheckBox1 = ZipSelectCheckBox1.Checked
My.Settings.CopySelectCheckBox1 = CopySelectCheckBox1.Checked
For Each s As String In StartNameListBox1.Items()
My.Settings.StartNameListBoxItems1.Add(s)
Next
For Each s As String In StartNameListBox1.SelectedItems()
My.Settings.StartNameListBoxSelectedItems1.Add(s)
Next
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' FORM 1.
' Initialise specialised string collections.
If My.Settings.StartNameListBoxItems1 Is Nothing Then
My.Settings.StartNameListBoxItems1 = _
New System.Collections.Specialized.StringCollection
End If
If My.Settings.StartNameListBoxSelectedItems1 Is Nothing Then
My.Settings.StartNameListBoxSelectedItems1 = _
New System.Collections.Specialized.StringCollection
End If
' TAB PAGE 1.
' Restore controls from saved settings.
StartPathTextBox1.Text() = My.Settings.StartPathTextBox1
ZipPathTextBox1.Text() = My.Settings.ZipPathTextBox1
CopyPathTextBox1.Text() = My.Settings.CopyPathTextBox1
ZipSelectCheckBox1.Checked = My.Settings.ZipSelectCheckBox1
CopySelectCheckBox1.Checked = My.Settings.CopySelectCheckBox1
For Each s As String In My.Settings.StartNameListBoxItems1()
StartNameListBox1.Items.Add(s)
Next
For Each s As String In My.Settings.StartNameListBoxSelectedItems1()
StartNameListBox1.SelectedItems.Add(s)
Next
' Decide controls initial states.
If StartNameListBox1.SelectedItems.Count = 0 Then
ZipSelectCheckBox1.Enabled = False
RunButton1.Enabled = False
End If
If ZipSelectCheckBox1.Checked = False Then
ZipPathTextBox1.Enabled = False
ZipBrowseButton1.Enabled = False
End If
If ZipPathTextBox1.Text = String.Empty Then
CopySelectCheckBox1.Enabled = False
End If
If CopySelectCheckBox1.Checked = False Then
CopyPathTextBox1.Enabled = False
CopyBrowseButton1.Enabled = False
End If
End Sub
It appears to be that you are only ever adding the current selections to the Settings collections. You might well clear the ListBox when they make new selections, but you do not do the same thing with the Settings Collections like My.Settings.StartNameListBoxItems1:
For Each s As String In StartNameListBox1.Items()
My.Settings.StartNameListBoxItems1.Add(s)
Next
The collection will have all the items in it from all the other times it has ever run already and you are now going to add more to it. Eventually you will have many, many, many items in it.
My.Settings.StartNameListBoxItems1.Clear ' REMOVE ALL OLD ITEMS
' Save just the current items to the collection
For Each s As String In StartNameListBox1.Items()
My.Settings.StartNameListBoxItems1.Add(s)
Next
use .Clear on both Collections

Detect when exe is started vb.net

Dose anybody know how I can make my VB.net application wait until a process is detected as running?
I can find example of how to detect once an exe has finished running but none that detect when an exe is started?
You can use the System.Management.ManagementEventWatcher to wait for certain WMI events to occur. You need to give it a query type and condition to have it watch for the next creation of your process, then get it to do something when that occurs.
For example, if you want :
Dim watcher As ManagementEventWatcher
Public Sub Main()
Dim monitoredProcess = "Notepad.exe"
Dim query As WqlEventQuery = New WqlEventQuery("__InstanceCreationEvent", new TimeSpan(0, 0, 1), "TargetInstance isa ""Win32_Process"" And TargetInstance.Name = """ & monitoredProcess & """")
watcher = New ManagementEventWatcher()
watcher.Query = query
'This starts watching asynchronously, triggering EventArrived events every time a new event comes in.
'You can do synchronous watching via the WaitForNextEvent() method
watcher.Start()
End Sub
Private Sub Watcher_EventArrived(sender As Object, e As EventArrivedEventArgs) Handles watcher.EventArrived
'Do stuff with the startup event
End Sub
Eventually you'll need to stop the watcher, which is you can do by closing the app, or calling watcher.Stop(). This has been written as brain compiler, so if there's any issues let me know.
You could simply wait and check every once in a while whether the process exists. Use Thread.Sleep to avoid busy waiting.
However, this has the possibility that you miss the process if it starts and exists during your wait time.
You can use the below condition
return Process.GetProcesses().Any(Function(p) p.Name.Contains(myProcessName))
Dim p() As Process
Private Sub CheckIfRunning()
p = Process.GetProcessesByName("processName")
If p.Count > 0 Then
' Process is running
Else
' Process is not running
End If
End Sub
OR SIMPLY
System.Diagnostics.Process.GetProcessesByName("processName")

OpenFileDialog Filter Option Not Working

Since I put my OpenFileDialog into a BackgroundWorker, the Filter option no longer works.
I use to have this as a button click and it worked fine, with the exception of what every file I opened it wouldn't close the file, hence I added the BackgroundWorker.
Anywho, here's my current code, nothing different from the button click code I had.
Dim OpenFileDialog2 As New OpenFileDialog()
OpenFileDialog2.InitialDirectory = "C:\Temp\Config_Files\"
OpenFileDialog2.Filter = "Configuration Files (*.cfg)|*.cfg"
Is there something I need to add to make this work properly?
I think that you are misunderstanding the advice to use a backgroundworker.
You should let the OpenFileDialog do its work and grab the cfg file to be processed, then, if you want a faster UI response start the backgroundworker.
Dim fileToProcess as String = string.Empty
Using opf As New OpenFileDialog()
opf.InitialDirectory = "C:\Temp\Config_Files\"
opf.Filter = "Configuration Files (*.cfg)|*.cfg"
if opf.ShowDialog() = DialogResult.OK then
fileToProcess = opf.FileName
Endif
End Using
if fileToProcess <> string.Empty then
' Now start you backgroundworker to do its job
end if
Of course, the user could re-start againg the same code and select again the same file. This could lead to unexpected results. Better to disable the Button/Menu or whatever that start the file selection process till the previous process ends.