Run CMD in VB.Net using files as StandardInput and StandardOutput - vb.net

I'm trying to run a command in VB.Net such as:
my_program.exe < input_commands.txt > console_outputs.txt
I tried using the RedirectStandardInput :
myProcessStartInfo.FileName = programPath
myProcessStartInfo.RedirectStandardInput = True
myprocess.StartInfo = myProcessStartInfo
myprocess.Start()
And a StreamWriter to input my text file :
Dim myStreamWriter As StreamWriter = myprocess.StandardInput
For Each Line As String In System.IO.File.ReadLines(processInputFile)
myStreamWriter.WriteLine(Line)
Next
myStreamWriter.Close()
And a similar approach to get the ouputs to a file text :
startInfo.RedirectStandardOutput = True
Dim output As String = Process.StandardOutput.ReadToEnd()
But results are quite limited...
Could you please guide me toward a proper solution?

What I would do is, first read all the lines from the input_commands.txt file into mem:
Private Sub ReadInputFile(programPath as String, processInputFile as String, processOuputFile as String)
' Open the file to read from.
Dim readText() As String = File.ReadAllLines(processInputFile)
For Each s As String In readText
' Run the command through the cmd process
OutPutResults(programPath, s, processOuputFile)
Next
End Sub
and output (append) the results to console_output.txt:
Private Sub OutPutResults(programPath as String, strArgument as String, processOuputFile as String)
Dim p As New Process()
' Set it to run hidden from user
With p.StartInfo
.RedirectStandardOutput = True
.RedirectStandardError = True
.FileName = programPath
.Arguments = strArgument
.UseShellExecute = False
.CreateNoWindow = True
End With
p.Start()
' Save all output to the variable "strOutput"
Dim strOutput As String = p.StandardOutput.ReadToEnd()
' Wait for programPath .exe to finish before we handle it's output:
' (Sync method, meaning the thread won't continue until this one is finished. Use .exited if wanting to do Async)
' Also note that you can add a timeout in milliseconds to this if wanted. i.e. .WaitForExit(1000)
p.WaitForExit()
' Save the output to console_output.txt
File.AppendAllText(processOuputFile, strOutput)
End Sub
Note the above code is completely untested; I just whipped it up to give you the idea.

I wrote the following function that does the trick :
Sub runProgrammCommandsInputFileResultsOutputFile(ByVal myProcessStartInfo As ProcessStartInfo, ByVal myProcess As Process, ByVal programPath As String, ByVal commandsInputFile As String, ByVal resultsOutputFile As String)
myProcessStartInfo.FileName = programPath
myProcessStartInfo.RedirectStandardInput = True
myProcessStartInfo.RedirectStandardOutput = True
myProcessStartInfo.RedirectStandardError = True
myProcessStartInfo.UseShellExecute = False
myProcessStartInfo.CreateNoWindow = True
myProcess.StartInfo = myProcessStartInfo
myProcess.Start()
' Read commands from text file
Dim readCommandsInputFile() As String = System.IO.File.ReadAllLines(commandsInputFile)
' Open StreamWriter to StandardInput
Dim myStreamWriter As StreamWriter = myProcess.StandardInput
' Write read commands to Streamwriter openned to StandardInput
For Each s As String In readCommandsInputFile
myStreamWriter.WriteLine(s)
Next
myStreamWriter.Close()
'Read StandardOutput
Dim resultsOutputStrings As String = myProcess.StandardOutput.ReadToEnd()
' Write StandardOutput read to text file
System.IO.File.AppendAllText(resultsOutputFile, resultsOutputStrings)
End Sub

Related

convert jpg to avi vb.net

I try to convert my sequenced numbers photos jpg to output.mp4 or avi
but my output file is empty
the photos are renamed liked this out01.jpg , out02.jpg, etc. i have 10 frames (Photos)
I have try with this code:
Dim desk = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim args As String 'declare args
'args = " -i C:\mediapubisert\out%03d.jpg -r 10 C:\mediapubisert\out.mp4 "
args = " -i C:\mediapubisert\out%02d.jpg -c:v libx264 -r 30 -pix_fmt yuv420p C:\mediapubisert\out.mp4 "
Dim proc As New Process
Dim proci As New ProcessStartInfo
proci.FileName = My.Application.Info.DirectoryPath & "\ffmpeg.exe"
proci.Arguments = args
proci.WindowStyle = ProcessWindowStyle.Hidden
proci.CreateNoWindow = True
proci.UseShellExecute = False
proc.StartInfo = proci
proc.Start()
Do Until proc.HasExited = True
Me.Text = "Saving"
Loop
Me.Text = "your video done"
'My.Computer.FileSystem.CopyFile(TextBox1.Text, DestPath + TextBox1.Text)
MsgBox("Done")
Dim directoryName As String = "C:\mediapubisert\"
If i start explaining each and every term related to this topic, i may run out of letters... :(
Anyway, here's a simple code snippet to get started.Make sure you download this :)
Private Sub createAVideo(ByVal imageInputfolderName As String, ByVal outVideoFileName As String, ByVal Optional fps As Single = 12F, ByVal Optional imgSearchPattern As String = "*.png")
Dim vwriter As VideoWriter = New VideoWriter(outVideoFileName, New Accord.Extensions.Size(500, 500), fps, True) 'Make sure to change 500 with required height and width
Dim ReadImg As Accord.Extensions.Imaging.ImageDirectoryReader = New ImageDirectoryReader(imageInputfolderName, imgSearchPattern)
While ReadImg.Position < ReadImg.Length
Dim i As IImage = ReadImg.Read()
vwriter.Write(i)
End While
vwriter.Close()
End Sub
I never tried this myself but once heard about this library on SO , hope his helps :)

Process.Start() with "manage-bde.exe" crashing in VB.NET

I'm trying to start manage-bde.exe as a new process in VB.net but when it tries to start the proc, Bitlocker crashes. Could anyone please tell me what I'm doing wrong here? This code was converted from C# where it works all day long....
Code:
Private Sub btnLock_Click(sender As Object, e As EventArgs) Handles btnLock.Click
Dim drvSelected As String = cmbDriveSelect.SelectedValue.ToString()
Dim sysDirWithBDE As String = Environment.SystemDirectory + "\manage-bde.exe"
Dim lockStatus As String = String.Empty
' This is the code for the base process
Dim myProcess As New Process()
' Start a new instance of this program
Dim myProcessStartInfo As New ProcessStartInfo(sysDirWithBDE, " -lock " + drvSelected.Remove(2))
'Set Use Shell to false so as to redirect process run info to application
myProcessStartInfo.UseShellExecute = False
myProcessStartInfo.RedirectStandardOutput = True
myProcess.StartInfo = myProcessStartInfo
Try
myProcess.Start()
lblDriveLockMsg.Show()
Catch err As Exception
lblDriveLockMsg.Text = err.Message
End Try
'Read the standard output of the process.
lockStatus = myProcess.StandardOutput.ReadToEnd()
If lockStatus.Contains("code 0x80070057") Then
lblDriveLockMsg.Text = "Drive selected is not Bit Locker encrypted"
ElseIf lockStatus.Contains("code 0x80070005") Then
lblDriveLockMsg.Text = "Drive selected is in use by an application on your machine, force dismounting might result in data loss, please check and close any applications using the drive"
Else
lblDriveLockMsg.Text = lockStatus
End If
myProcess.WaitForExit()
myProcess.Close()
End Sub

How to run batch commands with dynamic statements?

I am writing code in VB.NET 2.0 and want to run batch commands for FTP using FTP -s:filename command.
I have a Batch file FTP.TXT for FTP Upload. It has the following statements:
OPEN <FPT SERVER IP>
USERNAME
PASSWORD
ASC
CD FOLDERNAME
PUT D:\DRFT000009.TXT FTPDRFTIN.DRFT000009
BYE
I have to dynamically change the filename in the Batch File. Now either I can create a Batch file at runtime and then read it or I got a code to set the input stream of the Process object. But its not working as desired.
This code runs fine but here I read a static batch file FTP.TXT from the computer:
Public Sub FTP4()
Dim psi As ProcessStartInfo
Dim totalerror As String = ""
psi = New ProcessStartInfo()
psi.FileName = "FTP.EXE"
psi.Arguments = " -s:D:\FTP.TXT"
psi.RedirectStandardError = True
psi.RedirectStandardOutput = True
psi.CreateNoWindow = True
psi.WindowStyle = ProcessWindowStyle.Hidden
psi.UseShellExecute = False
Dim process As Process = process.Start(psi)
Dim error2 As String = process.StandardError.ReadToEnd()
totalerror = totalerror & error2
process.WaitForExit()
Response.Write(totalerror)
End Sub
But I want somehow to get the FTP done with custom file name for each request. This is what I tried which is not working:
Public Sub FTP5()
Dim totalerror As String = ""
Dim BatchScriptLines(6) As String
Dim process As New Process
process.StartInfo.FileName = "FTP.EXE"
process.StartInfo.UseShellExecute = False
process.StartInfo.CreateNoWindow = True
process.StartInfo.RedirectStandardInput = True
process.StartInfo.RedirectStandardOutput = True
process.StartInfo.RedirectStandardError = True
process.Start()
process.BeginOutputReadLine()
Using InputStream As System.IO.StreamWriter = process.StandardInput
InputStream.AutoFlush = True
BatchScriptLines(0) = "OPEN <FPT IP ADDRESS>"
BatchScriptLines(1) = "USERNAME"
BatchScriptLines(2) = "PASSWORD"
BatchScriptLines(3) = "ASC"
BatchScriptLines(4) = "CD SFCD40DAT"
BatchScriptLines(5) = "PUT D:\DRFT000006.TXT FTPDRFTIN.DRFT000006"
BatchScriptLines(6) = "BYE"
For Each ScriptLine As String In BatchScriptLines
InputStream.Write(ScriptLine & vbCrLf)
Next
End Using
Dim error2 As String = process.StandardError.ReadToEnd()
totalerror = totalerror & error2
process.WaitForExit()
Response.Write(totalerror)
End Sub
Please advise how I can get the "FTP -s:filename" command executed in this case. Basically I want to do something similar to single line batch file execution which I not able to do.
Being a simple text file with a clear format, you could rewrite the file passing the parameters that need to be dynamically changed
Public Sub FTP4()
' Of course I assume that, at this point your program knows the exact values '
' to pass at the procedure that rebuilds the file'
PrepareFTPFile("D:\DRFT000006.TXT", "USERNAME", "PASSWORD")
' Now you call the original code.....
Dim psi As ProcessStartInfo
Dim totalerror As String = ""
psi = New ProcessStartInfo()
psi.FileName = "FTP.EXE"
psi.Arguments = " -s:D:\FTP.TXT"
....
End Sub
Public Sub PrepareFTPFile(fileToUpload as String, username as string, userpass as string)
Using sw = new StreamWriter("D:\FTP.TXT", False)
sw.WriteLine("OPEN <FPT IP ADDRESS>")
sw.WriteLine(username)
sw.WriteLine(userpass)
sw.WriteLine("ASC")
sw.WriteLine("CD SFCD40DAT")
sw.WriteLine("PUT " + fileToUpload + " FTPDRFTIN." + Path.GetFileNameWithoutExtension(fileToUpdload))
sw.WriteLine("BYE")
End Using
End Sub

Get data from Text file Print to Label

Just to keep this short I am working on a simple game to be played with anyone in the world who be interested in it, and because I am creating said game I decided to work on a simple launcher for the game one that pings the website for a version, checks that version with a stored text file with the game already installed and see if its a difference in version. If its a difference in version the launcher downloads the game. If the person does not already have the game installed it downloads the game for them.
Now for my problem why I am posting here, I am trying to get the text file already stored on the computer from the AppData directory to be read by the launcher and use it as an comparison with the version on the website. This is what I have for the on launch:
On Launch:
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim wc As New Net.WebClient
Text = wc.DownloadString("https://dl.dropboxusercontent.com/u/47132467/version.txt")
If My.Computer.FileSystem.FileExists("C:\Program Files\SC\SC.exe") Then
StartBtn.Enabled = True
StartBtn.Visible = True
Else
StartBtn.Enabled = False
StartBtn.Visible = False
End If
If My.Computer.FileSystem.FileExists("C:\Program Files\SC\Readme.txt") Then
ReadMeBtn.Visible = True
Else
ReadMeBtn.Visible = False
End If
End Sub
In short I am trying to figure out how to make a text file from the computer itself stored in AppData under Environ("AppData") & "\SC\version.txt" Been trying to figure out how to get the program to Read the local stored text file and put it as a variable where the program will compare it with the text file online. Thanks in Advanced! Sorry if I confuse anyone my brain is in derp mode trying to figure this out for a while now.
Here are 2 Functions Read & Write:
Public Function GetFileContents(ByVal FullPath As String, _
Optional ByRef ErrInfo As String = "") As String
Dim strContents As String
Dim objReader As StreamReader
Try
objReader = New StreamReader(FullPath)
strContents = objReader.ReadToEnd()
objReader.Close()
Return strContents
Catch Ex As Exception
ErrInfo = Ex.Message
End Try
End Function
Public Function SaveTextToFile(ByVal strData As String, _
ByVal FullPath As String, _
Optional ByVal ErrInfo As String = "") As Boolean
Dim Contents As String
Dim bAns As Boolean = False
Dim objReader As StreamWriter
Try
objReader = New StreamWriter(FullPath)
objReader.Write(strData)
objReader.Close()
bAns = True
Catch Ex As Exception
ErrInfo = Ex.Message
End Try
Return bAns
End Function
Call:
Dim File_Path as string = Environ("AppData") & "\SC\version.txt"
Dim versionStr as String = GetFileContents("File_Path")
Label1.text = versionStr
Label1.text.refresh ''// Sometimes this may be required depending on what you are doing!
if you want to read the version directly, rather than a text file, have a look at this code:
If My.Computer.FileSystem.FileExists(fn) Then
Dim fv As FileVersionInfo = FileVersionInfo.GetVersionInfo(fn)
If fv Is Nothing Then Return -1 'file has no version info
Return fv.FileMajorPart * 100000 + fv.FileMinorPart * 1000 + fv.FileBuildPart
Else
Return 0 'file does not exist
End If

Reading Console Output to write out an error log VB

I am running some commands on computers and I would like to have them output a seperate text file if the command cannot run.
For Each strUserName As String In strLines
Dim ReplaceCommand As String = sCommand.Replace("*", strUserName).Replace("$$$", saveFileDialog3.FileName & ".txt").Replace("###", exeSearch)
Shell("cmd.exe /c" & ReplaceCommand, AppWinStyle.Hide, True, )
' If Command Cannot Execute, List Why and Move onto Next Command
Using swrr As New StreamWriter(File.Open(ErrorLog, FileMode.OpenOrCreate))
If Console.Readline = "blahblah" Then swrr.WriteLine("FAIL") Else swrr.WriteLine("PASS")
End Using
Next
Am I on the right track? I am getting an output to a text file but its just one line ans always says PASS.
Several things: you're creating a new StreamWriter every time you want to write a line to it, instead of creating one then just writing to it when you need to. You're still using shell which is really basic, and not really suited for what you need. You should really be using a process for this.
I've written a function for you to use to execute the process instead of using the shell, which will return the output from the command execution to the ConsoleOutput variable, which you can then check for output strings.
Lastly, you should be using String.Format instead of replace to create the correct string for the command to run. For example:
Dim FirstName As String = "Jay"
Dim Age As String = "twenty"
Dim Greeting As String = String.Format("Hello {0}, I know you're {1} years old", FirstName, Age)
' Greetings value would be "Hello Jay, I know you're twenty years old"
So tweak the below to suit, specifically the Args variable, USING THE STRING.FORMAT function :)
Sub DoWork()
Dim ConsoleOutput As String = String.Empty
Using swrr As New StreamWriter(ErrorLog, True)
For Each strUserName As String In StrLines
ConsoleOutput = GetCMDOuput(strUserName, saveFileDialog3.FileName, exeSearch)
' If Command Cannot Execute, List Why and Move onto Next Command
If ConsoleOutput = "blahblah" Then swrr.WriteLine("FAIL") Else swrr.WriteLine("PASS")
Next
End Using
End Sub
Function GetCMDOuput(ByVal strUserName As String, ByVal strFileName As String, ByVal strExeSearch As String) As String
Dim Args As String = String.Format("/c -paramzero {0} -paramone {1} -paramtwo {2}", strUserName, strFileName, strExeSearch)
Dim CMD As New Process
CMD.StartInfo.FileName = "cmd.exe"
CMD.StartInfo.Arguments = Args
CMD.StartInfo.UseShellExecute = False
CMD.StartInfo.RedirectStandardInput = True
CMD.StartInfo.RedirectStandardOutput = True
CMD.StartInfo.CreateNoWindow = True
CMD.Start()
Dim retval As String = CMD.StandardOutput.ReadToEnd
CMD.WaitForExit()
Return retval
End Function