how to drag a file and get path of it - vb.net

How to implement a Panel in Winform , when a user drags a file on it (a simple .txt file) , it should accept it and stores its path into some variable called filepathname etc. which can be used earlier. I could find examples on how to implement drag and drop but not on how to get the path and store it for use later in the program.
Using : Visual Studio 2008 - Vb.net
Thanks!

I found this in this MSDN page
The code below is the modificated ones
Private Sub Panel1_DragEnter(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DragEventArgs) Handles Panel1.DragEnter
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
e.Effect = DragDropEffects.All
End If
End Sub
Private Sub Panel1_DragDrop(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DragEventArgs) Handles Panel1.DragDrop
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
Dim MyFiles() As String
Dim i As Integer
' Assign the files to an array.
MyFiles = e.Data.GetData(DataFormats.FileDrop)
'If there are more than one file, set first only
'If you want another restrictment, please edit this.
filepathname = MyFiles(0)
End If
End Sub

Related

How to refresh OpenFileDialog .txt file in Label (VB)?

My VB application should read text using a StreamReader and show the .txt file contents in a label:
Private Sub FileLocationButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FileLocationButton.Click
OpenFileDialog1.ShowDialog()
End Sub
Private Sub OpenFileDialog1_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
If OpenFileDialog1.FileName <> "" Then
Dim SR As New StreamReader(OpenFileDialog1.FileName)
Do Until SR.EndOfStream
Label6.Text = Label6.Text & SR.ReadLine & vbCrLf
Loop
SR.Close()
End If
End Sub
I am writing and saving the text file in MS Word etc. and would like to view the updated version of the file (the text) in the vb app.
Therefore:
I have added a timer and would like to know what code would allow the application to refresh the label with it's new text (from the .txt file) every 3 seconds so that the new content I just typed in MS Word/Notepad etc. will show?
You can use a timer to refresh the text in the label. In the form designer, drag a Timer from the toolbox onto your main form (Form1). Add a FilePath property to your preferences form (Preferences1) and use it to store the path selected in the OpenFileDialog. When you show the preferences form, save its path in a class level variable in the main form and start the timer with an interval of 3000 (this is milliseconds, so 3000 is 3 seconds). In the timer Tick event, read the file again and replace the text in the label. Note that the following code uses File.ReadAllText to read the file (and close it) in one statement.
In the main form (Form1) you have this code
Private textFile As String
Sub PrefButton_Click(sender As Object, e As EventArgs) Handles PrefButton.Click
Using pref As New Preferences1
pref.ShowDialog
textFile = pref.FilePath
End Using
If textFile <> "" Then Label6.Text = File.ReadAllText(textFile)
Timer1.Interval = 3000
Timer1.Start
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) _
Handles Timer1.Tick
If textFile <> "" Then Label6.Text = File.ReadAllText(textFile)
End Sub
In the preferences form (Preferences1) you have this code
Private myPath As String
Public ReadOnly Property FilePath As String
Get
Return myPath
End Get
End Property
Private Sub FileLocationButton_Click(sender As Object, e As EventArgs) _
Handles FileLocationButton.Click
If OpenFileDialog1.ShowDialog = DialogResult.OK Then
myPath = OpenFileDialog1.FileName
End If
End Sub

Get files one at a time from a folder in VB.NET

I am trying to read some text files path in a folder sequentially. However, I get only the first file.
I need to get the first file, execute a timer, get the next file path, execute a timer right up to the last file in the folder, and stop. How can I get around this?
Private zMailbox As String = "c:\Fold\"
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles Button1.Click
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Timer1.Tick
Dim finfo As New IO.DirectoryInfo(zMailbox)
For Each fi In finfo.GetFiles("*.txt")
TextBox1.Text = fi.FullName
Next
End Sub
Thanks to the contributions below I got the code to work with the text box value. However, it gives the index count instead of the path which I want to retrieve.
Private zMailbox As String = "c:\Fold\"
Dim files As FileInfo()
Dim index As Integer = 0
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles Button1.Click
Dim finfo As New IO.DirectoryInfo(zMailbox)
files = finfo.GetFiles("*.txt")
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Timer1.Tick
If index >= files.Length Then
index = 0
End If
TextBox1.Text = (ListBox1.Items.Add(files(index)))
index += 1
End Sub
Your code loads all the files in the Timer event and assign them to the TextBox1.Text property inside the loop. Every loop overwrites the data that has been written in the previous loop.
At the end of the loop you see only the last value.
To show sequentially the files inside the Timer Tick event, you need to read the directory content before starting the Timer in a global FileInfo array. Another global variable will be used as indexer to show a particular file from this FileInfo array in your Timer.Tick event.
The index will be incremented and, at the next Tick, you could show the next file
Dim files as FileInfo()
Dim index As Integer = 0
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Dim finfo As New IO.DirectoryInfo(zMailbox)
files = finfo.GetFiles("*.txt")
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
if index >= files.Length Then
index = 0
End If
TextBox1.Text = files(index)
index += 1
End Sub
EDIT
According to your comment, you need to set the MultiLine property of the TextBox to true (using the form designer) and then, at every Tick, instead of replacing the Text property, append to it
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
if index >= files.Length Then
return ' Reached the end of the array. Stop the Timer???
End If
TextBox1.AppendText(files(index) & Environment.NewLine)
index += 1
End Sub
As a side note, if you want to show all file names together then it is not clear why you need a timer at all.
You could get the same result with code like this
Dim finfo As New IO.DirectoryInfo(zMailbox)
Dim files = finfo.EnumerateFiles("*.txt")
TextBox1.Text = string.Join(Environment.NewLine, files.Select(Function(x) x.FullName).ToArray())
On the original code you posted you where getting all files in the for loop each time the timer clicks.
After reading steve answer, and your comments, probably you always got all the files, but you override the textbox.text value.
TextBox1.Text += < String > & vbNewLine
Where < String >, of course, is the string returned by DirectoryInfo.GetFiles()
I think steve answer works just fine, but you are not implementing it well.
I would try and make this as easy as possible for you. You Microsoft's Reactive Framework for this. Just NuGet "Rx-Main".
Here's what you can then do:
finfo.GetFiles("*.txt").ToObservable() _
.Zip(Observable.Interval(TimeSpan.FromSeconds(1.0)), Function(f, _) f.Name) _
.ObserveOn(TextBox1) _
.Subscribe(Function(n) textbox_text += n + Environment.NewLine)
That's it. No timers. No separate methods. No need for module-level variables. Just one line of code and you're done.
It's processed on a background thread and then marshalled back to the UI via the .ObserveOn(TextBox1) call.
You can even keep a reference to the IDisposable returned by the .Subscribe(...) call to terminate the observable (timer) early.
Simple.
This seems a bit Rube Goldberg-ish. Just get all the files and loop through them in your Button_Click method:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim finfo As New IO.DirectoryInfo(zMailbox)
For Each fi In finfo.GetFiles("*.txt")
TextBox1.Text = fi.FullName
Next
End Sub

Converting drag and drop application that shows directory into showing hash

I am having trouble converting this code into allowing me to drop files into my application and my application create a message box saying its md5 hash code. Currently, I have the code to give the directory of the file I dropped in.
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.AllowDrop = True
End Sub
Private Sub Form1_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop
Dim files() As String = e.Data.GetData(DataFormats.FileDrop)
For Each path In files
MsgBox(path)
Next
End Sub
Private Sub Form1_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragEnter
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
e.Effect = DragDropEffects.Copy
End If
End Sub
End Class
Seems like you have most of the code you need, only needs a function to calculate the md5, and then you can plug that into your message box:
MsgBox(ComputeMD5Hash(path))
Here is the function, taken mostly from this Microsoft Support Article
Private Function ComputeMD5Hash(ByVal path As String) As String
Dim tmpSource() As Byte
Dim tmpHash() As Byte
'Create a byte array from source data.
tmpSource = My.Computer.FileSystem.ReadAllBytes(path)
'Compute hash based on source data.
tmpHash = New Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(tmpSource)
Dim i As Integer
Dim sOutput As New System.Text.StringBuilder(tmpHash.Length)
For i = 0 To tmpHash.Length - 1
sOutput.Append(tmpHash(i).ToString("X2"))
Next
Return sOutput.ToString()
End Function
In-case you want to drop a directory and get all the hashes of the files inside you first need to check if you're dealing with a file or a folder, if its a folder you loop over all the files inside and call the function for each one, which would make your DragDrop event handler look something like this, and have the added benefit both files and folders can be taken care of.
Private Sub Form1_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop
Dim files() As String = e.Data.GetData(DataFormats.FileDrop)
For Each path In files
If IO.File.GetAttributes(path) = FileAttribute.Directory Then
'Dealing with a Directory
Dim di As New IO.DirectoryInfo(path)
Dim fiArr As IO.FileInfo() = di.GetFiles()
Dim fri As IO.FileInfo
For Each fri In fiArr
MessageBox.Show(fri.FullName & " " & ComputeMD5Hash(fri.FullName))
Next fri
Else
'Dealing with a File
MessageBox.Show(path & " " & ComputeMD5Hash(path))
End If
Next
End Sub

Copy folders and exclude folder

I have a code that copy a folder to another location through textboxes. Textbox1 where the user can specify which folder to copy and textbox2 that the user can browse for a destination folder.
If Textbox1 is the path to "My documents" an error occur saying:
Access to path C:\Users\%USERNAME%\Documents\My Music is denied.
"My Music" is a hidden folder in "My document" that is checked as "hide protected operating system files" by windows 7. I am using Visual Studio 2005 and new in VB.net, can anybody take a look at this code and tell me a way to exclude folders to copy?
Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
Dim fs As Object = CreateObject("Scripting.FileSystemObject")
Dim sFolderpath As String = TextBox1.Text
Dim sourceFolderName As String = System.IO.Path.GetFileName(sFolderpath)
Dim strDate As String = DateTime.Now.ToString("yyyy-MM-dd")
Dim dFolderpath As String = System.IO.Path.Combine(TextBox6.Text, strDate)
fs.createfolder(dFolderpath)
dFolderpath = System.IO.Path.Combine(dFolderpath, sourceFolderName)
fs.createfolder(dFolderpath)
fs.copyfolder(sFolderpath, dFolderpath)
End Sub
I'd suggest splitting the problem into 4 subs. Firstly two subs to allow users to select a folder they desire for source and destination. The a button click event that starts the copying and finally a sub that actually handles the copying.
Try this on for size:
Dim CopyFromPath As String
Dim CopyToPath As String
Private Sub TextBox1_MouseClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.MouseClick
Dim fldbroser1 As New FolderBrowserDialog
fldbroser1.RootFolder = Environment.SpecialFolder.MyMusic
fldbroser1.ShowDialog()
CopyFromPath = fldbroser1.SelectedPath
End Sub
Private Sub TextBox2_MouseClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.MouseClick
Dim fldbroser1 As New FolderBrowserDialog
fldbroser1.RootFolder = Environment.SpecialFolder.MyComputer
fldbroser1.ShowDialog()
CopyToPath = fldbroser1.SelectedPath
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
CopyAllFiles(CopyFromPath, CopyToPath)
End Sub
Private Sub CopyAllFiles(ByVal CopyFromPath As String, ByVal CopyToPath As String)
If Not Directory.Exists(CopyToPath) Then
Directory.CreateDirectory(CopyToPath)
End If
For Each filee As String In Directory.GetFiles(Path.GetDirectoryName(CopyFromPath))
Dim dest As String = Path.Combine(CopyToPath, Path.GetFileName(filee))
File.Copy(filee, dest)
Next
For Each folder As String In Directory.GetDirectories(Path.GetDirectoryName(CopyFromPath))
Dim dest As String = Path.Combine(CopyToPath, Path.GetFileName(folder))
CopyAllFiles(folder, dest)
Next
End Sub
You will need to import System.IO for this to work. Fell free to ask any questions if you have trouble with the code. Good luck learning VB, it can be annoying at times but it's pretty useful.

drag and drop to checkedlistbox

I have a checkedlistbox and I want to drag and drop only image extensions and not text files.
so how do I get it done.
I am able to drag and drop all file formats but I need only image files.
Here is my code:
Private Sub CheckedListBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles CheckedListBox1.DragDrop
Dim Files As String() = CType(e.Data.GetData(DataFormats.FileDrop), String())
For Each FileName As String In Files
CheckedListBox1.Items.Add(FileName, CheckState.Checked)
Thumbcontrol1.AddThumbnail(FileName)
Next
End Sub
Private Sub CheckedListBox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles CheckedListBox1.DragEnter
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
e.Effect = DragDropEffects.Copy
End If
End Sub
Just check each file name's extension.
Private Shared ReadOnly SupportedExtensions As String() = {".jpg", ".jpeg", ".gif"}
Private Sub CheckedListBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles CheckedListBox1.DragDrop
Dim Files As String() = CType(e.Data.GetData(DataFormats.FileDrop), String())
For Each FileName As String In Files
Dim Extension As String = Path.GetExtension(FileName).ToLower
If Array.IndexOf(SupportedExtensions, Extension) <> -1 Then
CheckedListBox1.Items.Add(FileName, CheckState.Checked)
Thumbcontrol1.AddThumbnail(FileName)
End If
Next
End Sub
You may want to add similar code to the DragEnter method to show DragDropEffects.None if there are no picture files in the dragged file list.
Something like this (you'll need to add in more file extensions):
Dim Files As String() = CType(e.Data.GetData(DataFormats.FileDrop), String())
For Each FileName As String In Files
If FileName.Contains(".jpg") Or FileName.Contains(".bmp") Then
CheckedListBox1.Items.Add(FileName, CheckState.Checked)
Thumbcontrol1.AddThumbnail(FileName)
End If
Next
You will also need to account for the case of the filenames.