Jason Paradis
asked on
Preventing access/bypassing junction folders when calculating folder sizes in userprofile folders
I am attempting to write a program that displays the full folder sizes of a specific group of folders. Right now it's only set up for the userprofile "Documents" folder.
Here is my code:
Every time it runs, it obtains the correct directory but when it tries to access the junction folders (My Music, My Pictures, My Videos, etc.) under "Documents" I get an Unauthorized Access error, as I should. Junction folders are not accessible by design. However, I cannot figure out how to bypass those folders when trying to get the size so an exception doesn't get thrown.
Can anyone assist?
Here is my code:
Imports System
Imports System.IO
Public Class BackupperForm
Dim TotalSize As Long = 0
Public Function GetDirSize(RootFolder As String) As Long
Dim FolderInfo = New IO.DirectoryInfo(RootFolder)
For Each File In FolderInfo.GetFiles : TotalSize += File.Length
Next
For Each SubFolderInfo In FolderInfo.GetDirectories : GetDirSize(SubFolderInfo.FullName)
Next
Return TotalSize
End Function
Private Sub calButton_Click(sender As Object, e As EventArgs) Handles calButton.Click
TotalSize = 0 'Reset the counter
Dim TheSize As Long = GetDirSize(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "\Documents\")
MsgBox(FormatNumber(TheSize, 0) & " Bytes" & vbCr & _
FormatNumber(TheSize / 1024, 1) & " Kilobytes" & vbCr & _
FormatNumber(TheSize / 1024 / 1024, 1) & " Megabytes" & vbCr & _
FormatNumber(TheSize / 1024 / 1024 / 1024, 1) & " Gigabytes")
End Sub
End Class
Every time it runs, it obtains the correct directory but when it tries to access the junction folders (My Music, My Pictures, My Videos, etc.) under "Documents" I get an Unauthorized Access error, as I should. Junction folders are not accessible by design. However, I cannot figure out how to bypass those folders when trying to get the size so an exception doesn't get thrown.
Can anyone assist?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I don't mean to open this again because you helped immensely, however I'm having the exact same problem on a different event.
When the button is clicked I get an error regarding those junction folders again. I tried creating my own module and module extension to complete failure. Please bear with me as I am a very amateur programmer as you can tell by my code.
I assume a module and module extension need to be created for this event. However, I cannot figure out how to structure the extension code to work with my code above.
I would have created a new question but it seemed futile.
Thank you.
My.Computer.FileSystem.CopyDirectory(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "\Documents\", "\\destination\users\" & (Environment.UserName) & "\Documents\", True)
My.Computer.FileSystem.CopyDirectory(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "\Downloads\", "\\destination\users\" & (Environment.UserName) & "\Downloads\", True)
My.Computer.FileSystem.CopyDirectory(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "\My Pictures\", "\\destination\users\" & (Environment.UserName) & "\My Pictures\", True)
My.Computer.FileSystem.CopyDirectory(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "\Contacts\", "\\destination\users\" & (Environment.UserName) & "\Contacts\", True)
My.Computer.FileSystem.CopyDirectory(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "\Desktop\", "\\destination\users\" & (Environment.UserName) & "\Desktop\", True)
My.Computer.FileSystem.CopyDirectory(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "\Favorites\", "\\destination\users\" & (Environment.UserName) & "\Favorites\", True)
My.Computer.FileSystem.CopyDirectory(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "\My Videos\", "\\destination\users\" & (Environment.UserName) & "\My Videos\", True)
When the button is clicked I get an error regarding those junction folders again. I tried creating my own module and module extension to complete failure. Please bear with me as I am a very amateur programmer as you can tell by my code.
I assume a module and module extension need to be created for this event. However, I cannot figure out how to structure the extension code to work with my code above.
I would have created a new question but it seemed futile.
Thank you.
Probably the best way to handle this then is to Create your own CopyDirectory extension method which passes the parameters required for the .NET implementation of CopyDirectory you want to use. Within that method, you would surround the method call with a Try...Catch statement; e.g. -
-saige-
Imports System.IO
Module Module1
Sub Main()
Dim folders = New String() {"Documents", "Downloads", "My Pictures", "Contacts", "Desktop", "Favorites", "My Videos"}
Dim sourcePath As String = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
Dim targetPath As String = String.Format("\\destination\users\{0}", Environment.UserName)
Dim size As Long = Path.Combine(sourcePath, folders(0)).GetDirectorySize()
Console.WriteLine("{1} Bytes{0}{2} Kilobytes{0}{3} Megabytes{0}{4} Gigabytes", vbCrLf, FormatNumber(size, 0), FormatNumber(size / 1024, 1), FormatNumber(size / 1024 / 1024, 1), FormatNumber(size / 1024 / 1024 / 1024, 1))
For Each folder In folders
If Path.Combine(sourcePath, folder).CopyDirectory(Path.Combine(targetPath, folder), True) Then
Console.WriteLine("Successfully copied; {0} to; {1}", Path.Combine(sourcePath, folder), Path.Combine(targetPath, folder))
Else
Console.WriteLine("Copy failed for; {0} to; {1}", Path.Combine(sourcePath, folder), Path.Combine(targetPath, folder))
End If
Next
Console.ReadLine()
End Sub
End Module
Module Extensions
<System.Runtime.CompilerServices.Extension>
Function CopyDirectory(source As String, target As String, overwrite As Boolean) As Boolean
Dim result As Boolean = False
Try
My.Computer.FileSystem.CopyDirectory(source, target, overwrite)
result = True
Catch ex As Exception
result = False
End Try
Return result
End Function
<System.Runtime.CompilerServices.Extension>
Function GetDirectorySize(folder As String) As Long
Return New DirectoryInfo(folder).GetDirectorySize().Sum()
End Function
<System.Runtime.CompilerServices.Extension>
Iterator Function GetDirectorySize(folder As DirectoryInfo) As IEnumerable(Of Long)
For Each [file] In folder.EnumerateFiles
Try
Yield [file].Length
Catch ex As Exception
End Try
Next
For Each [child] In folder.EnumerateDirectories
Try
Yield [child].GetDirectorySize().Sum()
Catch ex As Exception
End Try
Next
End Function
End Module
-saige-
ASKER
It worked great, thanks! I wish I could re-open this post and give you assisted solution to your second answer.
No worries.
-saige-
-saige-
ASKER