start an executable application from resources without saving it somewhere - vb.net

If i have a file ( appres.exe ) in the resources of my VB 2008 Application (myVbApp.exe), how can I start from there? I don't want to save it (appres.exe) somewhere else before start, i want only myVbApp.exe, no more files.

Retrieve the EXE from the resources:
Dim l as System.IO.Stream = Reflection.Assembly.GetEntryAssembly.GetManifestResourceStream(String.Format("{0}.{1}", "ApplicationProjectName", "YourExeName"))
Then save it to temp folder - example method:
Private Sub SaveStreamToFile(ByVal p_stream As Stream, ByVal p_fileName As String)
Dim l_streamWriter As System.IO.FileStream = System.IO.File.Create(p_fileName)
Try
Dim l_bytes(65536) As Byte
Dim l_offset As Integer = 0
Dim l_readBytes As Integer
Do
l_readBytes = p_stream.Read(l_bytes, 0, 65536)
l_streamWriter.Write(l_bytes, 0, l_readBytes)
l_offset += l_readBytes
Loop While (l_readBytes > 0)
Debug.WriteLine("Num Of bytes Read: " + l_offset.ToString)
Catch ex As Exception
'log error
Finally
p_stream.Close()
l_streamWriter.Close()
End Try
End Sub
Now that you got the EXE in a temp folder, you can regulary lunch it using:
Process.Start("EXE_PATH")
And delete it once the process is done.

You can try this :
Dim SetupPath As String = Application.StartupPath & "\appres.exe"
Using sCreateMSIFile As New FileStream(SetupPath, FileMode.Create)
sCreateMSIFile.Write(My.Resources.yourexefilename, 0, My.Resources.Yourexefilename.Length)
End Using
Process.Start(SetupPath)

Related

Direct Streaming Method CopyTo does not find the end

I am reading a SSE by using this method
Public Shared Sub ReadStreamForever(ByVal stream As Stream)
Dim encoder = New UTF8Encoding()
Dim buffer = New Byte(2047) {}
Dim counter As Integer = 0
While True
If stream.CanRead Then
Dim len As Integer = stream.Read(buffer, 0, 2048)
counter = counter + 1
If len > 0 Then
Dim text = encoder.GetString(buffer, 0, len)
SSEApplication.Push(text) 'Here I collect the text slices to a List(of string) object
Else
Exit While
End If
Else
Exit While
End If
End While
SSEApplication.writer() 'Here I write the content to a .txt file
End Sub
With my example data it takes about 2 seconds. I would prefer not to read the stream into memory though and tried this method
Public Shared Sub ReadStreamForever1(ByVal stream As Stream)
Dim output As FileStream = File.OpenWrite("C:\Users\mini_dataset.txt")
While True
If stream.CanRead Then
stream.CopyTo(output)
Else
Exit While
End If
End While
End Sub
But the process ends up in an endless loop (I guess) at least to me it looks like the end of the stream can not be found. I can break the process after a few seconds and all the data are in the .txt file. Any idea what I can do to get the direct stream to file method working?
Stream.CanRead tells you whether a stream supports reading. Since it's apparently readable, While True will go on forever.
Let's verify whether the output Stream.CanWrite instead.
Public Shared Sub ReadStreamForever1(ByVal stream As Stream)
Using output As FileStream = File.OpenWrite("[Output file path]")
If output.CanWrite Then
stream.CopyTo(output)
End If
End Using
End Sub
If the process takes some time and you need to report its progress, you could read the stream using a buffer (I didn't add any error checking but of course a try/catch block should be used):
(Here, with 100 parts division commonly used by a ProgressBar)
Public Sub ReadStreamForever1(ByVal stream As Stream)
Dim BufferLength As Integer = 81920 'As the default stream buffer
Dim Buffer(BufferLength) As Byte
Dim BytesRead As Long = 0L
Using output As FileStream = File.OpenWrite("[Output file path]")
If output.CanWrite Then
Dim Part As Long = stream.Length \ 100
Dim PartCount As Integer = 0
Dim read As Integer = 0
Do
read = stream.Read(Buffer, 0, BufferLength)
If read = 0 Then Exit Do
If (BytesRead / Part > PartCount) Then
PartCount += 1
'ReportWriteProgress(PartCount)
End If
output.Write(Buffer, 0, read)
BytesRead += read
Loop
End If
End Using
End Sub

How to make a memory scanner faster?

I use VB.net 2008 to make a memory scanner and hacking program. I try some of their answers but still the memory scanner is slow. Maybe I have an improvement because before I scan a simple minesweeper and it takes 10 to 20 minutes. But now I can scan it for 2 to 10 seconds.
But I'm still not satisfied because when I try it in other games it takes 5 to 10 minutes or sometimes freeze due of too much long and too much usage of CPU.
Here is my code
Assume I declare all the API and some arguments for making a first scan
this code is a sample of scanning a 4 bytes address:
'' Command Button Event
btn_firstScan(....) Handle....
'' The Code
Me.Enabled = False
FirstScanThread = New Thread(AddressOf scanF)
FirstScanThread.IsBackground = True
FirstScanThread.Priority = ThreadPriority.Highest
FirstScanThread.Start() '' Thread Started for the First Scan.
End sub
Private Sub scanF() '' This is the Function is being Executed by the FirstScanThread at the btn_firstScan.
FirstScan(Of Int32)(pHandle, &H400000, &H7FFF0000, CType(txt_value.Text, Int32))
End Sub
The Sub FirstScan Executed by Sub scanF() that is being Executed by FirstScanThread in Command button btn_firstScan sub
Friend Sub FirstScan(Of T)(ByVal pHandle As IntPtr, ByVal minAddress As Int64, ByVal maxAddress As Int64, _
ByVal VALUE As T, Optional ByVal tempFileName As String = "temp.txt")
Dim thr As New Thread(AddressOf getProcessMemoryInfo) '' Get the Process Memory Info First
Dim memRange As New scanRange
memRange.minimum_address = minAddress
memRange.maximum_address = maxAddress
thr.IsBackground = True
thr.Priority = ThreadPriority.Highest
thr.Start(memRange)
thr.Join()
thr = New Thread(AddressOf dumpReadProcessMemory) '' Read All Bytes and Dump to the Temporary File
thr.IsBackground = True
thr.Priority = ThreadPriority.Highest
thr.Start()
thr.Join()
thr = New Thread(AddressOf readTempFile) '' Scan the Dump File in a Specific Set of Bytes [4 Bytes Aligned]
thr.IsBackground = True
thr.Priority = ThreadPriority.Highest
thr.Start(VALUE)
thr.Join()
setControlState(Me, True) '' If the Scan is Complete , The form is Ready Again to Receive Input
End Sub
Friend Sub dumpReadProcessMemory() '' This Sub is Use to Dump the All Bytes Read by ReadProcessMemory
Dim INFO As FileStream = New FileStream("FIRST.INFO.txt", FileMode.Open, FileAccess.Read, FileShare.Read)
Dim SR As StreamReader = New StreamReader(INFO) '' This is use to Obtain the Info that is needed to switch Page by Page Faster , No need to obtain in VirtualQueryEx
Dim BFILE As FileStream = New FileStream("FIRST.SCAN.txt", FileMode.Create, FileAccess.Write, FileShare.Write)
Dim BW As BinaryWriter = New BinaryWriter(BFILE) '' This is the Binary Writer for writing the READ Bytes
Dim BUFFER(0 To (1048576 * 128)) As Byte
Dim mem As New memoryInfo
While Not SR.EndOfStream '' While there is Page Found
mem.regionBaseAddress = CLng(SR.ReadLine.ToString)
mem.regionSize = CLng(SR.ReadLine.ToString)
ReadProcessMemory(pHandle, mem.regionBaseAddress, BUFFER, mem.regionSize, 0)
BW.Write(BUFFER, 0, mem.regionSize)
Thread.Sleep(1)
End While
SR.Close()
SR.Dispose()
INFO.Close()
INFO.Dispose()
BW.Close()
BFILE.Close()
BFILE.Dispose()
GC.Collect() '' Collect Garbage of BUFFER prevent CPU Stressing and RAM Leak, and i think i helps :P
End Sub
Friend Sub getProcessMemoryInfo(ByVal Obj As Object) '' Use to Get What PAGE is Readable/Writable and its Size
Dim FILE As System.IO.FileStream = New System.IO.FileStream("FIRST.INFO.txt", IO.FileMode.Create, FileAccess.Write, IO.FileShare.Write)
Dim SW As System.IO.StreamWriter = New System.IO.StreamWriter(FILE)
Dim BASE_ADDRESS As Int64 = CLng(Obj.minimum_address.ToString)
Dim MAX As Int64 = CLng(Obj.maximum_address.ToString)
Dim PAGE_COUNT As Integer = 0
While VirtualQueryEx(pHandle, BASE_ADDRESS, MBI, MBIsize)
If MBI.State = MemoryAllocationState.Commit Then
If MBI.zType = MemoryAllocationType.MEM_PRIVATE Or MBI.zType = MemoryAllocationType.MEM_IMAGE Then
Select Case MBI.AllocationProtect
'' Check if The Region is Readable/Writable and Executable
Case MemoryAllocationProtectionType.PAGE_CANWRITE
GoTo WRITE_INFO
Case MemoryAllocationProtectionType.PAGE_EXECUTE_READWRITE
GoTo WRITE_INFO
Case MemoryAllocationProtectionType.PAGE_WRITECOMBINE
GoTo WRITE_INFO
Case MemoryAllocationProtectionType.PAGE_EXECUTE_WRITECOPY
GoTo WRITE_INFO
Case MemoryAllocationProtectionType.PAGE_READWRITE
GoTo WRITE_INFO
Case Else
GoTo BYPASS_WRITE
End Select
WRITE_INFO:
SW.WriteLine(BASE_ADDRESS)
SW.WriteLine(MBI.RegionSize.ToInt32)
Thread.Sleep(1)
'PAGE_COUNT += 1
End If
End If
BYPASS_WRITE:
BASE_ADDRESS = BASE_ADDRESS + MBI.RegionSize.ToInt32
updateProgressTo(Me.pb_scanProgress, CInt(BASE_ADDRESS / MAX * 100))
End While
SW.Close()
SW.Dispose()
FILE.Close()
FILE.Close()
'Console.WriteLine(PAGE_COUNT)
End Sub
Public Sub readTempFile(ByVal Value As Object)
Dim TEMP As System.IO.FileStream = New System.IO.FileStream("TEMP.txt", IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.Write)
Dim TFILE As System.IO.FileStream = New System.IO.FileStream("FIRST.INFO.txt", IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Dim BFILE As System.IO.FileStream = New System.IO.FileStream("FIRST.SCAN.txt", IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Dim SW As System.IO.StreamWriter = New System.IO.StreamWriter(TEMP) '' Will Contain a list of Addressed found with the Value input.
Dim SR As System.IO.StreamReader = New System.IO.StreamReader(TFILE) '' Contains the Region baseAddesses and Size
Dim BR As System.IO.BinaryReader = New System.IO.BinaryReader(BFILE) '' Contains the Bytes being Dump Before and will now Read for Scanning.
Dim ADDRESS_POINTER As Int64 = 0
Dim mem As New memoryInfo
Dim TEMP_BYTE(0 To 4 - 1) As Byte
Dim BUFFER(0 To (1024 * 1024)) As Byte = 1024KB
Dim BUFFER_INDEX = 0
mem.regionBaseAddress = CLng(SR.ReadLine.ToString) ''Obtain the Staring Base Address
mem.regionSize = CLng(SR.ReadLine.ToString) '' Obtain the Region Size
ADDRESS_POINTER = mem.regionBaseAddress
While BR.Read(BUFFER, 0, BUFFER.Length) '' Fill the BUFFER with Data
BUFFER_INDEX = 0
While BUFFER_INDEX < BUFFER.Length - (4 - 1)
For a As Integer = 0 To (4 - 1) '' Compile the Read Bytes
TEMP_BYTE(a) = BUFFER(BUFFER_INDEX + a)
Next
If BitConverter.ToInt32(TEMP_BYTE, 0) = Value Then '' If the Compiled 4 Bytes = Value then
SW.WriteLine(formatHex(Hex(ADDRESS_POINTER).ToString))
'addItemTo(Me.lb_addressList, formatHex(Hex(ADDRESS_POINTER).ToString))
End If
ADDRESS_POINTER += 4
BUFFER_INDEX += 1
mem.regionSize -= 4
If mem.regionSize <= 0 Then
If SR.EndOfStream Then
Exit While
Else
''Switch to the Next Region
mem.regionBaseAddress = CLng(SR.ReadLine.ToString) ''Obtain the Staring Base Address
mem.regionSize = CLng(SR.ReadLine.ToString) '' Obtain the Region Size
ADDRESS_POINTER = mem.regionBaseAddress
End If
End If
End While
Thread.Sleep(1) '' Prevent 100% CPU Usage therefore the Form and other App avoid Crashing and Not Responding,
End While
BR.Close()
BFILE.Close()
SW.Close()
TEMP.Close()
SW.Dispose()
TEMP.Dispose()
SR.Close()
SR.Dispose()
TFILE.Dispose()
GC.Collect()
setControlState(Me, True) '' Make the Form Enabled
End Sub
NOTE: formatHex is only a Function that will put trailing Zeros in the front of Hex String if the Hex is not have Length of 8.
This code works in minesweeper in Windows XP 32 Bit and works fast in MINESWEEPER ONLY. I tried it in Grand Chase and Farm Frenzy; the scan won't ends because its still slow and even the scan is done, there is no address being found (maybe because in just tested it for 4 bytes).
I like to use VirtualProtectEx and VirtualAllocEx to enable to scan those PAGE_GUARD and write on it. Therefore I am able to obtain the specific address that I want but I can't do it because it is still slow. I make the PAGE_GUARD'ed PAGE into EXECUTE_READWRITE it will make more bytes to scan. It will make the App slower.

How to create sub folders when creating file?

i am making an application which involves reading chunks of an existing file and writing them to a new one... now, the problem is that the code i am currently using does not create subfolders and then file if a full path is given...
If i give it a path like this: C:\folder1\folder2\file.mp3 it gives an error because the folders folder1 and 2 does not exist, however, i would like it to create these subfolders if they do not exist while creating the file... thanks... here is my code:
Dim bytesRead As Integer
Dim buffer(40096) As Byte
Using inFile As New System.IO.FileStream(arch, IO.FileMode.Open, IO.FileAccess.Read)
Using outFile As New System.IO.FileStream(path & "\" & f, IO.FileMode.Create, IO.FileAccess.Write)
inFile.Seek(StartAt, IO.SeekOrigin.Begin)
Do
If astop.Text = 1 = False Then
If CurrentFsize - currtotal < buffer.Length Then
ReDim buffer(CurrentFsize - currtotal)
End If
bytesRead = inFile.Read(buffer, 0, buffer.Length)
If bytesRead > 0 Then
outFile.Write(buffer, 0, bytesRead)
currtotal += bytesRead
End If
Else
Exit Do
Exit Do
End If
Application.DoEvents()
Loop While bytesRead > 0 AndAlso currtotal < CurrentFsize
End Using
End Using
Yout should create the directories and subdirectories of path before creating the output file:
If(Not System.IO.Directory.Exists(path)) Then
System.IO.Directory.CreateDirectory(path)

How to check if the text file is open and close the text file?

I am trying to save the text file in this path:"C:\Test\test.txt" and when the file is already opened I need to check whether the file is opened and I need to close it before writing it to the file.
Here is the code for saving the file:
Dim myfile As String = "C:\Test\test.txt"
'Check if file exists
If System.IO.File.Exists(myfile) = True Then
'Delete it!
Dim fi As New FileInfo(myfile)
fi.Delete()
End If
Using sfdlg As New Windows.Forms.SaveFileDialog
sfdlg.DefaultExt = "amk"
sfdlg.Filter = "AquaMark Project|*.amk"
If sfdlg.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim SaveData As New gCanvasData
IO.Directory.CreateDirectory("C:\Test")
Dim w As New IO.StreamWriter("C:\Test\test.txt")
Dim i As Integer
For i = 0 To CheckedListBox1.Items.Count - 1
w.WriteLine(CheckedListBox1.Items.Item(i))
Next
w.Close()
With SaveData
frmDisplay.GCanvas1.UnselectCurrentAnotate()
.gAnnotates = frmDisplay.GCanvas1.gAnnotates
.Image = frmDisplay.GCanvas1.Image
End With
Using objStreamWriter As New StreamWriter(sfdlg.FileName)
Dim x As New XmlSerializer(GetType(gCanvasData))
x.Serialize(objStreamWriter, SaveData)
objStreamWriter.Close()
End Using
End If
End Using
If I am doing this way I am able to close the notepad process but I need to close the specific opened text file:
Dim Process() As Process = System.Diagnostics.Process.GetProcessesByName("notepad")
Process() = CType(Interaction.GetObject("C:\Test\test.txt"), Diagnostics.Process())
For Each p As Process In Process
p.Kill()
Next
I do not believe there is a property that will allow for you to check if the streamreader is open or not.
Best practice seems to be to .close the reader when done with it. (All in the method that it was used in.)
You could try a try block to handle the exception if you are still getting one.
May be able to find additional info and some sample code here. Good Luck.
MSDN! StreamReader
EDIT: You may be able to check using this. IO.File
Private Function CheckFile(ByVal filename As String) As Boolean
Try
System.IO.File.Open(filename, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)
FileClose(1)
Return False
Catch ex As Exception
Return True
End Try
End Function
What about :
If File.Exists("File1.txt") = False Then
File.CreateText("File1.txt").Close()
Else
Exit Sub
End If
If File.Exists("File2.txt") = False Then
File.CreateText("File2.txt").Close()
Else
Exit Sub
End If
End If
Private Sub IsFileOpen(ByVal file As FileInfo)
Dim stream As FileStream = Nothing
Try
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None)
Catch ex As IOException
If IsFileLocked(ex) Then
'do something here, either wait a few seconds, close the file if you have
'a handle, make a copy of it, read it as shared (FileAccess fileAccess = FileAccess.Read, FileShare fileShare = FileShare.ReadWrite).
'I dont recommend terminating the process - which could cause corruption and lose data
End If
Catch ex As Exception
End Try
End Sub
Private Shared Function IsFileLocked(exception As Exception) As Boolean
Dim errorCode As Integer = Marshal.GetHRForException(exception) And ((1 << 16) - 1)
Return errorCode = 32 OrElse errorCode = 33
End Function
The following function can be used to determine is a file is already open (True) or not (False). Action can then be based on the Function result.
Public Function IsFileOpen(ByVal xFileName As String, ByVal xFileChannel As Integer) As Boolean
' ************************************************************
' * Function: IsFileOpen
' * Purpose: To determine if a file is already open.
' * Can be used to determine if a file should be closed.
' * Syntax:
' * Dim bResult as Boolean
' *
' * bResult = IsFileOpen("C:\Test.txt", 1)
' *
' * OR
' *
' * If IsFileOpen("C:\Test.txt", 1) = True Then
' * Microsoft.VisualBasic.FileClose(1)
' * End If
' *
' ************************************************************
Try
Microsoft.VisualBasic.FileOpen(xFileChannel, xFileName, OpenMode.Input, OpenAccess.Read, OpenShare.Default)
Catch
' File Already Open Error Number = 55
If Trim(Err.Number.ToString) = "55" Then
Return True
Else
Return False
End If
End Try
End Function
I was having this problem with a .csv file my program attaches to an email. I added code to clear the Attachments collection in the MailMessage object then disposing the MailMessage and Attachment objects after the mail is sent. That appears to have fixed the problem.

What’s the best way to calculate the size of a directory in VB .NET?

I need to calculate the directory size in VB .Net
I know the following 2 methods
Method 1: from MSDN http://msdn.microsoft.com/en-us/library/system.io.directory.aspx
' The following example calculates the size of a directory
' and its subdirectories, if any, and displays the total size
' in bytes.
Imports System
Imports System.IO
Public Class ShowDirSize
Public Shared Function DirSize(ByVal d As DirectoryInfo) As Long
Dim Size As Long = 0
' Add file sizes.
Dim fis As FileInfo() = d.GetFiles()
Dim fi As FileInfo
For Each fi In fis
Size += fi.Length
Next fi
' Add subdirectory sizes.
Dim dis As DirectoryInfo() = d.GetDirectories()
Dim di As DirectoryInfo
For Each di In dis
Size += DirSize(di)
Next di
Return Size
End Function 'DirSize
Public Shared Sub Main(ByVal args() As String)
If args.Length <> 1 Then
Console.WriteLine("You must provide a directory argument at the command line.")
Else
Dim d As New DirectoryInfo(args(0))
Dim dsize As Long = DirSize(d)
Console.WriteLine("The size of {0} and its subdirectories is {1} bytes.", d, dsize)
End If
End Sub 'Main
End Class 'ShowDirSize
Method 2: from What's the best way to calculate the size of a directory in .NET?
Dim size As Int64 = (From strFile In My.Computer.FileSystem.GetFiles(strFolder, _
FileIO.SearchOption.SearchAllSubDirectories) _
Select New System.IO.FileInfo(strFile).Length).Sum()
Both these methods work fine. However they take lot of time to calculate the directory size if there are lot of sub-folders. e.g i have a directory with 150,000 sub-folders. The above methods took around 1 hr 30 mins to calculate the size of the directory. However, if I check the size from windows it takes less than a minute.
Please suggest better and faster ways to calculate the size of the directory.
Though this answer is talking about Python, the concept applies here as well.
Windows Explorer uses system API calls FindFirstFile and FindNextFile recursively to pull file information, and then can access the file sizes very quickly through the data that's passed back via a struct, WIN32_FIND_DATA: http://msdn.microsoft.com/en-us/library/aa365740(v=VS.85).aspx.
My suggestion would be to implement these API calls using P/Invoke, and I believe you will experience significant performance gains.
Doing the work in parallel should make it faster, at least on multi-core machines. Try this C# code. You will have to translate for VB.NET.
private static long DirSize(string sourceDir, bool recurse)
{
long size = 0;
string[] fileEntries = Directory.GetFiles(sourceDir);
foreach (string fileName in fileEntries)
{
Interlocked.Add(ref size, (new FileInfo(fileName)).Length);
}
if (recurse)
{
string[] subdirEntries = Directory.GetDirectories(sourceDir);
Parallel.For<long>(0, subdirEntries.Length, () => 0, (i, loop, subtotal) =>
{
if ((File.GetAttributes(subdirEntries[i]) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
{
subtotal += DirSize(subdirEntries[i], true);
return subtotal;
}
return 0;
},
(x) => Interlocked.Add(ref size, x)
);
}
return size;
}
This is a short and sweet code snippet that will get the job done. You just need to reset the counter before you call the function
Public Class Form1
Dim TotalSize As Long = 0
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
TotalSize = 0 'Reset the counter
Dim TheSize As Long = GetDirSize("C:\Test")
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
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
End Class
Big thanks #Jamie for Code and #Mathiasfk for translating to VB.net. I use it for my own Backup program which in default setting just backup the whole profile folder, it's a code which finally also is able to understand junction points and read more or less correct size. It's at least okay for Backup. :-)
I just had to put code within Try so it doesn't stop for folders it doesn't have access to, if you also could have such problem just use this (doesn't handle the error just skip it, you can add if important for you):
Imports System.IO
Imports System.Threading
Imports System.Threading.Tasks
Public Function GetFolderSize(ByVal path As String, Optional recurse As Boolean = True) As Long
Dim totalSize As Long = 0
Try
Dim files() As String = Directory.GetFiles(path)
Parallel.For(0, files.Length,
Sub(index As Integer)
Dim fi As New FileInfo(files(index))
Dim size As Long = fi.Length
Interlocked.Add(totalSize, size)
End Sub)
Catch ex As Exception
End Try
Try
If recurse Then
Dim subDirs() As String = Directory.GetDirectories(path)
Dim subTotal As Long = 0
Parallel.For(0, subDirs.Length,
Function(index As Integer)
If (File.GetAttributes(subDirs(index)) And FileAttributes.ReparsePoint) <> FileAttributes.ReparsePoint Then
Interlocked.Add(subTotal, GetFolderSize(subDirs(index), True))
Return subTotal
End If
Return 0
End Function)
Interlocked.Add(totalSize, subTotal)
End If
Catch ex As Exception
End Try
Return totalSize
End Function
Here this as short as I can get it.
It will display the size of the selected in a message box.
You're going to need a FolderBrowserDialog in the form for this to work.
Class Form1
Private Sub form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
If (FolderBrowserDialog1.ShowDialog() = DialogResult.OK) Then
Else : End
End If
Dim dInfo As New IO.DirectoryInfo(FolderBrowserDialog1.SelectedPath)
Dim sizeOfDir As Long = DirectorySize(dInfo, True)
MsgBox("Showing Directory size of " & FolderBrowserDialog1.SelectedPath _
& vbNewLine & "Directory size in Bytes : " & "Bytes " & sizeOfDir _
& vbNewLine & "Directory size in KB : " & "KB " & Math.Round(sizeOfDir / 1024, 3) _
& vbNewLine & "Directory size in MB : " & "MB " & Math.Round(sizeOfDir / (1024 * 1024), 3) _
& vbNewLine & "Directory size in GB : " & "GB " & Math.Round(sizeOfDir / (1024 * 1024 * 1024), 3))
Catch ex As Exception
End Try
End Sub
Private Function DirectorySize(ByVal dInfo As IO.DirectoryInfo, ByVal includeSubDir As Boolean) As Long
Dim totalSize As Long = dInfo.EnumerateFiles().Sum(Function(file) file.Length)
If includeSubDir Then totalSize += dInfo.EnumerateDirectories().Sum(Function(dir) DirectorySize(dir, True))
Return totalSize
End Function
End Class
VB Code based on Jamie's answer:
Imports System.Threading
Imports System.IO
Public Function GetDirectorySize(ByVal path As String, Optional recurse As Boolean = False) As Long
Dim totalSize As Long = 0
Dim files() As String = Directory.GetFiles(path)
Parallel.For(0, files.Length,
Sub(index As Integer)
Dim fi As New FileInfo(files(index))
Dim size As Long = fi.Length
Interlocked.Add(totalSize, size)
End Sub)
If recurse Then
Dim subDirs() As String = Directory.GetDirectories(path)
Dim subTotal As Long = 0
Parallel.For(0, subDirs.Length,
Function(index As Integer)
If (File.GetAttributes(subDirs(index)) And FileAttributes.ReparsePoint) <> FileAttributes.ReparsePoint Then
Interlocked.Add(subTotal, GetDirectorySize(subDirs(index), True))
Return subTotal
End If
Return 0
End Function)
Interlocked.Add(totalSize, subTotal)
End If
Return totalSize
End Function
Try this to get total size in GB
Dim fso = CreateObject("Scripting.FileSystemObject")
Dim profile = fso.GetFolder("folder_path")
MsgBox(profile.Size / 1073741824)
heres what i think is the best way to do it .
Imports System.IO
Public Class FolderSizeCalculator
Public Shared Function GetFolderSize(ByVal folderPath As String) As Long
Dim size As Long = 0
Try
Dim files As String() = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories)
For Each file As String In files
Dim fileInfo As New FileInfo(file)
size += fileInfo.Length
Next
Catch ex As Exception
' Handle any exceptions that may occur
End Try
Return size
End Function
End Class
You can call the GetFolderSize() method and pass in the path of the folder you want to calculate the size of, and it will return the size in bytes.
You can use it like this:
Dim folderSize As Long = FolderSizeCalculator.GetFolderSize("C:\MyFolder")
Console.WriteLine("Folder size: " & folderSize & " bytes")
..Please note that this method will fail if the user running the application doesn't have permission to read the folder or subfolders, you can handle that by using try catch block