I need to pass a string into the ProcessStartInfo for ffmpeg so that I can call the dim.Argument and have it append the strings and variables from code as I parse through the files.
I have the current filename.mp3 that the code sees in movedFileInfo but it won't allow me to append it to the string using & operators... help?
I know there may be one other way to do this utilizing the ffmpeg command in separate function to simply loop through a directory using "for" but I've not found a successful command for running my ffmpeg.exe nor the ffprompt in windows. I also need to append a carriage return when I write to merge.txt but can't find an example... I'm new to vba.
These commands work but vba is complaining about the & operator in my string with the error The operator '&' is not defined for types 'String' and 'System.IO.FileInfo'.
So what I understand is that the string I'm passing into psi.Arguments doesn't like the fact that I'm sending it a string and a variable appended using the & operator... do I simply use a comma or how do I append the variable movedFileInfo to ffmpeg -i? psi is defined above as ProcessStartInfo... so I'm not sure what types vb recognizes for it... I haven't found info on ProcessStartInfo to kick off my ffmpeg exe.
See code below:
Imports System
Imports System.IO
Imports System.Text.RegularExpressions
Public Class Form1
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
'videos are from SD card always on I:\Private\AVCHD\BDMV\STREAM\
'store files to RAID drives in folders structured as :
' F:\BUILD\FLIGHT#\CAM#\<TAIL_NUMBER>_FLT_<FLT_NUMBER>_UTC_<START_UTC_TIME>_CAM_<CAM_NUMBER>.MTS
'set base dir as directory F:\
Dim dir As String = "C:\"
Dim video_card_dir As String = "C:\1bak\" '"I:\Private\AVCHD\BDMV\STREAM\"
Directory.SetCurrentDirectory(dir)
Dim new_flightnum_directory = dir & Me.BUILD.Text & "\" & FLT.Text & "\"
'establish new video dir> F: \ BUILD \ FLIGHT # \ CAM # \
Dim new_video_directory = dir & Me.BUILD.Text & "\" & FLT.Text & "\" & Me.CAM.Text & "\"
'establish new filename to rename the video file
' TAIL # FLT #
Dim new_filename As String = TAIL.Text & "_" & FLT.Text & "_" & UTC.Text & "_" & CAM.Text
Dim ffmpeg As String = "C:\ffmpeg\bin\ffmpeg.exe"
'****FFMPEG required variables
Dim psi As ProcessStartInfo = New ProcessStartInfo("C:\ffmpeg\bin\ffmpeg.exe")
Dim proc As Process = Process.Start(psi)
psi.UseShellExecute = True
psi.CreateNoWindow = True
'****end FFMPEG required variables
'!!!!!!!!!!!!!!!!!!!!!!!!!!!need to add the processing below to the IF statement aboev so that if the folders exist, the video processing doesn't attempt to run on existing files
' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~START - MOVE THIS DOWN BELOW CREATION OF FILE STRUCTURE WHEN DOEN DEBUGGING************
'***START MOVING the files from the card to the new directory****
For Each foundFile As String In My.Computer.FileSystem.GetFiles(video_card_dir, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, "*.MTS")
Dim foundFileInfo As New System.IO.FileInfo(foundFile)
My.Computer.FileSystem.MoveFile(foundFile, new_video_directory & foundFileInfo.Name)
Next
For Each foundFile As String In My.Computer.FileSystem.GetFiles(video_card_dir, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, "*.MTS")
Dim movedFileInfo As New System.IO.FileInfo(foundFile)
psi.Arguments = "ffmpeg -i " & movedFileInfo & " -vcodec -c libx264 " & movedFileInfo & ".mp4"
psi.ToString()
'proc = Process.Start(psi)
'***convert each MTS file in the new directory to MP4****
'Writes filenames to merge.txt as " path\to\merge.txt , 'file ' F:\path\to\ file1 .MP4 '" so that ffmpeg can merge, then rename
'My.Computer.FileSystem.WriteAllText(new_video_directory & "merge.txt", "file '" & movedFileInfo & ".mp4'" & vbCrLf, True)
'>>>>need to add carriage return to text file
'NOW CAPTURE FILENAMES OF MP4 and MERGE INTO 1 MP4 FILE
' merge all F:\path\to\merge.txt to merge the files & merge them
'psi.Arguments = "ffmpeg -f concat -i " & new_video_directory & "merge.txt -c copy " & new_filename & ".mp4"
proc = Process.Start(psi)
Next
'***END MERGE FILES***
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~* END - MOVE
'***START CREATE STORAGE DIRECTORY STRUCTURE ***
'Verify if the build # directory exists?
If My.Computer.FileSystem.DirectoryExists(dir & Me.BUILD.Text) Then
MessageBox.Show("The build directory exists, moving on to create subdirectories")
Else
Try
'create the new directory F:\ build \ FLIGHT #
My.Computer.FileSystem.CreateDirectory(dir & Me.BUILD.Text)
MessageBox.Show("The build directory" & dir & Me.BUILD.Text & " was created.")
Catch ex As Exception
MessageBox.Show("Doh! The build directory could not be created! Error: " & ex.Message, "Error creating directory.", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End If
'verify if the flight num directory exists - or create it
If My.Computer.FileSystem.DirectoryExists(new_flightnum_directory) Then
MessageBox.Show("The flight # folder already exists! Check that you have the right Flight #.")
Else
Try
'create the new directory F:\ BUILD \ FLIGHT #
My.Computer.FileSystem.CreateDirectory(new_flightnum_directory)
'Now create new subDirectories
My.Computer.FileSystem.CreateDirectory(new_video_directory)
MessageBox.Show("The new flight directory & video CAM subdirectories have been created! The videos will be moved and files converted now which will take some time.")
Catch ex As Exception
MessageBox.Show("Doh! The flight num or CAM directory could not be created! Error: " & ex.Message, "Error creating directory.", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End If
'***END CREATE STORAGE DIRECTORY STRUCTURE ***
MessageBox.Show("new merged video file has been created in " & dir & Me.BUILD.Text & "\" & Me.CAM.Text)
End Sub
End Class
The problem is that the & operator in VB is used only to concatenate System.String objects. It's stricter than using + to concatenate. You can't use it to concatenate a String and a System.IO.FileInfo object together. What you want is to get the file name from the FileInfo object. It has an attribute, FileInfo.FullName which will return the full path of the file as a String - from the documentation.
Try instead:
For Each foundFile As String In My.Computer.FileSystem.GetFiles(video_card_dir, Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, "*.MTS")
Dim movedFileInfo As New System.IO.FileInfo(foundFile)
psi.Arguments = "ffmpeg -i " & movedFileInfo.FullName & " -vcodec -c libx264 " & movedFileInfo.FullName & ".mp4"
psi.ToString()
proc = Process.Start(psi)
Next
If you want to replace the .mts extension with .mp4, instead of simply appending .mp4 as this code does, please see this question.
Related
I need to search a directory with sub folders for one specific file and get that file's directory path. All the examples I've found has been to search for a file type and place those files in a list.The code I have returns a count of 1, but not the file name and path. What is the best way to achieve this?
Code
Dim folders As List(Of String) = New DirectoryInfo(imgLocation).EnumerateFiles(graphicName, SearchOption.AllDirectories).[Select](Function(d) d.FullName).ToList()
For Each file In folders
Debug.Write("file found " & file & vbCr)
Next
If you just want to find a specific file, you could:
Dim file As String = IO.Directory.EnumerateFiles("SearchDir",
"TheTargetFileName",
IO.SearchOption.AllDirectories).FirstOrDefault
Then you can get it's directory:
If file IsNot Nothing Then
Dim dir As String = IO.Path.GetDirectoryName(file)
'...
End If
In order to get information about files you need to use FileInfo class like the example below shows:
Sub SearchFiles()
Dim files() As String = IO.Directory.GetFiles("your directory root path here", "*.xml", SearchOption.AllDirectories)
For Each cFile In files
Dim fi As FileInfo = New IO.FileInfo(cFile)
Console.WriteLine("File name : " & fi.Name & " is in directory " & fi.Directory.Name & " or full path directory: " & fi.DirectoryName)
Next
End Sub
And for a single file use this:
Sub SearchSingleFile()
Dim ext As String = ".xml"
Dim files As List(Of String) = IO.Directory.GetFiles("put your directory here", "*" & ext, SearchOption.AllDirectories).Where(Function(fname) fname.ToLower.EndsWith("your filename here" & ext)).ToList
If files IsNot Nothing AndAlso files.Count > 0 Then
Dim fInfo As IO.FileInfo = New IO.FileInfo(files(0))
Console.WriteLine("File name : " & fInfo.Name & " is in directory " & fInfo.Directory.Name & " or full path directory: " & fInfo.DirectoryName)
End If
End Sub
put your directory path and change extension *.xml in your extension
I've been searching the net and have tried all the code found. My code should be simple but it's not working. I'm using a list to store image strings (but they do not have the extension on them). I want to test if the image file exists in a folder and if it does copy it. If it doesn't write to a file with the image name. The result I'm getting is all the files do not exists. But I checked and the files are there.
For Each image In GraphicList
ImgFile = ImgLocation & "\" & image & ".*"
Dim MoveFile As String
MoveFile = createFigFolder & "\" & image & ".*"
If Not System.IO.File.Exists(ImgFile) Then
Debug.Write("File does not exists : " & ImgFile & vbCrLf)
' file does not exist
Else
Debug.Write("File EXISTS : " & ImgFile & vbCrLf)
System.IO.File.Copy(ImgFile, MoveFile)
End If
Next
Here's the code that writes the GraphicList
Private Sub CreateGraphicsFunction(sender As Object, e As EventArgs)
Dim Regex = New Regex("infoEntityIdent=""(ICN.+?)[""].*?[>]")
Dim ICNFiles = Directory.EnumerateFiles(MoveToPath, "*.*", SearchOption.AllDirectories)
For Each tFile In ICNFiles
Dim input = File.ReadAllText(tFile)
Dim match = Regex.Match(input)
If match.Success Then
GraphicList.Add(match.Groups(1).Value)
Dim Regex2 = New Regex("<!ENTITY " & match.Groups(1).Value & " SYSTEM ""(ICN.*?[.]\w.+)")
Dim sysFileMatch = Regex2.Match(input)
If sysFileMatch.Success Then
ICNList.Add(sysFileMatch.Groups(1).Value)
Debug.Write("found ICN " & sysFileMatch.Groups(1).Value)
End If
End If
Next
End Sub
New Code to cycle through array and see if its entries match strings in Graphic Lists. This code doesn't work, but I think it's similar to what I want.
Dim fileEntries As String() = Directory.GetFiles(ImgLocation, ".*")
' Process the list of files found in the directory. '
Dim fileName As String
For Each fileName In fileEntries
If ICNList.Contains(fileName) Then
Debug.Write("File EXISTS : " & fileName & vbCrLf)
Else
Debug.Write("File does not exists : " & fileName & vbCrLf)
End If
Next
Join the list of filenames on the source list of files, using the filename without extension as the key. Then iterate over the results and copy each one
Dim fileNames = System.IO.Directory.GetFiles(imgLocation).Join(
graphicList,
Function(p) Path.GetFileNameWithoutExtension(p),
Function(f) f,
Function(p, f) p)
' create the directory first (does nothing if it already exists)
Directory.CreateDirectory(newLocation)
' copy each file
For Each fileName In fileNames
System.IO.File.Copy(fileName, Path.Combine(newLocation, Path.GetFileName(fileName)))
Next
I already extracted a folder with files from a RAR archive using the Unrar.exe I then want to edit the files within the extracted folder and then Re-rar that folder back into a password protected RAR archive. Either that, or append the existing RAR archive. Either way, the main goal is to update the files within the password protected archive. But I can't seem to figure out how to compress the folder again. My code as follows:
Imports System.IO
Public Class Form1
'establish the application directory and set it as a string to plugin later when needed
Dim MAINDIR As String = AppDomain.CurrentDomain.BaseDirectory
Private Sub UNRAR()
'if extracted folder does NOT exist then
If Not (System.IO.Directory.Exists(MAINDIR & "Credentials\")) Then
'set variables
Dim SourceFile As String = MAINDIR & "Credentials.rar"
Dim PassWord As String = "locker101"
Dim DestinationFolder As String = MAINDIR
'if extracted folder does not exist then
If Not IO.Directory.Exists(DestinationFolder) Then IO.Directory.CreateDirectory(DestinationFolder)
'unrar it and create extracted folder with the files
Dim p As New Process
p.StartInfo.FileName = MAINDIR & "UnRAR.exe"
p.StartInfo.Arguments = "-p" & PassWord & " x " & Chr(34) & SourceFile & Chr(34) & " " & Chr(34) & DestinationFolder & Chr(34)
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
p.Start()
End If
End Sub
Private Sub EDIT(ByVal ACCOUNT, ByVal USER, ByVal PASS, ByVal URL)
Do Until (System.IO.Directory.Exists(MAINDIR & "Credentials\"))
'does nothing on loop and keeps checking for the folder to exist
Loop
'confirms that the folder exists then begins to write to the file(s) inside
If (System.IO.Directory.Exists(MAINDIR & "Credentials\")) Then
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter(MAINDIR & "Credentials\" & ACCOUNT & ".txt", False)
file.WriteLine(USER)
file.WriteLine(PASS)
file.WriteLine(URL)
file.Close()
MsgBox("DONE")
Else
MsgBox("FAILED")
MsgBox("END existing")
MsgBox("END LOOP")
End If
APPENDRAR()
End Sub
Private Sub APPENDRAR()
End Sub
Private Sub DELETE()
'deletes the extracted folder, leaving behind only the password protected rar archive
My.Computer.FileSystem.DeleteDirectory(MAINDIR & "Credentials", False, False)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
UNRAR()
'sets textboxes' texts as strings then sends those values to the EDIT sub
Dim btn As Button = DirectCast(sender, Button)
Dim ACCOUNT As String = TB_account.Text
Dim USER As String = TB_user.Text
Dim PASS As String = TB_pass.Text
Dim URL As String = TB_url.Text
EDIT(ACCOUNT, USER, PASS, URL)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
End Sub
End Class
It should also be mentioned that I have the Unrar.exe and Rar.exe
files in the application folder. The same files found in the Winrar
directory. I added them to my project folder to use them.
A brief explanation of what is expected: The user will fill out 3 textboxes (username, password, website url) then they will click a button. The button takes the text in each textbox as values then creates strings of those values. It then passes these string values onto the sub which UNRARS the RAR archive, then once the folder is extracted, it either overwrites any existing file in that folder or creates a new one. Then after that, it should repack this newly edited folder back into a RAR archive with the same password as before, then deletes the extracted folder and the old RAR archive (UNLESS I can just append them back into the original archive, then I would not have to make an "updated" archive.)
UPDATE:
Dim SourceFile As String = MAINDIR & "Credentials\"
Dim PassWord As String = "locker101"
Dim DestinationFolder As String = MAINDIR
'if extracted folder does not exist then
'If Not IO.Directory.Exists(DestinationFolder) Then IO.Directory.CreateDirectory(DestinationFolder)
'unrar it and create extracted folder with the files
Dim p As New Process
Dim bbs As String = "-p" & PassWord & " u " & Chr(34) & MAINDIR & "ass.rar" & Chr(34) & " " & Chr(34) & SourceFile & Chr(34)
p.StartInfo.FileName = MAINDIR & "Rar.exe"
p.StartInfo.Arguments = bbs
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
p.Start()
This seems to work but it seems to not just add the "Credentials" folder but every folder leading up to it starting from "Projects".
I finally figured it out. Just in case anyone else needed the answer, here it is.
Dim p0 As New Process
Dim createo As String
createo = "-p" & <PASSWORD> & " u -ep " & Chr(34) & <arhive.rar> & Chr(34) & " " & Chr(34) & <FILE TO REPLACE> & Chr(34)
p0.StartInfo.FileName = "Rar.exe"
p0.StartInfo.Arguments = createo
p0.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
p0.Start()
Example for the string
createo = "-p" & TB_BIGKEY.Text & " u -ep " & Chr(34) & Form1.MAINDIR & "Users\" & TB_ID.Text & ".rar" & Chr(34) & " " & Chr(34) & Form1.MAINDIR & "Users\" & TB_ID.Text & ".txt" & Chr(34)
Which is read out 'tostring' as
-ppassyword u -ep "F:\Projects\PG\PG\bin\Debug\Users\Username.rar" "F:\Projects\PG\PG\bin\Debug\Users\Username.txt"
or <PASSWORD> <UPDATE> <EXLUDE PATHS> <RAR TO UPDATE> <FILE TO UPDATE WITH>
To not use a password, just remove the -ppassyword part.
I've been working on a script, a windows console application, that reads a .CSV for a file-path and other various information and then using System.IO.File.Copy to copy the file to a new directory and give it a new name. The file's im working with are .WAV files. Essentially I take a peek at the .CSV provided, then grab the filepath from there, then rename the file using different columns from the .CSV with dot-notation. I.E. Acc.Date.Name.Type.wav.
However, I'm experiencing "NotSupportedException" error on the line that copies and create the new file. The sub message is "The given paths format is not supported." Now, I've fairly new to VB code, I' assuming right now that .WAV format is not supported.
I'm not sure what all to add, if anything is needed let me know.
Here is the script so far:
Module Module1
Sub Main()
Dim fileLine As String
Dim aryTextFile() As String
Dim objReader As New System.IO.StreamReader("C:\Temp\EDCallFilePaths.csv")
Do While objReader.Peek() <> -1
fileLine = fileLine & objReader.ReadLine() & vbNewLine
aryTextFile = fileLine.Split(",")
If Not aryTextFile(7) = "null" Then
System.IO.File.Copy(aryTextFile(7), "C:\Temp\" & aryTextFile(0) & "." & aryTextFile(2) & "." & aryTextFile(3) & "." & aryTextFile(4) & "." & aryTextFile(5) & "." & aryTextFile(6) & ".wav")
fileLine = ""
End If
Loop
End Sub
End Module
I should note, column 7 is the filepath to the recording
I'm currently using the Directory.Move method to copy files from one location to another. What i would like to do is only move files with certain extensions (.dbf, .ini & .txt). If the original folder doesn't contain any of these files then i just want to create an empty directory
Current code I'm using is...
Dim n As Integer
If lb1.SelectedItems.Count = 0 Then Exit Sub
For n = 0 To UBound(AllDetails)
If AllDetails(n).uName & " - " & AllDetails(n).uCode & " - " & AllDetails(n).uOps = lb1.SelectedItem Then
If Not My.Computer.FileSystem.DirectoryExists(aMailbox & "\" & AllDetails(n).uFile) Then
Directory.Move(zMailbox & AllDetails(n).uFile, aMailbox & "\" & AllDetails(n).uFile)
lb3.Items.Add(AllDetails(n).uName & " - " & AllDetails(n).uCode & " - " & AllDetails(n).uOps)
Else
lb3.Items.Add(AllDetails(n).uName & " - " & AllDetails(n).uCode & " - " & AllDetails(n).uOps)
Exit Sub
End If
End If
Next
All the variables are declared and this works but moves the entire folder contents
One way to approach this is to use each extension as a search pattern for File.GetFiles, then use Directory.Move on each file returned. Something like this might help:
For Each OldFile As String In (From s In {".dbf", ".ini", ".txt"}
From f In Directory.GetFiles(zMailbox & AllDetails(n).uFile, s)
Select f)
Directory.Move(OldFile, aMailbox & "\" & AllDetails(n).uFile & "\" & Path.GetFileName(OldFile))
Next
if what you want is certain file extensions only? well Open File Dialog can filter that for you
Let's say you call this operation with a button click:
Dim fd As OpenFileDialog = New OpenFileDialog()
fd.Title = "Open File Dialog"
fd.InitialDirectory = "the initial directory you want to look at first"
'this filters the available files to be opened!
fd.Filter = "dbf files|*.dbf*|ini files|*.ini*|Text files|*.txt*"
fd.FilterIndex = 2 'set's the default files to open first as .ini
fd.RestoreDirectory = True
If fd.ShowDialog() = Windows.Forms.DialogResult.OK Then
'Copy the file to the location using the copyer subroutin
resulta.Text = fd.FileName.ToString
Copyer(fd.FileName.Tostring, "the location where you want to copy")
End If
End Sub
Now for the copying of the file, have a look at this subroutine. This subroutine checks first if the file exists. If it does, it deletes it, then copies the new file.
Public Sub Copyer(ByVal theFile As String, ByVal Lokasyon As String)
Try
Dim resultpath As String = Lokasyon
If System.IO.File.Exists(resultpath) = True Then
System.IO.File.Delete(resultpath)
'this deletes the file so you can overwrite it.
End If
My.Computer.FileSystem.CopyFile(theFile, resultpath)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Please let me know if this has helped you.