pause/ wait for *.bat to finish VB.net - vb.net

hi i need to pause/ wait the bellow VB program between the arorasTEMP.bat and the "Label2.Text = "Appending for AutoCAD version A..." as it happens the bat is appending before its temp copy is made
Dim RetBat1
RetBat1 = Shell("C:\VTS\arorasTEMP.bat", 1)
Label2.Text = "Appending for AutoCAD version A..."
'Appending the acad2011.lsp
If System.IO.File.Exists(FILE_NAME1) = True Then
Dim objWriter As New System.IO.StreamWriter(FILE_NAME1, True)
objWriter.WriteLine(arorasKEY)
objWriter.Close()
End If
can anyone give example?

Shell is a VB6 command, it's not the ideal way to launch processes.
The proper way in .NET to invoke a process and wait for it is:
Dim aroras as Process = Process.Start("C:\VTS\arorasTEMP.bat")
aroras.WaitForExit()
' error code is available in aroras.ExitCode, if you need it
You can also forcibly kill it if it takes too long:
If Not aroras.WaitForExit(300) Then
aroras.Kill()
End If
(where 300 is the time in milliseconds to wait)

you can tell the shell to wait for the process to be done before executing anything else:
RetBat1 = Shell("C:\VTS\arorasTEMP.bat", ,True)
And even give a timeout that stops the execution if it takes too long, in this case 6 seconds:
RetBat1 = Shell("C:\VTS\arorasTEMP.bat", , True, 6000)
More info about the Shell function: http://msdn.microsoft.com/en-us/library/xe736fyk(VS.80).aspx

Related

run external program and exit from calling program

n the closing procedure of a program (just before running Application.exit) I need to run an external program to pass a parameter and exit the calling program.
The program called (FilmDB_Update.exe) has the task of overwriting the main program or a dll library.
I tried to use the "process.start" technique, but apparently, the calling program remains in use and does not allow me to overwrite it.
This is the code that I write:
Private Sub AggiornaPgm()
Dim ws_file As String = "FilmDB_Update.exe"
Dim ws_proc_param As String = """" + ws_working_path + """ " + ws_temp_path
Dim ws_fullPath As String = Path.Combine(ws_temp_path, ws_file)
If File.Exists(ws_fullPath) Then
File.Copy(ws_fullPath, ws_file, True)
End If
Dim proc As New System.Diagnostics.Process()
proc = Process.Start(ws_file, ws_proc_param)
End Sub
I wanted to try using the shell command, but I can not pass the parameters to the called program.
Does any of you have any other ideas about it?
Thank you
Marcello
As Ahmed suggested, I added the test for the calling process to the program called.
p = Process.GetProcessesByName(ws_calling_pgm)
While p.Count > 0
Threading.Thread.Sleep(3000)
p = Process.GetProcessesByName(ws_calling_pgm)
End While
p = Nothing
When I exit the While loop, the calling process is terminated. I do not understand why, despite the process no longer exists, the main program is still in use.

Writing to Command Line Not Working

An application I need to use (USB capture utility) has a .cmd version that I can call from my Visual Basic code. I am able to launch the application and put it in "command line mode" like this:
Public Class MyClass
Dim StreamWriteUtility As System.IO.StreamWriter
Dim StreamReadUtility As System.IO.StringReader
Dim ProcessInfo As ProcessStartInfo
Dim Process As Process
Public Sub StartUSBCapture(ByVal DataStorageLocation As String)
Dim ProcessInfo As ProcessStartInfo
Dim Process As New Process
ProcessInfo = New ProcessStartInfo("C:\FW_Qualification_Suite\data-center-windows\data-center\bin\datacenter.cmd", "-c ")
ProcessInfo.CreateNoWindow = True
ProcessInfo.UseShellExecute = False 'Must be changed if redirect set to True
ProcessInfo.RedirectStandardInput = True
Process = Process.Start(ProcessInfo)
SWUtility = Process.StandardInput
While True
SWUtility.WriteLine("run") 'Looping for test to ensure this isn't a timing issue
End While
End Sub
End Class
This launches the application and opens a separate command line window that should accept further commands (i.e., capture, run, stop, etc). However, I am having trouble getting those subsequent commands to show up in the command line window. I've tried redirecting the standard input of the process, but still nothing shows up in the console window.
Can anyone tell how I'm supposed to actually get these commands from my Visual Basic program into this application?

show a trackbar or image while shell() is running a cmd.exe instruction

I'm trying to do a simple windows form application in visual basic that change the attributes of all the files in a drive using shell().
It works but since sometimes there are a lot of files, the applications looks like it freeze (because I'm using the "wait" argument as true.
So I'm looking for a way to show an "load" gif while the cmd is doing his thing, I found and example in msdn for a "wait until process finish" using interaction.Start (http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.interaction.shell(v=vs.110).aspx) I tried to mix shell with that example but I can't get it to run ok.
This is my code so far.
pic_working.Visible = True
myDrive = "F:\"
Dim procID As Integer
Dim newProc As Diagnostics.Process
newProc = Diagnostics.Process.GetProcessById(Shell("cmd.exe /C attrib -r " + myDrive + "*.* /s /d", AppWinStyle.NormalFocus, False))
procID = newProc.Id
Dim procEC As Integer = -1
If newProc.HasExited Then
procEC = newProc.ExitCode
End If
MsgBox("Process with ID " & CStr(procID) & " terminated with exit code " & CStr(procEC))
myDrive =""
pic_working.Visible = False
It works...kind of... when I set the wait argument for shell() to "true" it take like 30 seconds to complete the task (in my test drive), but with it to false it just skips everything and my pic_Working is never showed.
Can you give me a hint... it's possible to do this in this way, or I have to do the long way (using File.SetAttributes and parsing one file at the time?
Thanks!
Disclaimer: C++ guy here.
Set Wait to False. If Shell tells you the program is still running, display your image, start a Timer, Use the Win32 API OpenProcess with the PID returned by Shell and save the HANDLE, and return. On each Timer Tick, use the Win32 API WaitForSingleObject with the HANDLE and with a timout equal to 0. If the process handle is successfully signaled, then the task is terminated.
EDIT
How to know when a process is terminated, when you have successfully got an HANDLE to that process with OpenProcess:
HANDLE hProcess;
[...]
DWORD dwRet = WaitForSingleObject( hProcess, 0 );
if ( dwRet == WAIT_OBJECT_0 ) {
// Process is terminated. Don't forget to close the handle
CloseHandle( hProcess );
} else if ( dwRet == WAIT_TIMEOUT ) {
// Process NOT terminanted, wait next Timer Tick
} else {
// Error Occurred
DWORD dwLE = GetLastError();
}
Using the Win32 HANDLE type in C#/VB: use IntPtr

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")

Executing processes in vb.net with a delay

I'm trying to execute a number of processes from a listview although i need a delay between them.
My vb.net knowledge is limited,
For Each ListView1 As ListViewItem In Me.ListView1.Items
If ListView1.Checked = True Then
Dim targetName As String = ListView1.SubItems(5).Text.ToString
Dim fileExists As Boolean
fileExists = My.Computer.FileSystem.FileExists(targetName)
If fileExists = True Then
Dim p As System.Diagnostics.Process
p = New System.Diagnostics.Process()
p.StartInfo.WorkingDirectory = "c:\"
p.StartInfo.FileName = URLDecode(targetName)
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
p.Start()
p.Close()
Else
This will execute the processes fine most of the time, which is actually an mp3 file and it will add it to winamps playlist. Sometimes it just fires too quickly and it's causing winamp to crash while processing the mp3's, how can i put in a delay between executing each process without locking up the ui? Also any suggestions on how i can improve the overall code and make it more stable would be much appreciated. Thanks
Imports System.Threading
Thread.Sleep(5000)
Thread.Sleep() takes a number of miliseconds to wait, so the above will wait 5 seconds.