Running Multiple Processes - vb.net

The following code I'm about to posts works fine, however I need to be able to kick off multiple processes at the same time.
So to give some background, the listbox contains files that will be run through another process to create PDF files (essentially passing arguments to the other process which is the exe listed in the StartInfo.Filename). What's currently happening, say the listbox contains 10 files. Each file will be processed separately before the additional files are processed. I'd like to be able to kick off all 10 files at the same time instead of waiting. Some files may take longer than others, so I'm wasting time waiting for each file to finish.
Suggestions?
Dim UPSFiles = (From i In ListBoxUPSFiles.Items).ToArray()
For Each Item In UPSFiles
Dim UPSFiles2 = Item.ToString
Using psinfo As New Process
psinfo.StartInfo.FileName = "\\dgrvdp1\ClientServices\APPS\Printtrack\HeliosPNetExecuter\HeliosPNetExecuter.exe "
psinfo.StartInfo.Arguments = Arg2 + Arg3 + Arg4 + (Chr(34) + DATA_PATH + "\" + UPSFiles2 + Chr(34) + " ") + Arg6 + Arg7 + Arg8 + Arg9a + Arg10 + Arg11 + Arg13
psinfo.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
psinfo.Start()
'psinfo.WaitForExit()
End Using
Next
EDIT
Here's my current code, based on the Parallel.ForEach suggestion. It appears to sort of worked but submitted 10x the number of files I need to run. In my case, I have two files to process however like I mention the code produced 10x the number of processes I truly need.
Dim SequentialFiles = (From i In ListBoxSequentialFiles.Items).ToString
For Each Item In SequentialFiles
Dim SequentialFiles2 = Item.ToString
Parallel.ForEach(SequentialFiles2, Sub(processFiles)
Using psinfo As New Process
psinfo.StartInfo.FileName = "\\dgrvdp1\ClientServices\APPS\Printtrack\HeliosPNetExecuter\HeliosPNetExecuter.exe "
psinfo.StartInfo.Arguments = Arg2 + Arg3 + Arg4 + (Chr(34) + DATA_PATH + "\" + SequentialFiles2 + Chr(34) + " ") + Arg6 + Arg7 + Arg8 + Arg9c + Arg10 + Arg11 + Arg12
psinfo.StartInfo.WindowStyle = ProcessWindowStyle.Normal
psinfo.Start()
psinfo.WaitForExit()
End Using
End Sub)
Next

Depends how is PDF processor work. You can avoid creting threads, but simply launch 10 processes, by feeding inside one file per process. No need of multi threading, at this stage at least.

Related

trouble with interrupting a Batch file started with VBA

I have an Excel file with a lot of PC's names in a server, I want to execute the "systeminfo" command and get the OS out of it. Then the OS shall be put into an Excel cell automatically. To do so, I used the following codes, respectively in the VBA file and the batch file.
however, whenever the server can't reach a pc, the cmd window is stuck until I manually close it. Since the list is actually 148 names long, knowing of a way to automatically close those Windows after, say, 8 seconds would be really helpful.
I tried to look up for a way to multi-thread VBA, just to find out that It is a single-threaded Language. I then tried to start another batch file with the one I'm actually using as to forcefuly kill it afetr a set of time, but it seems that the second batch starts only after the first is terminated, making it useless.
VBA
Sub Test()
'
' Test Macro
' I'm not an expert in VBA, I just picked it up for this task, so a lot of code will result redundant. Bear with me
'
'
Dim i As Integer
'a is basically i-1.
a = 1
' I needed 148 cells for the project
Dim models(1 To 147) As String
For i = 2 To 148
models(a) = Cells(i, 3).Value
a = a + 1
Next i
a = 1
For i = 2 To 148
'not totally sure what the next five lines actually do, but "metodo" is the name of the batch file.
Dim strShellCommand As String
strShellCommand = "C:\Users\Administrator\Desktop\metodo.bat " + models(a)
Set oSh = CreateObject("WScript.Shell")
Set oEx = oSh.Exec(strShellCommand)
strBuf = oEx.StdOut.readAll
'I took out of the string everything that wasn't purely the OS name
Dim FinalString As String
FinalString = Right(strBuf, 26)
FinalString = Left(FinalString, 25)
'this is the line that prints the OS names into Excel cells
ActiveSheet.Cells(i, 10) = FinalString
a = a + 1
Next i
End Sub
then there is the Batch file
set nome=%1
shift
systeminfo /s %nome% |findstr /c:"Microsoft Windows "
u can do a control loop after the Set oEx = oSh.Exec(strShellCommand)
like :
Set oEx = oSh.Exec(strShellCommand)
LoopCount = 0
Do 'Control loop
wscript.Sleep 1000
If TimeOut > 0 Then LoopCount = LoopCount + 1
Loop Until (oEx.Status <> 0) Or (LoopCount > TimeOut * 8)
If oEx.Status = 0 Then 'Timeout occured
oEx.Terminate
ReturnValue = "[Process terminated after timeout!]" & VbCrLf
Else
ReturnValue = "[Process completed]" & VbCrLf
End If
each loop takes 1 second (wscript.Sleep 1000) and the (LoopCount > TimeOut * 8) sets the total time to 8 seconds
good luck

Overflow.Exception crashing my program

I know this is how it's supposed to be done however, in VB.NET it gives me an overflow exception crashing my program. If there is any "VB.NET equivalent" of doing this, help is much appreciated.
Dim hActiveWeapon = _mem.rdInt(GetLocalBase() + &H2EE8)
Dim wepEntity = _mem.rdInt(_client + Offsets.EntityList + ((hActiveWeapon & &HFFF) - 1) * &H10) ' Crashes here # hActiveWeapon & &HFFF
Dim wepIndex = _mem.rdInt(wepEntity + Offsets.iItemDefinitionIndex)
I am doing this to get the lower 12 bytes of m_hActiveWeapon (0xFFF = 0b111111111111 = 4095), so I can get the index of the active weapon.
Meh the answer was simple, changing "&" to "And" fixed it.

VBA Excel Dynamically Display Added Results

So I am modeling my question with a simple Grocery List applications.
Program GUI:
Now what I want is for the Customer to enter: Eggs, Milk, and Bread and for that to enter and output to a .txt file.
Current Code:
Private Sub CreateList_Click()
Dim myFile As String, myString As String
myFile = "C:\Reformatted.txt"
Open myFile For Output As #1
myString = First.Value + Second.Value + Third.Value + Fourth.Value + Fifth.Value
Print #1, myString
Close #1
Shell "C:\Windows\Notepad.exe C:\Reformatted.txt", 1
End Sub
Desired Operation:
What I want to happen is that ther enter there first 5 items. Then it prompts them if they want another 5. If they do then they can add another line.
So I understand that I can add a MsgBox in VB and just design a while loop for that. My question is how to display the results of their first/previous submissions?
Desired Result:
I understand that VB stores the values as variables, but how can I show them to the user while they still have a chance to enter more entries. Also how to add all this with the preferred formatting to a notepad file?
----------------------------After Miss Palmer's Answer--------------------------
Private Sub AddEntry_Click()
Dim UserEntry As String
UserEntry = First.Value + DDPP.Value + Filer.Value + EntryNumber.Value
myString = myString & Chr(13) & UserEntry
GroceryList.UserDisplay.Caption = "You have entered:" & myString
End Sub
Scenario 1 - First Addition
Scenario 2 - Second Addition
The two additions should be placed one after the other. But currently it just replaces it.
You can update a label on the form on each iteration of your while loop using something of the form:
FormName.LabelName.Caption = "you have entered:" & myString
and then add to the string each loop with
myString = myString & First.Value + Second.Value + Third.Value + Fourth.Value + Fifth.Value
EDIT
myString = myString & chr(13) & First.Value + Second.Value + Third.Value + Fourth.Value + Fifth.Value

Why is the file being overwritten?

I'm designing a new server application, which includes a subroutine that parses the input into the console window, for example
LogAlways("--- CPU detection ---")
will be written as:
[net 21:8:38.939] --- CPU detection ---
This is the subroutine:
Public Sub LogAlways(ByVal input As String)
Dim dm As String = "[net " + Date.Now.Hour.ToString + ":" + Date.Now.Minute.ToString + ":" + Date.Now.Second.ToString + "." + Date.Now.Millisecond.ToString + "] "
Console.WriteLine(dm + input)
Dim fName As String = Application.StartupPath() + "\LogBackups\" + Date.Now.Day.ToString + Date.Now.Month.ToString + "" + Date.Now.Year.ToString + ".log"
Dim stWt As New Global.System.IO.StreamWriter(fName)
stWt.Write(dm + input)
stWt.Close()
End Sub
This works, but however only the last line of my desired input is written to the file.
Why is this happening, and how can I make it so that it does not overwrite the log file?
This is using the Wildfire Server API.
This is not a duplicate, as the destination question has a different answer which would otherwise not answer this question.
This occurs as the StreamWriter has not been told to append the output to the end of the file with the parameter set to True, Visual Studio actually gives it as a version of the StreamWriter:
To correctly declare it:
Dim stWt As New Global.System.IO.StreamWriter(fName, True)
or in the subroutine:
Public Sub LogAlways(ByVal input As String)
Dim dm As String = "[net " + Date.Now.Hour.ToString + ":" + Date.Now.Minute.ToString + ":" + Date.Now.Second.ToString + "." + Date.Now.Millisecond.ToString + "] "
Console.WriteLine(dm + input)
Dim fName As String = Application.StartupPath() + "\LogBackups\" + Date.Now.Day.ToString + Date.Now.Month.ToString + "" + Date.Now.Year.ToString + ".log"
Dim stWt As New Global.System.IO.StreamWriter(fName, True)
stWt.Write(dm + input)
stWt.Close()
End Sub
Requires the following to be Imports:
System.IO
System.Windows.Forms
It will now correctly write to the end of the file, but however it is noted that stWt.Close()'ing the file on every call may cause issues, therefore a queuing system may be better:
Desired log output is inserted into a single-dimensional array
A Timer dumps this array to the log file on every, say, five to ten seconds
When this is done, the array is cleared

VB.Net Substring Error

At the moment, I have three different times that the following code is ran, back-to-back just with the variables changed:
txtCourseName.LoadFile(strRootLocation + "\subject\" + strSubject + "\" + "\class\" + cmbCourses.SelectedItem, RichTextBoxStreamType.PlainText)
aData = txtCourseName.Text
i = aData.IndexOf("<h3 class=""panel-title"">") + "<h3 class=""panel-title"">".Length
j = aData.IndexOf("</h3>") - i
txtCourseName.Text = aData.Substring(i, j)
For every time it is ran, the rich-text box that is being used is changed, aData is changed to bData, cData, etc., and the data that i and j are indexing is changed. It will run properly for the first two iterations, returning what it is supposed to into the text box, however on the third one, it gives me a System.ArgumentOutOfRangeException with the additional information of Length cannot be less than zero.
My only assumption for what could be causing this is that the third iteration, which I included below, is only supposed to find a 7-letter long string of characters and this is causing some math issues.
I have no idea how to fix this.
txtCourseNumber.LoadFile(strRootLocation + "\subject\" + strSubject + "\" + "\class\" + cmbCourses.SelectedItem, RichTextBoxStreamType.PlainText)
cData = txtCourseNumber.Text
i = cData.IndexOf("Course Number: </b>") + "Course Number: </b>".Length
j = cData.IndexOf("</li>") - i
txtCourseNumber.Text = cData.Substring(i, j)
Example Data That Is Returned By Each Iteration
aData - "English 4"
bData - "insert some really long course description here"
cData - "10045C"