How to loop a file check until conditions are met in Visual studio 2017 with vb code? - vb.net

So I'm trying to loop a file check until 1 file is there and the file that creates that file is gone. I keep trying to rewrite and have been trying to find a working setup but just can't find any this is the code that I have currently
Dim dir = My.Application.Info.DirectoryPath
If ProgressBar1.Value = 25 Then
Do
If CheckBox1.Checked Then
If FileExists(dir + "\download\downloaded.mp3") Then
If FileExists(dir + "\download\downloaded.mkv") Then
Else
ProgressBar1.Value = 45
Exit Do
End If
End If
End If
If FileExists(dir + "\download\dvid.mp4") Then
If FileExists(dir + "\download\dvid.mp4.part") Then
Else
ProgressBar1.Value = 45
Exit Do
End If
End If
Loop
when ever I get my application up a run this code the app stops responding so am I doing something wrong or is there something missing?

using wait for exit on process fixed my problem
Dim p As New Process
Dim psi As New ProcessStartInfo(dir + "file to start.exe")
psi.WindowStyle = ProcessWindowStyle.Hidden
psi.Arguments = "-x --audio-format mp3 --output /downloaded/downloaded.mkv " + Form1.TextBox1.Text
p.StartInfo = psi
p.Start()
p.WaitForExit()

Related

Delete a file in use by another process in vb.net / framework 2.0

I have a program that watches if there is a file with a certain name, in a certain directory.
the FileStream is created with the sequent command:
fs = File.Open(PathK, FileMode.Append, FileAccess.Write, FileShare.None)
After half an hour, the program closes, disposes and kills the text file and then shuts down itself, calling for another program to create another process of itself and closes the old one.
Sometimes this doesn't happen though. The file can't be removed and it causes an error.
After that the program closes itself and continues with its restart routine. but when it starts itself, it checks if there is that specific file, and there it is, because it couldn't kill it. Now, i can do File.OpenRead on that file, so the old filestream of the old process is not running, so it means the old one process is shut down. But I still can't kill it!
this is the starting code:
Private Sub Verifica_PID_Aperti()
Dim Tentativi As Integer = 0
PidAlreadyOpen = 0
'file exist ?
If File.Exists(PathK) = True Then
Try
'can i read it?
File.OpenRead(PathK)
Catch ex As Exception
'if it's locked than there is another PID active right now, stop this process
Settaggi.lStop = 1
PidAlreadyOpen = 1
Exit Sub
End Try
'not locked? than it's a bug and the file is still open, try to delete
While (Tentativi < 1000)
Try
File.Delete(PathK)
Tentativi = 1000
Catch ex As Exception
Tentativi = Tentativi + 1
End Try
End While
'is him still alive?
If File.Exists(PathK) Then
'if yes, there is an error, sand a mail and close yourself
Dim pf As New Send_Mail
pf.Invio_Mail_Automatico_EDP(999, "ERRORECHIUSURA", Err.Description & " - " & PathK, "", Settaggi.lPID)
pf = Nothing
Settaggi.lStop = 1
PidAlreadyOpen = 1
Exit Sub
Else
'ok, if it does not exists anymore, create another one
fs = File.Open(PathK, FileMode.Append, FileAccess.Write, FileShare.None)
End If
Else
'no file ? than create it
fs = File.Open(PathK, FileMode.Append, FileAccess.Write, FileShare.None)
End If
End Sub
and here it's the code for the restart procedure:
If PidAlreadyOpen = 0 Then
'close and clean
fs.Close()
fs.Dispose()
End If
Threading.Thread.Sleep(1000)
Dim Chiusura As Integer = 0
While Chiusura < 1000
Try
'try to delete
File.Delete(PathK)
If TimeToReboot = 1 Then
System.Diagnostics.Process.Start(Application.ExecutablePath, "/noservice /release /PID:" & Settaggi.lPID)
End If
Catch ex As Exception
Chiusura = Chiusura + 1
' not deleted ? send an email, and don't stop yourself
If Chiusura = 999 Then
Dim pf As New Send_Mail
pf.Invio_Mail_Automatico_EDP(999, "ERRORECHIUSURA", Err.Description & " - " & PathK, "", Settaggi.lPID)
pf = Nothing
Exit Sub
End If
Threading.Thread.Sleep(100)
End Try
'deleted? than stop the loop
If Not File.Exists(PathK) Then
Chiusura = 1000
End If
End While
Me.Close()
how do you think should i resolve this problem ?
I don't think there's much you can do here. I had similar issues in the past and found that, while it's not possible to delete the file, it is possible to rename the file. Depending on the situation, you can rename the file and open a new file with that name. You'll also need to check, later in the process, if the renamed file is still used and delete it.

Check if Mage.exe batch manifest update was successful or not - ClickOnce

I have created a console app that creates a batch file in code, that will automatically update and re-sign my app manifest file using mage.exe when a new version gets published.
This batch file then gets executed by the same console app after it has created it.
I want to know if there is a way to determine if the mage.exe batch file failed in updating or signing the manifest?
Any help or ideas will be appreciated.
UPDATE
As per TnTinMn's comment, I forced the batch to fail on updating the manifest. This returned a exit code of 1. How is it then possible for me to extract that exit code to do my error handling? Im doing the following:
Dim procInfo As New ProcessStartInfo()
procInfo.UseShellExecute = True
procInfo.FileName = (sDriveLetter & ":\updatemanifest.bat")
procInfo.WorkingDirectory = ""
procInfo.Verb = "runas"
procInfo.WindowStyle = ProcessWindowStyle.Hidden
Dim sval As Object = Process.Start(procInfo) 'I tested the object to see if there is indeed a value that i can use.
While debugging and looking at the sval object's properties, the exit code is set to 1 but i can't seem to extract it from there.
There are two ways (that I know of) that you can wait for the process to exit before retrieving the Process.ExitCode.
The first as is a blocking call: Process.WaitForExit
and the second is to use the Exit event.
Private Sub RunProcess()
Dim psi As New ProcessStartInfo()
psi.UseShellExecute = True
psi.WindowStyle = ProcessWindowStyle.Hidden
psi.FileName = "cmd.exe"
psi.Arguments = "/c Exit 100"
Dim proc As Process = Process.Start(psi)
proc.EnableRaisingEvents = True
AddHandler proc.Exited, AddressOf ProcessExited
End Sub
Private Sub ProcessExited(sender As Object, e As EventArgs)
Dim proc As Process = DirectCast(sender, Process)
proc.Refresh()
Dim code As Int32 = proc.ExitCode
Me.BeginInvoke(Sub() MessageBox.Show(String.Format("Process has exited with code: {0}", code)), Nothing)
proc.Dispose()
End Sub

Create and write to file > start application > delete file in VB.NET

I'm trying to create a VB.NET application which writes multiple lines of text into a text file, then starts an application and after the application started, deletes the text file.
How exactly can I realize that?
--
Edit:
I now got this code:
Dim iniFile As String = Application.StartupPath + "\settings.ini"
If System.IO.File.Exists(iniFile) = True Then
File.Delete(iniFile)
End If
If System.IO.File.Exists(iniFile) = False Then
File.Create(iniFile)
End If
Dim fileStr As String() = {"line1", "line2", "line3"}
File.WriteAllLines(iniFile, fileStr)
Dim p As Process = Process.Start(Application.StartupPath + "\app.exe")
p.WaitForInputIdle()
If System.IO.File.Exists(iniFile) = True Then
File.Delete(iniFile)
End If
The only problem I got, is that VS is telling me, the file is in use. Between creating and editing the file. Any ideas for that?
Your code is starting the app and then moving straight on to delete the ini file.
You need to wait for the process to exit first before you continue with deleting the ini file
E.g
{code to create ini file}
'Start the process.
Dim p As Process = Process.Start(Application.StartupPath + "\app.exe")
'Wait for the process window to complete loading.
p.WaitForInputIdle()
'Wait for the process to exit.
p.WaitForExit()
{code to delete ini file}
Full example here: https://support.microsoft.com/en-us/kb/305368
Just use File.WriteAllText
Note: As others already mentioned, you should check against True in your last If
If System.IO.File.Exists(Application.StartupPath + "\settings.ini") = False Then
File.Create(Application.StartupPath + "\settings.ini")
End If
Dim fileStr As String() = {"line1", "line2", "line3"}
System.IO.File.WriteAllText(Application.StartupPath + "\settings.ini", [String].Join(Environment.NewLine, fileStr))
Process.Start(Application.StartupPath + "\app.exe")
If System.IO.File.Exists(Application.StartupPath + "\settings.ini") = True Then
File.Delete(Application.StartupPath + "\settings.ini")
End If
Use File.WriteAllLines since it
Creates a new file, write the specified string array to the file, and then closes the file. [...] If the target file already exists, it is overwritten.
msdn
Also you should use Path.Combine to setup your path
Dim path as String = Path.Combine(Application.StartupPath, "settings.ini")
Dim fileStr As String() = {"line1", "line2", "line3"}
File.WriteAllLines(path, fileStr)
Use the Path.Combine for the Process.Start and File.Delete too.

IO.File.Delete Random UnauthorizedAccessException

I'm using My.Computer.Filesystem.WriteAllBytes to write out an executable stored in my application's resources to it's startup directory. After running the executable, I then delete it. Everything works fine; however, I'll randomly get an UnauthorizedAccessException for no reason. After getting the exception, I can manually delete the file with no problem. Here's the full code:
' Convert MP3
' First, copy out converter
Dim Path = New IO.FileInfo(SoundPath)
Try
My.Computer.FileSystem.WriteAllBytes(Application.StartupPath + "\converter.exe", My.Resources.madplay, False)
Catch ex As Exception
MessageBox.Show(ex.ToString, "Report", MessageBoxButtons.OK)
Exit Sub
End Try
' Set up process
Dim MAD As New Process
' Set process info
Dim output As String = IO.Path.GetFileNameWithoutExtension(Path.FullName) + ".wav"
Dim input As String = Path.FullName
Dim adjust As String = barVolumeAdjust.Value.ToString
Dim hz As String = "15000"
With (MAD.StartInfo)
.FileName = Application.StartupPath + "\converter.exe"
.Arguments = "-v -a " + adjust + " -R " + hz + " -o """ + output + """ """ + input + """"
.UseShellExecute = False
.RedirectStandardInput = True
.RedirectStandardError = True
.RedirectStandardOutput = True
.CreateNoWindow = True
End With
' Start
MAD.Start()
' Update title with output
Dim Line As String = MAD.StandardError.ReadLine
While Not Line Is Nothing
Me.Text = Line
Line = MAD.StandardError.ReadLine
End While
' Stop
MAD.Close()
' Delete MAD
Try
IO.File.Delete(Application.StartupPath + "\converter.exe")
Catch ex As Exception
MessageBox.Show(ex.ToString, "Report", MessageBoxButtons.OK)
End Try
What perplexes me is that I literally just wrote out the executable, and nothing else could possibly be using it. I've checked the file attributes and it's not read-only. My application is also running as an administrator. What could be the problem?
You do not wait for the process to exit, so it is still running when you attempt to delete the file. See Process.WaitForExit
It looks like your using a separate process to write out the file - perhaps this is still using the file when you try to delete.
I suggest catching and handling the exception to get around the problem.

Visual Basic (Visual Studio 2005) redirect inputstream to process

I've been searching around the net for roughly three hours now w/o getting forward. I don't know VB very well, but I need to create a wrapper program for any executable that logs the arguments, all input, output and err information:
My wrapper is called: e.g. someApp.exe arg1 arg2
Logs to someApp.log: arg1 arg2
Calls original executable: _someApp.exe arg1 arg2
Must log and forward any console input to _someApp process inputstream
Must log any output and error stream from _someApp process
Okay, I'm stuck at point 4 now:
Dim p As New ProcessStartInfo
p.FileName = execute
p.Arguments = Command()
p.UseShellExecute = False
p.CreateNoWindow = True
p.RedirectStandardInput = True
p.RedirectStandardError = True
p.RedirectStandardOutput = True
Dim process As System.Diagnostics.Process
process = Diagnostics.Process.Start(p)
process.WaitForExit()
After _someApp ends I am able to read out and err stream to log it, but I still need to provide my own wrappers input to the process and I want to read out and err stream as it happens.
Thanks for info/examples
Okay here the solution...
Variables needed:
Private process As System.Diagnostics.Process
Private threadOut As Thread
Private streamOut As System.IO.StreamReader
Private threadErr As Thread
Private streamErr As System.IO.StreamReader
Private threadIn As Thread
Private streamIn As System.IO.StreamWriter
Subs needed:
Private Sub ThreadTaskOut()
Dim line
While Not process.HasExited
line = streamOut.ReadToEnd
If line <> Nothing And line <> "" Then
log("Out: " & line)
Console.Out.Write(line)
End If
End While
End Sub
Private Sub ThreadTaskErr()
Dim line
While Not process.HasExited
line = streamErr.ReadToEnd
If line <> Nothing And line <> "" Then
log("Err: " & line)
Console.Error.Write(line)
End If
End While
End Sub
Private Sub ThreadTaskIn()
Dim line
While Not process.HasExited
line = Console.In.ReadLine
If line <> Nothing And line <> "" Then
log("In: " & line)
streamIn.WriteLine(line)
End If
End While
End Sub
Inside main:
' create process information
Dim p As New ProcessStartInfo
p.FileName = execute
p.Arguments = Command()
p.UseShellExecute = False
p.CreateNoWindow = True
p.RedirectStandardInput = True
p.RedirectStandardError = True
p.RedirectStandardOutput = True
' log process start
log("Execute: " & execute & " " & Command())
' start process
process = Diagnostics.Process.Start(p)
' start thread for output stream
streamOut = process.StandardOutput
threadOut = New Thread(AddressOf ThreadTaskOut)
threadOut.IsBackground = True
threadOut.Start()
' start thread for error stream
streamErr = process.StandardError
threadErr = New Thread(AddressOf ThreadTaskErr)
threadErr.IsBackground = True
threadErr.Start()
' start thread for input stream
streamIn = process.StandardInput
threadIn = New Thread(AddressOf ThreadTaskIn)
threadIn.IsBackground = True
threadIn.Start()
' wait for the process to finish
process.WaitForExit()
log is another sub to log to file, execute is the variable holding the _someApp.exe frommy initial post. I still don't know if the console to inputstream thread dows it right, because my wrapped app had no input as it seems. May someone spotts an error...
For my purposes, hmm it works like I need it
Greetz,
GHad
Code inside main
How about for writing to the app:
Dim sw as IO.StreamWriter = process.StandardInput
sw.WriteLine("Boo")
and for reading from the standard output:
Dim sr As IO.StreamReader = process.StandardOutput
Do
aString = sr.ReadLine()
Loop Until (sr.EndOfStream)