Why is the process id not found in GetProcesses() - vb.net

I am starting a PDF, and I get a process.
The PDF is shown in a Chrome window.
Then I try to find this process among the processes, but it is not there.
I have even tried adding some time to wait before calling GetProcesses(), but that wouldn't change anything.
What am I missing?
Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
Dim sPath As String = "d:\test.pdf"
Dim nProc As Process = System.Diagnostics.Process.Start(sPath)
Dim iProcID As Integer = nProc.Id
Dim allProcesses() As Process = System.Diagnostics.Process.GetProcesses
For Each nProcess As Process In allProcesses
If nProcess.Id = iProcID Then
Stop 'found :-)
End If
Next
End Sub

Related

VB.NET Program is always reading last created textfile

Trying to create a login form,
My coding is currently:
Imports System
Imports System.IO
Public Class frmLogin
Dim username As String
Dim password As String
Dim fileReader As String
Dim folderpath As String
Dim files As Integer
Dim filepath As String
Public Structure info
Dim U As String
Dim P As String
End Structure
Dim details As info
Private Sub btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
If txtusername.Text = details.U And txtpassword.Text = details.P Then
MessageBox.Show("Correct!")
frmmenu.Show()
Me.Hide()
Else
MessageBox.Show("wrong")
txtusername.Clear()
txtpassword.Clear()
End If
End Sub
Private Sub btncreate_Click(sender As Object, e As EventArgs) Handles btncreate.Click
frmcreate.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
files = files + 1
filepath = "C:\Users\TheGlove\Desktop\Alex's Program\loginfile" & files & ".txt"
Dim di As DirectoryInfo = New DirectoryInfo("C:\Users\TheGlove\Desktop\Alex's Program")
folderpath = "C:\Users\TheGlove\Desktop\Alex's Program"
files = System.IO.Directory.GetFiles(folderpath, "*.txt").Count
For Each fi In di.GetFiles()
MsgBox(fi.Name)
Dim FILE = System.IO.File.ReadAllLines("C:\Users\TheGlove\Desktop\Alex's Program\loginfile" & files & ".txt")
Dim myArray As String() = FILE
details.U = myArray(0)
details.P = myArray(1)
Next
End Sub
End Class
Button 1 will be merged with btnlogin when i get it working and for now is currently just a seperate button to read each textfile.
When each button is pressed (Button 1 -> btnlogin), only the last created textfile is correct.
By the looks of things, your code does read all the text files, but keeps overwriting details.u and details.p with the value retrieved from each file. So, when the loop gets to the last file, those values are what ends up in the details object.
I'm assuming that you want to read all the usernames and passwords into a list and check the details in the TextBoxes against that list, so .. Your code should probably be something like the code below (see the code comments for an explanation of some of the differences.
Before we get to the code, can give you a couple of pointers.
Firstly, always try to use names that are meaningful. Defining your structure as Info is not as meaningful as it could be. For example, you would be better calling it UserInfo and rather than use P and U, you would be better using Password and UserName. It may not matter so much right now, but when you start writing larger more complex programs, and have to come back to them in 6 months time to update them, info.P or details.P aren't as informative as the suggested names.
Secondly, as #ajd mentioned. Don't use magic strings. Create one definition at the beginning of your code which can be used throughout. Again it makes maintenance much easier if you only have to change a string once instead of multiple times, and reduces the chance of mistakes.
Finally, several of the variables you have defined aren't used in your code at all. Again, at this level, it isn't a major issue, but with large programs, you could end up with a bigger memory footprint than you want.
Dim username As String
Dim password As String
Dim fileReader As String
Dim folderpath As String = "C:\Users\TheGlove\Desktop\Alex's Program"
Dim files As Integer
Dim filepath As String
Public Structure UserInfo
Dim Name As String
Dim Password As String
End Structure
'Change details to a list of info instead of a single instance
Dim userList As New List(Of UserInfo)
Private Sub Btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
'Iterate through the list of details, checking each instance against the textboxes
For Each tempUserInfo As UserInfo In userList
If txtusername.Text = tempUserInfo.Name And txtpassword.Text = tempUserInfo.Password Then
MessageBox.Show("Correct!")
frmmenu.Show()
Me.Hide()
'This is here, because after your form has opened an closed, the loop
'that checks usernames and passwords will continue. The line below exits the loop safely
Exit For
Else
MessageBox.Show("wrong")
txtusername.Clear()
txtpassword.Clear()
End If
Next
End Sub
Private Sub Btncreate_Click(sender As Object, e As EventArgs) Handles btncreate.Click
frmcreate.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'clear the list of user details otherwise, if the files are loaded a second time,
'you'll get the same details added again
userList.Clear()
'This line replaces several lines in your code that searches the folder for files
'marching the search pattern
Dim fileList() As FileInfo = New DirectoryInfo(folderpath).GetFiles("loginfile*.txt")
For Each fi As FileInfo In fileList
MsgBox(fi.Name)
Dim userDetails() As String = System.IO.File.ReadAllLines(fi.FullName)
Dim tempInfo As New UserInfo With {.Name = userDetails(0), .Password = userDetails(1)}
'An expanded version of the above line is
'Dim tempInfo As New info
'tempInfo.U = userDetails(0)
'tempInfo.P = userDetails(1)
userList.Add(tempInfo)
Next
files = fileList.Count
End Sub

Method to download large files in Vb.net

Okay, so I have been trying to download a large file with different methods. In my code what would usually work best is My.Computer.NetWork.DownloadFile but because the file is 1.5Gb's my windows form freezes and doesn't respond. I didn't bother waiting to see for how long it wouldn't respond for after I waited 5 minutes because I thought it would just be a waste of time. So I also tried wc.DownloadFileAsync (wc standing for Web Client) this works and doesn't freeze my windows form but the problem with this is that it skips over it and doesn't wait until the download is finished so it continues on with my code and therefore I get errors.
I tried researching ways to pause or stop the code until the download was finished but no luck. After further research I found the backgroundworker class. I was wondering if this would work for me and how would I implement it into my code, or if there is any easier way to go about doing this?
I was not able to successfully implement it into my code. I wasn't able to invoke and therefore got errors such as this: Cross-thread operation not valid.
This is currently my code, with the background worker:
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim downloader As New System.Net.WebClient
Dim ServerVersion = wc.DownloadString("http://127.0.0.1:8080/patch/PatchList.txt").Trim
Dim tLines As String() = ServerVersion.Split(Environment.NewLine)
For Each NewLine As String In tLines
Dim tVersionAndUrl As String() = NewLine.Split(vbTab)
Dim encText As New System.Text.UTF8Encoding()
Dim btText() As Byte
btText = encText.GetBytes(tVersionAndUrl(0))
'MessageBox.Show(btText.ToString)
'MessageBox.Show(tVersionAndUrl(0)(0))
If tVersionAndUrl.Length < 2 Then
Exit For
End If
If Integer.Parse(tVersionAndUrl(0)) < Integer.Parse(CVersion.Text) Then
Dim TempPath As String = "\launcher\temp.rar"
AddHandler wc.DownloadProgressChanged, AddressOf ProgressChanged
AddHandler wc.DownloadProgressChanged, AddressOf ProgressChanged
AddHandler wc.DownloadFileCompleted, AddressOf DownloadCompleted
'wc.DownloadFileAsync(New Uri(tVersionAndUrl(1)), Me.GetFileName(tVersionAndUrl(1)))
wc.DownloadFileAsync(New Uri(tVersionAndUrl(1)), tmp, Stopwatch.StartNew)
'My.Computer.FileSystem.DeleteFile(Me.GetFileName(tVersionAndUrl(1)))
CVersion.Text = tVersionAndUrl(0)
LabelStatus.Text = "Download in Progress"
Button1.Enabled = False
End If
Next
MsgBox("Client is up to date")
End Sub
And this is the Addhandlers for it:
Private Sub ProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
Dim bytesIn As Double = Double.Parse(e.BytesReceived.ToString())
Dim totalBytes As Double = Double.Parse(e.TotalBytesToReceive.ToString())
Dim percentage As Double = bytesIn / totalBytes * 100
ProgressBarCurrent.Value = Int32.Parse(Math.Truncate(percentage).ToString())
Dim BytesDownloaded As String = (e.BytesReceived / (DirectCast(e.UserState, Stopwatch).ElapsedMilliseconds / 1000.0#)).ToString("#")
If BytesDownloaded < 1024 Then
Dim Bs As String = Convert.ToInt32(BytesDownloaded)
Label4.Text = (Bs & " B/s")
ElseIf BytesDownloaded < 1048576 Then
Dim KBs As String = Math.Round(BytesDownloaded / 1024, 2)
Label4.Text = (KBs & " KB/s")
ElseIf BytesDownloaded < 1073741824 Then
Dim MBs As String = Math.Round(BytesDownloaded / 1048576, 2)
Label4.Text = (MBs & " MB/s")
End If
End Sub
Private Sub DownloadCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
'MessageBox.Show("Download Complete")
LabelStatus.Text = "Download Complete"
Button1.Enabled = True
Downloading = False
End Sub
I would appreciate any help. Thanks.
In newer VB/C# .net the keywords you are interested in are Await and Async:
http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
Also you should design your routine to download in chunks. There are many ways to do that but maybe you are better to look at HTTPWebRequest/Response will handles chunking and has a method to work with +2GB files easily (ranging).
Sorry not an answer as I don't have enough rep to put this as a comment.
Cheers,
Al
In your code, we can see that you have used BackgroundWorker class, which seems good to me. What i am trying to find is the remaining delegate functions of the BackgroundWorker class like ProgressChanged, RunWorkerCompleted (instead you have registered you own delegates which might seems to lead to an error on the later stage). Try handling these events, it should help you and let you know when the task completes and reports progress in the meanwhile. For reporting progress, in the main UI thread, you can also run a progress bar with style property set as Marquee.

Causing a batch file to finish its operations, before continuing?

The following code will extract files modified today from the SourceDirectory and place them into the FilesExtracted folder, then the batch file will delete the rest of the files in the sourceDirectory. But after that is all done a brand new set of files will be copied from the OriginalTestFiles folder and put into the sourceDirectory, but its does not do it. Does anyone think that it could be because the batch files hasn't stopped its operations and is still deleting the files in the sourceDirectory, or is there another problem. Thank You all!
Imports System.IO
Public Class frmExtractionator
' Dim txtFiles1 As Control
Dim sourceDirectory As String = "F:\CopierFolderforTestDriveCapstone"
Dim archiveDirectory As String = "F:\FilesExtracted"
Dim originalDirectory As String = "F:\OriginalTestFiles"
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Try
Dim txtFiles = Directory.EnumerateFiles(sourceDirectory)
If (Not System.IO.Directory.Exists(archiveDirectory)) Then
System.IO.Directory.CreateDirectory(archiveDirectory)
End If
For Each currentFileLoc As String In txtFiles
Dim fileName = currentFileLoc.Substring(sourceDirectory.Length + 1)
If (IO.File.GetLastWriteTime(currentFileLoc).ToString("MM/dd/yyyy") = DateTime.Now.ToString("MM/dd/yyyy")) Then
MessageBox.Show(currentFileLoc & " moved", "Moved Succesfully")
File.Move(currentFileLoc, Path.Combine(archiveDirectory, fileName))
End If
Next
Catch eT As Exception
Console.WriteLine(eT.Message)
End Try
System.Diagnostics.Process.Start("F:\poop.bat")
Try
Dim txtFiles2 = Directory.EnumerateFiles(originalDirectory)
For Each currentFileLoc2 As String In txtFiles2
Dim fileName = currentFileLoc2.Substring(originalDirectory.Length + 1)
File.Move(currentFileLoc2, Path.Combine(sourceDirectory, fileName))
Next
Catch eT As Exception
Console.WriteLine(eT.Message)
End Try
End Sub
End Class
You can get the process as a variable once you start it and wait for it to exit:
Dim theProcess As Process = Process.Start("F:\poop.bat")
theProcess.WaitForExit()
Try monitoring the Process for completion...
'Start the process.
Dim Proc = Process.Start("F:\poop.bat")
'Wait for the window to finish loading.
Proc.WaitForInputIdle()
'Wait for the process to end.
Proc.WaitForExit()
...

Opening up process and grabbing window title. Where did I go wrong?

In my application I allow for the users to add a program from a open file dialog, and it then adds the item to a listview and saves the items location into the tag. So what I am trying to do is when the program in the listview is selected and the button is pressed, it starts a timer and this timer checks to see if the process is running, and if it isn't launches the process, and once the process is launched it gets the window title of the process and sends it to a textbox on another form.
EDIT:
The question is if anyone can see why it is not working, by this I mean starting the process, then when it's started closing the form and adding the process window title to a textbox on another form.
I have tried to get it working but I can't. I know that the process name it is getting is right I think my problem is to do with my for loop. Basically it isn't doing anything visible right now.
I feel like I am very close with my code and im hoping it just needs a couple minor tweaks. Any help would be appreciated. Sorry if my coding practices aren't that great, im pretty new to this.
**EDIT:I found solution. I added code to the button that enables my timer to execute the process. Also another problem was indeed the way it read the file, I had to use the replace function to remove the ".exe" from the filepath code.
EDIT 2 : A better solution has been posted by Mark Hall. I am now using his code as it has less chance for error.
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim s As String = ListView1.SelectedItems(0).Tag
Dim myFile As String = Path.GetFileName(s)
Dim mu As String = myFile.Replace(".exe", "").Trim()
Dim f As Process
Dim p As Process() = Process.GetProcessesByName(mu)
For Each f In p
If p.Length > 0 Then
For i As Integer = 0 To p.Length - 1
ProcessID = (p(i).Id)
AutoMain.Name.Text = f.MainWindowTitle
Timer1.Enabled = False
Me.Close()
Next
Else
ProcessID = 0
End If
If ProcessID = 0 Then
Process.Start(mu)
End If
Next
End Sub
What is happening is that you are looking for a Process that matches your parameters before you enter your For Each loop the Process array is empty so it never enters it, therefore you never start your process.
This is a very quick example that works:
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
Dim s As String = ListView1.SelectedItems(0).Tag.ToString
Dim myFile As String = Path.GetFileName(s)
Dim p As Process() = Process.GetProcessesByName(Path.ChangeExtension(myFile, Nothing))
Static started As Boolean
If p.Count > 0 Or started Then
If p.Length > 0 Then
For i As Integer = 0 To p.Length - 1
ProcessId = (p(0).Id)
AutoMain.Name.Text = p(0).MainWindowTitle
Timer1.Enabled = False
started = False
Timer1.Stop()
Me.Close()
Next
Else
ProcessId = 0
End If
Else
started = True
Process.Start(myFile)
End If
End Sub

VB.NET - Running one sub multiple times at once

I have one Private sub that runs in a loop. I want the sub to run multiple times at once. For example the program runs, you press start; you run the program again and press start, again and again... the same program doing the job at once. now i just want one program do to it alone. But i would like it to be user defined. exp. run program. type in a text box 10. press start. and it works as if 10 of them work open working on the same thing.
I have seen another program made with vb.net 2010 and its what i use and do not know how to do it. so i am just wondering.
Private Sub Flood1(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles Flood.DoWork
Dim IP As IPAddress = IPAddress.Parse(TextBox1.Text)
Dim IPPort As New IPEndPoint(IP, Convert.ToInt32(TextBox2.Text))
Dim PacketS As Byte() = New Byte(TextBox3.Text) {}
Dim SocketN As Integer = Convert.ToInt32(TextBox4.Text)
Do While Flooding = True
For i = 0 To SocketN
If Flooding = True Then
Dim _Sock(i) As Socket
_Sock(i) = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Try
_Sock(i).SendTo(PacketS, IPPort)
Threading.Thread.Sleep(500)
Catch ex As Exception
Threading.Thread.Sleep(500)
End Try
Else
Exit Do
End If
Next
Loop
End Sub
Mostly want to have this work over and over at once by the users choice... kinda hoped not to use this code else might not get helped.
You can use background worker for that.
Once you know how many workers you want to do the job
just create those many instances of background worker.
Tell me if this is the answer you are looking for or not
Sample Source Code
Imports System.ComponentModel
Module Module1
Sub Main()
Console.WriteLine("Please enter the worker count:")
Dim workerCount As Integer = Console.ReadLine()
For i As Int16 = 0 To workerCount
Dim worker As BackgroundWorker = New BackgroundWorker
worker.RunWorkerAsync(i + 1)
AddHandler worker.DoWork, AddressOf Worker_DoWork
Next
End Sub
Private Sub Worker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
Console.WriteLine(e.Argument.ToString())
End Sub
End Module