NAS performance tester (C# and VB.Net)

This free utility benchmarks the read and write performance in megabytes per second of network attached storage connected through SMB/CIFS network shares.

NAS performance tester 1.700c screenshot
How it works: Temporary files of selectable sizes are generated and copied to and from the NAS a number of times, whereafter the average read and write speeds are calculated.

The utility is available compiled for .NET framework 4.x* with source code included:

Download NAS performance tester 1.700c

*If you only have Microsoft .NET framework version 2.0 installed, you can re-compile the program to that (or any newer .Net version installed on the PC) by running the script compile.vbs included in the zip file.

Note that reliable results depend on that the local computer drive, the test is being executed from, has faster read and write speeds than the NAS being tested. Also note that the program's method of generating the read speed test files on the NAS is specifically tuned for avoiding caching on network drives. This means that running the benchmark against local or iSCSI connected drives will give incorrect read speed results due to locally cached test files. Please use it only for testing network drives.

The standard disclaimer: The program is provided 'as is' without warranty of any kind. I have done my best to incorporate graceful exception handling and to test the code in different scenarios, so it shouldn't be able to do anything bad. The source code for the program is listed below.

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Threading;
using System.Reflection;

[assembly: AssemblyTitle("NAS performance tester 1.700c")]
[assembly: AssemblyDescription("A small C# utility for benchmarking the read and write performance of network attached storage")]
[assembly: AssemblyCompany("www.700c.dk")]
[assembly: AssemblyProduct("NasTester")]
[assembly: AssemblyCopyright("Creative Commons Attribution (CC BY 3.0) https://creativecommons.org/licenses/by/3.0/ Reference source https://www.700c.dk/?code-csharp-nas-performance")]
[assembly: AssemblyVersion("1.7.0.0")]
[assembly: CLSCompliant(true)]

public class NasPerformanceForm : Form
{
  private Label driveLetterLabel = new Label();
  private Label networkPathLabel = new Label();
  private Label fileSizeLabel = new Label();
  private Label loopsLabel = new Label();
  private Button benchmarkButton = new Button();
  private TextBox networkPath = new TextBox();
  private ComboBox driveLetter = new ComboBox();
  private ComboBox fileSize = new ComboBox();
  private ComboBox loops = new ComboBox();
  private TextBox resultArea = new TextBox();
  private Label infoLabel = new Label();
  private LinkLabel urlLabel = new LinkLabel();
  private bool loopBreak = false;
  private string testPath;
  private ulong testFileSize;
  private ulong testIterations;
  private string testType;
  private string localStoragePath;
  private Thread workerThread;
  private bool testIsActive = false;

  public NasPerformanceForm()
  {
    this.Text = "NAS performance tester 1.700c";
    this.Size = new Size(558, 400);
    this.Font = new Font("Microsoft Sans Serif", 8);
    driveLetterLabel.Location = new Point(5, 8);
    driveLetterLabel.Text = "NAS drive letter";
    driveLetterLabel.Size = new Size (83, 20);
    driveLetter.Location = new Point(90, 5);
    driveLetter.Size = new Size(33, 15);
    driveLetter.Items.AddRange(GetNetworkDriveLetters());
    if (GetNetworkDriveLetters().Length > 0)
    {
      driveLetter.SelectedIndex = 0;
    }
    networkPathLabel.Location = new Point(123, 8);
    networkPathLabel.Text = "or network path";
    networkPathLabel.Size = new Size(80, 20);
    networkPath.Location = new Point(205, 5);
    networkPath.Text = "";
    networkPath.Size = new Size(90, 20);
    fileSizeLabel.Location = new Point(302, 8);
    fileSizeLabel.Text = "File size";
    fileSizeLabel.Size = new Size(50, 20);
    fileSize.Location = new Point(352, 5);
    fileSize.Size = new Size(49, 15);
    fileSize.Items.AddRange(new object[]
      {"100",
       "200",
       "400",
       "800",
       "1000",
       "2000",
       "4000",
       "8000"});
    fileSize.SelectedIndex = 2;
    loopsLabel.Location = new Point(407, 8);
    loopsLabel.Text = "Loops";
    loopsLabel.Size = new Size(36, 20);
    loops.Location = new Point(443, 5);
    loops.Size = new Size(37, 15);
    loops.Items.AddRange(new object[]
      {"1",
       "2",
       "3",
       "4",
       "5",
       "10",
       "20",
       "40"});
    loops.SelectedIndex = 4;
    benchmarkButton.Location = new Point(487, 5);
    benchmarkButton.Size = new Size(50, 20);
    benchmarkButton.Text = "Start";
    resultArea.Location = new Point(5, 30);
    resultArea.Size = new Size(533,305);
    resultArea.ReadOnly = true;
    resultArea.Multiline = true;
    resultArea.ScrollBars = ScrollBars.Vertical;
    resultArea.WordWrap = false;
    resultArea.Text = "NAS performance tester 1.700c https://www.700c.dk/?nastester\r\n";
    resultArea.Font = new Font("Courier New", 8);
    infoLabel.Location = new Point(5, 341);
    infoLabel.Text = "For more information, visit";
    infoLabel.Size = new Size(140, 20);
    urlLabel.Location = new Point(143, 341);
    urlLabel.Text = "https://www.700c.dk/?code-csharp-nas-performance";
    urlLabel.Links.Add(0, 48, "https://www.700c.dk/?code-csharp-nas-performance");
    urlLabel.Size = new Size(300, 20);
    this.Controls.Add(driveLetterLabel);
    this.Controls.Add(driveLetter);
    this.Controls.Add(networkPathLabel);
    this.Controls.Add(networkPath);
    this.Controls.Add(fileSizeLabel);
    this.Controls.Add(fileSize);
    this.Controls.Add(loopsLabel);
    this.Controls.Add(loops);
    this.Controls.Add(benchmarkButton);
    this.Controls.Add(resultArea);
    this.Controls.Add(infoLabel);
    this.Controls.Add(urlLabel);
    benchmarkButton.Click += new EventHandler(benchmarkButton_Click);
    urlLabel.LinkClicked += new LinkLabelLinkClickedEventHandler(this.urlLabel_LinkClicked);
    this.ActiveControl = networkPath;
    if (IsFolderWritable(Path.GetDirectoryName(Application.ExecutablePath)))
    {
      localStoragePath = Path.GetDirectoryName(Application.ExecutablePath);
    }
    else // Write access to program folder denied, falling back to Windows temp folder as defined in the environment variables
    {
      localStoragePath = Path.GetTempPath();
    }
  }

  private void benchmarkButton_Click(object sender, EventArgs e)
  {
    if (!testIsActive)
    {
      int checkFileSize;
      int checkLoops;
      if ((!String.IsNullOrEmpty(driveLetter.Text) || (networkPath.Text.IndexOf("\\\\") == 0 && networkPath.Text.IndexOf("\\", 2) > 2)) &&
          int.TryParse(fileSize.Text, out checkFileSize) &&
          int.TryParse(loops.Text, out checkLoops))
      {
        if(checkFileSize <= 64000)
        {
          Thread newThread = new Thread(new ThreadStart(BenchmarkHandler));
          newThread.Start();
        }
        else
        {
          resultArea.AppendText("The maximum test file size is 64GB.\r\n");
          resultArea.Invalidate();
        }
      }
      else
      {
        resultArea.AppendText("Input invalid. Check drive letter or network path, file size and loops.\r\n");
        resultArea.Invalidate();
      }
    }
    else
    {
      loopBreak = true;
      resultArea.AppendText("Cancelling. Please wait for current loop to finish...\r\n");
      resultArea.Invalidate();
    }
  }

  private void urlLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  {
    string target = e.Link.LinkData as string;
    System.Diagnostics.Process.Start(target);
  }

  private void BenchmarkHandler()
  {
    testIsActive = true;
    loopBreak = false;
    benchmarkButton.Text = "Stop";
    if (String.IsNullOrEmpty(networkPath.Text))
    {
      testPath = driveLetter.Text + ":";
    }
    else
    {
      testPath = networkPath.Text;
    }
    if (!loopBreak)
    { // Run warmup
      testFileSize = 0; // for warmup run
      testIterations = 1;
      testType = "write";
      LaunchTestThread();
    }
    testFileSize = Convert.ToUInt64(fileSize.Text) * 1000000;
    testIterations = Convert.ToUInt64(loops.Text);
    if (!loopBreak)
    { // Run write test
      testType = "write";
      LaunchTestThread();
    }
    if (!loopBreak)
    { // Run read test
      testType = "read";
      LaunchTestThread();
    }
    testIsActive = false;
    loopBreak = false;
    benchmarkButton.Text = "Start";
  }

  private void LaunchTestThread()
  {
    workerThread = new Thread(TestPerf);
    workerThread.Start();
    while (!workerThread.IsAlive); // wait for thread activation
    while (workerThread.IsAlive) // wait for thread termination
    {
      Thread.Sleep(500);
    }
  }

  private void TestPerf()
  {
    try
    {
      string firstPath;
      string secondPath;
      string shortType;
      string iterText;
      ulong appendIterations;
      double totalPerf;
      DateTime startTime;
      DateTime stopTime;
      string randomText = RandomString(100000);
      if (testType == "read")
      {
        firstPath = testPath;
        secondPath = localStoragePath;
        shortType = "R";
      }
      else
      {
        firstPath = localStoragePath;
        secondPath = testPath;
        shortType = "W";
      }
      if (testIterations == 1)
      {
        iterText = "once";
      }
      else if (testIterations == 2)
      {
        iterText = "twice";
      }
      else
      {
        iterText = testIterations + " times";
      }
      if (testFileSize == 0)
      {
        resultArea.AppendText("Running warmup...\r\n");
        resultArea.Invalidate();
        appendIterations = 100; // equals a 10MB warmup file.
      }
      else
      {
        resultArea.AppendText(
          "Running a " + testFileSize/1000000 + "MB file " + testType +
          " on " + testPath + " " + iterText + "...\r\n");
        appendIterations = testFileSize/100000;
        // Note: dividing integers in C# always produce a whole number,
        // so no explicit rounding or type conversion is needed
      }
      totalPerf = 0;
      for(ulong j=1; j<=testIterations; j++)
      {
        Application.DoEvents();
        if (File.Exists(firstPath + "\\" + j + "test.tmp"))
        {
          File.Delete(firstPath + "\\" + j + "test.tmp");
        }
        if (File.Exists(secondPath + "\\" + j + "test.tmp"))
        {
          File.Delete(secondPath + "\\" + j + "test.tmp");
        }
        if (loopBreak == true)
        {
          resultArea.AppendText("Benchmark cancelled.\r\n");
          resultArea.Invalidate();
          break;
        }
        StreamWriter sWriter = new StreamWriter(firstPath +
          "\\" + j + "test.tmp", true, Encoding.UTF8, 1048576);
        for(ulong i=1; i<=appendIterations; i++)
        {
          sWriter.Write(randomText);
        }
        sWriter.Close();
        startTime = DateTime.Now;
        File.Copy(firstPath + "\\" + j + "test.tmp",
          secondPath + "\\" + j + "test.tmp");
        stopTime = DateTime.Now;
        File.Delete(firstPath + "\\" + j + "test.tmp");
        File.Delete(secondPath + "\\" + j + "test.tmp");
        TimeSpan interval = stopTime - startTime;
        if (testIterations > 1)
        {
          resultArea.AppendText(
            ("Iteration " + j + ":").PadRight(15) +
            ((testFileSize / 1000) / interval.TotalMilliseconds).ToString("F2").PadLeft(7) +
            " MB/sec\r\n");
          resultArea.Invalidate();
        }
        totalPerf += (testFileSize/1000)/interval.TotalMilliseconds;
      }
      if ((testFileSize != 0) && (loopBreak == false))
      {
        resultArea.AppendText("-----------------------------\r\n");
        resultArea.AppendText("Average (" + shortType + "):" +
          (totalPerf / testIterations).ToString("F2").PadLeft(10) + " MB/sec\r\n");
        resultArea.AppendText("-----------------------------\r\n");
        resultArea.Invalidate();
      }
    }
    catch (Exception e)
    {
      resultArea.AppendText("An error occured: " + e.Message + "\r\n");
    }
  }

  private string RandomString(int size)
  {
    StringBuilder builder = new StringBuilder();
    Random random = new Random();
    char ch;
    for (int i = 0; i < size; i++)
    {
      ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
      builder.Append(ch);
    }
    return builder.ToString();
  }

  private string[] GetNetworkDriveLetters()
  {
    System.Collections.ArrayList NetworkDriveLetters = new System.Collections.ArrayList();
    DriveInfo[] allDrives = DriveInfo.GetDrives();
    foreach (DriveInfo d in allDrives)
    {
      if (d.DriveType == DriveType.Network)
      {
        NetworkDriveLetters.Add(d.Name.Substring(0, 1));
      }
    }
    return NetworkDriveLetters.ToArray(typeof(string)) as string[];
  }

  private bool IsFolderWritable(string folderPath)
  {
    try
    {
      using (FileStream fs = File.Create(
        Path.Combine(folderPath, Path.GetRandomFileName()),
        1, FileOptions.DeleteOnClose)
        )
        { }
      return true;
    }
    catch
    {
      return false;
    }
  }

  static void Main()
  {
    Application.Run(new NasPerformanceForm());
  }
}

Or, if you prefer VB.Net:

Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Text
Imports System.IO
Imports System.Threading
Imports System.Reflection

<Assembly: AssemblyTitle("NAS performance tester 1.700c")>
<Assembly: AssemblyDescription("A small VB.Net utility for benchmarking the read and write performance of network attached storage")>
<Assembly: AssemblyCompany("www.700c.dk")>
<Assembly: AssemblyProduct("NasTester")>
<Assembly: AssemblyCopyright("Creative Commons Attribution (CC BY 3.0) https://creativecommons.org/licenses/by/3.0/ Reference source https://www.700c.dk/?code-csharp-nas-performance")>
<Assembly: AssemblyVersion("1.7.0.0")>
<Assembly: CLSCompliant(True)>

Public Class NasPerformanceForm
  Inherits Form
  Private driveLetterLabel As New Label()
  Private networkPathLabel As New Label()
  Private fileSizeLabel As New Label()
  Private loopsLabel As New Label()
  Private benchmarkButton As New Button()
  Private networkPath As New TextBox()
  Private driveLetter As New ComboBox()
  Private fileSize As New ComboBox()
  Private loops As New ComboBox()
  Private resultArea As New TextBox()
  Private infoLabel As New Label()
  Private urlLabel As New LinkLabel()
  Private loopBreak As Boolean = False
  Private testPath As String
  Private testFileSize As ULong
  Private testIterations As ULong
  Private testType As String
  Private localStoragePath As String
  Private workerThread As Thread
  Private testIsActive As Boolean = False

  Public Sub New()
    Me.Text = "NAS performance tester 1.700c"
    Me.Size = New Size(558, 400)
    Me.Font = New Font("Microsoft Sans Serif", 8)
    driveLetterLabel.Location = New Point(5, 8)
    driveLetterLabel.Text = "NAS drive letter"
    driveLetterLabel.Size = New Size(83, 20)
    driveLetter.Location = New Point(90, 5)
    driveLetter.Size = New Size(33, 15)
    driveLetter.Items.AddRange(GetNetworkDriveLetters())
    If GetNetworkDriveLetters().Length > 0 Then
      driveLetter.SelectedIndex = 0
    End If
    networkPathLabel.Location = New Point(123, 8)
    networkPathLabel.Text = "or network path"
    networkPathLabel.Size = New Size(80, 20)
    networkPath.Location = New Point(205, 5)
    networkPath.Text = ""
    networkPath.Size = New Size(90, 20)
    fileSizeLabel.Location = New Point(302, 8)
    fileSizeLabel.Text = "File size"
    fileSizeLabel.Size = New Size(50, 20)
    fileSize.Location = New Point(352, 5)
    fileSize.Size = New Size(49, 15)
    fileSize.Items.AddRange(New Object() _
      {"100", _
       "200", _
       "400", _
       "800", _
       "1000", _
       "2000", _
       "4000", _
       "8000"})
    fileSize.SelectedIndex = 2
    loopsLabel.Location = New Point(407, 8)
    loopsLabel.Text = "Loops"
    loopsLabel.Size = New Size(36, 20)
    loops.Location = New Point(443, 5)
    loops.Size = New Size(37, 15)
    loops.Items.AddRange(New Object() _
      {"1", _
       "2", _
       "3", _
       "4", _
       "5", _
       "10", _
       "20", _
       "40"})
    loops.SelectedIndex = 4
    benchmarkButton.Location = New Point(487, 5)
    benchmarkButton.Size = New Size(50, 20)
    benchmarkButton.Text = "Start"
    resultArea.Location = New Point(5, 30)
    resultArea.Size = New Size(533, 305)
    resultArea.[ReadOnly] = True
    resultArea.Multiline = True
    resultArea.ScrollBars = ScrollBars.Vertical
    resultArea.WordWrap = False
    resultArea.Text = "NAS performance tester 1.7 https://www.700c.dk/?nastester" & vbCrLf
    resultArea.Font = New Font("Courier New", 8)
    infoLabel.Location = New Point(5, 341)
    infoLabel.Text = "For more information, visit"
    infoLabel.Size = New Size(140, 20)
    urlLabel.Location = New Point(143, 341)
    urlLabel.Text = "https://www.700c.dk/?code-csharp-nas-performance"
    urlLabel.Links.Add(0, 48, "https://www.700c.dk/?code-csharp-nas-performance")
    urlLabel.Size = New Size(300, 20)
    Me.Controls.Add(driveLetterLabel)
    Me.Controls.Add(driveLetter)
    Me.Controls.Add(networkPathLabel)
    Me.Controls.Add(networkPath)
    Me.Controls.Add(fileSizeLabel)
    Me.Controls.Add(fileSize)
    Me.Controls.Add(loopsLabel)
    Me.Controls.Add(loops)
    Me.Controls.Add(benchmarkButton)
    Me.Controls.Add(resultArea)
    Me.Controls.Add(infoLabel)
    Me.Controls.Add(urlLabel)
    AddHandler benchmarkButton.Click, New EventHandler(AddressOf benchmarkButton_Click)
    AddHandler urlLabel.LinkClicked, New LinkLabelLinkClickedEventHandler(AddressOf Me.urlLabel_LinkClicked)
    Me.ActiveControl = networkPath
    If IsFolderWritable(Path.GetDirectoryName(Application.ExecutablePath)) Then
      localStoragePath = Path.GetDirectoryName(Application.ExecutablePath)
    Else ' Write access to program folder denied, falling back to Windows temp folder as defined in the environment variables
      localStoragePath = Path.GetTempPath()
    End If
  End Sub

  Private Sub benchmarkButton_Click(sender As Object, e As EventArgs)
    If Not testIsActive Then
      Dim checkFileSize As Integer
      Dim checkLoops As Integer
      If (Not String.IsNullOrEmpty(driveLetter.Text) Or (networkPath.Text.IndexOf("\\") = 0 AndAlso networkPath.Text.IndexOf("\", 2) > 2)) AndAlso _
          Integer.TryParse(fileSize.Text, checkFileSize) AndAlso _
          Integer.TryParse(loops.Text, checkLoops) Then
        If checkFileSize <= 64000 Then
          Dim newThread As New Thread(New ThreadStart(AddressOf BenchmarkHandler))
          newThread.Start()
        Else
          resultArea.AppendText("The maximum test file size is 64GB." & vbCrLf)
          resultArea.Invalidate()
        End If
      Else
        resultArea.AppendText("Input invalid. Check drive letter or network path, file size and loops." & vbCrLf)
        resultArea.Invalidate()
      End If
    Else
      loopBreak = True
      resultArea.AppendText("Cancelling. Please wait for current loop to finish..." & vbCrLf)
      resultArea.Invalidate()
    End If
  End Sub

  Private Sub urlLabel_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs)
    Dim target As String = TryCast(e.Link.LinkData, String)
    System.Diagnostics.Process.Start(target)
  End Sub

  Private Sub BenchmarkHandler()
    testIsActive = True
    loopBreak = False
    benchmarkButton.Text = "Stop"
    If String.IsNullOrEmpty(networkPath.Text) Then
      testPath = driveLetter.Text & ":"
    Else
      testPath = networkPath.Text
    End If
    If Not loopBreak Then ' Run warmup
      testFileSize = 0 ' for warmup run
      testIterations = 1
      testType = "write"
      LaunchTestThread()
    End If
    testFileSize = Convert.ToUInt64(fileSize.Text) * 1000000
    testIterations = Convert.ToUInt64(loops.Text)
    If Not loopBreak Then ' Run write test
      testType = "write"
      LaunchTestThread()
    End If
    If Not loopBreak Then ' Run read test
      testType = "read"
      LaunchTestThread()
    End If
    testIsActive = False
    loopBreak = False
    benchmarkButton.Text = "Start"
  End Sub

  Private Sub LaunchTestThread()
    workerThread = New Thread(AddressOf TestPerf)
    workerThread.Start()
    While Not workerThread.IsAlive ' wait for thread activation
    End While
    While workerThread.IsAlive ' wait for thread termination
      Thread.Sleep(500)
    End While
  End Sub

  Private Sub TestPerf()
    Try
      Dim firstPath As String
      Dim secondPath As String
      Dim shortType As String
      Dim iterText As String
      Dim appendIterations As ULong
      Dim totalPerf As Double
      Dim startTime As DateTime
      Dim stopTime As DateTime
      Dim randomText As String = RandomString(100000)
      If testType = "read" Then
        firstPath = testPath
        secondPath = localStoragePath
        shortType = "R"
      Else
        firstPath = localStoragePath
        secondPath = testPath
        shortType = "W"
      End If
      If testIterations = 1 Then
        iterText = "once"
      ElseIf testIterations = 2 Then
        iterText = "twice"
      Else
        iterText = testIterations & " times"
      End If
      If testFileSize = 0 Then
        resultArea.AppendText("Running warmup..." & vbCrLf)
        resultArea.Invalidate()
        appendIterations = 100 ' equals a 10MB warmup file.
      Else
        resultArea.AppendText( _
          "Running a " & testFileSize \ 1000000 & "MB file " & testType & _
          " on " & testPath & " " & iterText & "..." & vbCrLf)
        appendIterations = testFileSize \ 100000
        ' Note: dividing integers in VB.Net can produce a decimal number,
        ' so the integer division operator '\' is used instead of '/'
      End If
      totalPerf = 0
      For j As Integer = 1 To testIterations
        Application.DoEvents()
        If File.Exists(firstPath & "\" & j & "test.tmp") Then
          File.Delete(firstPath & "\" & j & "test.tmp")
        End If
        If File.Exists(secondPath & "\" & j & "test.tmp") Then
          File.Delete(secondPath & "\" & j & "test.tmp")
        End If
        If loopBreak = True Then
          resultArea.AppendText("Benchmark cancelled." & vbCrLf)
          resultArea.Invalidate()
          Exit For
        End If
        Dim sWriter As New StreamWriter(firstPath & _
          "\" & j & "test.tmp", True, Encoding.UTF8, 1048576)
        For i As Integer = 1 To appendIterations
          sWriter.Write(randomText)
        Next
        sWriter.Close()
        startTime = DateTime.Now
        File.Copy(firstPath & "\" & j & "test.tmp", _
          secondPath & "\" & j & "test.tmp")
        stopTime = DateTime.Now
        File.Delete(firstPath & "\" & j & "test.tmp")
        File.Delete(secondPath & "\" & j & "test.tmp")
        Dim interval As TimeSpan = stopTime - startTime
        If testIterations > 1 Then
          resultArea.AppendText( _
            ("Iteration " & j & ":").PadRight(15) & _
            ((testFileSize \ 1000) / interval.TotalMilliseconds).ToString("F2").PadLeft(7) & _
            " MB/sec" & vbCrLf)
          resultArea.Invalidate()
        End If
        totalPerf += (testFileSize \ 1000) / interval.TotalMilliseconds
      Next
      If (testFileSize <> 0) AndAlso (loopBreak = False) Then
        resultArea.AppendText("-----------------------------" & vbCrLf)
        resultArea.AppendText("Average (" & shortType & "):" & _
          (totalPerf / testIterations).ToString("F2").PadLeft(10) & " MB/sec" & vbCrLf)
        resultArea.AppendText("-----------------------------" & vbCrLf)
        resultArea.Invalidate()
      End If
    Catch e As Exception
      resultArea.AppendText("An error occured: " & e.Message & vbCrLf)
    End Try
  End Sub

  Private Function RandomString(size As Integer) As String
    Dim builder As New StringBuilder()
    Dim random As New Random()
    Dim ch As Char
    For i As Integer = 0 To size - 1
      ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)))
      builder.Append(ch)
    Next
    Return builder.ToString()
  End Function

  Private Function GetNetworkDriveLetters() As String()
    Dim NetworkDriveLetters As New System.Collections.ArrayList()
    Dim allDrives As DriveInfo() = DriveInfo.GetDrives()
    For Each d As DriveInfo In allDrives
      If d.DriveType = DriveType.Network Then
        NetworkDriveLetters.Add(d.Name.Substring(0, 1))
      End If
    Next
    Return TryCast(NetworkDriveLetters.ToArray(GetType(String)), String())
  End Function

  Private Function IsFolderWritable(folderPath As String) As Boolean
    Try
      Using fs As FileStream = _
        File.Create(Path.Combine(folderPath, _
        Path.GetRandomFileName()), 1, FileOptions.DeleteOnClose)
      End Using
    Return True
    Catch
      Return False
    End Try
  End Function

  Shared Sub Main()
    Application.Run(New NasPerformanceForm())
  End Sub
End Class

Page last updated 2024-03-24 14:36. Some rights reserved (CC by 3.0)