3

I am developing an application in C# so whereby, if the user confirms a messagebox to formatting a USB drive, selected from a combobox list, the drive will be formatted.

I haven't got an idea how to approach this, however - I have the following code:

 public static bool FormatDrive(string driveLetter,
    string fileSystem = "FAT", bool quickFormat = false,
    int clusterSize = 4096, string label = "", bool enableCompression = false)
    {
        if (driveLetter.Length != 2 || driveLetter[1] != ':' || !char.IsLetter(driveLetter[0]))
            return false;

        //query and format given drive         
        ManagementObjectSearcher searcher = new ManagementObjectSearcher
         (@"select * from Win32_Volume WHERE DriveLetter = '" + driveLetter + "'");
        foreach (ManagementObject vi in searcher.Get())
        {
            vi.InvokeMethod("Format", new object[] { fileSystem, quickFormat, clusterSize, label, enableCompression });
        }

        return true;
    } 

I'm not really sure how this works. Is this the correct way to approach formatting USB Drives? If not, could someone point me in the right direction?

I have tried looking at the Win32_Volume class but, again, I don't really understand how it works. This question would suggest using the CreateFile function. I have also looked at this website.

Any tips of pushing me into the right direction, would be much appreciated.

Alex P.
  • 30,437
  • 17
  • 118
  • 169
Sean
  • 442
  • 3
  • 6
  • 19
  • Do you actually need to format it completely? Or is your goal just to delete everything in it? – Callum Bradbury Oct 14 '15 at 08:39
  • @CallumBradbury It needs to be formatted completely. But NOT run as a QuickFormat, hence why it's set to `false`. – Sean Oct 14 '15 at 08:41
  • Possible duplicate of [Format a Drive from C#](http://stackoverflow.com/questions/8063538/format-a-drive-from-c-sharp) – online Thomas Oct 14 '15 at 08:44
  • @user2754599 I'd looked at that, also. But it's not easy to understand. Atleast, from my view. – Sean Oct 14 '15 at 08:46
  • Just curious, why you wish to format it completely using a custom C# program? there's already formatting tools that's avaliable. – User2012384 Oct 14 '15 at 08:51
  • @User2012384 I have to format a number of cards that run well into the thousands; having to use Microsoft's method is far too time consuming. If I can develop an application that can do this with a button click, it'll not only save me a lot of time, but the company also. – Sean Oct 14 '15 at 08:54

2 Answers2

1

Well maybe I have another method:

    public static bool FormatDrive_CommandLine(char driveLetter, string label = "", string fileSystem = "NTFS", bool quickFormat = true, bool enableCompression = false, int? clusterSize = null)
    {
        #region args check

        if (!Char.IsLetter(driveLetter) ||
            !IsFileSystemValid(fileSystem))
        {
            return false;
        }

        #endregion
        bool success = false;
        string drive = driveLetter + ":";
        try
        {
            var di                     = new DriveInfo(drive);
            var psi                    = new ProcessStartInfo();
            psi.FileName               = "format.com";
            psi.CreateNoWindow         = true; //if you want to hide the window
            psi.WorkingDirectory       = Environment.SystemDirectory;
            psi.Arguments              = "/FS:" + fileSystem +
                                         " /Y" +
                                         " /V:" + label +
                                         (quickFormat ? " /Q" : "") +
                                         ((fileSystem == "NTFS" && enableCompression) ? " /C" : "") +
                                         (clusterSize.HasValue ? " /A:" + clusterSize.Value : "") +
                                         " " + drive;
            psi.UseShellExecute        = false;
            psi.CreateNoWindow         = true;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardInput  = true;
            var formatProcess          = Process.Start(psi);
            var swStandardInput        = formatProcess.StandardInput;
            swStandardInput.WriteLine();
            formatProcess.WaitForExit();
            success = true;
        }
        catch (Exception) { }
        return success;
    }

First I wrote the code myself, now found a perfect method on http://www.metasharp.net/index.php/Format_a_Hard_Drive_in_Csharp

Answers to questions in comment:

Remove the /q if you don't want it to quick format

/x parameter forces the selected volume to dismount, if needed.

source: http://ccm.net/faq/9524-windows-how-to-format-a-usb-key-from-the-command-prompt

psi.CreateNoWindow = true;

Hides the terminal so your application looks smooth. My advice is showing it while debugging.

What you want to call is if the drive is F:/ for example:

FormatDrive_CommandLine('F', "formattedDrive", "FAT32", false, false);
Community
  • 1
  • 1
online Thomas
  • 8,864
  • 6
  • 44
  • 85
  • What does the `/x` do? Also, where you have `driveLetter`, could I replace that for `combobox1.SelectedItem.ToString()`? Also, will this keep all settings, I.E, FileSystem and Cluster Size? – Sean Oct 14 '15 at 08:56
  • I added the explanation and about the toString: as a Drive always has 1 character as identifier in Windows I suggest using char instead of String, but of course you can use the String. – online Thomas Oct 14 '15 at 08:58
  • Ok, when calling the method inside my button, I receive the error: 'no overload for method '' takes 0 arguements'? – Sean Oct 14 '15 at 09:05
  • @Sean because you didn't provide the driveLetter argument, if you are this beginner level at programming you might want to start with a tutorial or something. – online Thomas Oct 14 '15 at 09:06
  • Right, well I've resolved that but when running, it can't find the file? Yes, I'm at a stage when I'm still learning but this is a project I've been asked to create. I don't understand where it's looking for a file? – Sean Oct 14 '15 at 09:11
  • @Sean You ask to format USB drives in C#, why would you specify a file? You format the entire drive of course – online Thomas Oct 14 '15 at 09:16
  • The exception is thrown within your method? It breaks on `'processname'.start()` – Sean Oct 14 '15 at 09:18
  • @Sean well debug it then, what is the exception. I'm not able to test my code right now, but I used similar code to run CMD functions before and this example can't be that far off. I encourage you to find the problem and edit my post if it's (probably) a wrongly places space or something. – online Thomas Oct 14 '15 at 09:20
  • I can't seem to get it to write to CMD with those arguments. It writes in `Debug.WriteLine()` – Sean Oct 14 '15 at 10:41
  • @ThomasMoors Thanks for solution.this is working. I just want to know if I am using it in WCF service method based on the conditions, it should work. Is it? – Kumar Jun 23 '17 at 17:02
  • 1
    Thanks. I added a test to make sure the driveLetter isn't C. – Skyfish Oct 23 '20 at 12:46
  • Would it be possible to use exFAT with this answer, making the appropriate cluster size changes and the format being `FormatDrive_CommandLine('F', "formattedDrive", "exFAT", false, false);`? – Momoro Aug 02 '21 at 01:08
  • @Momoro one way to find out :) – online Thomas Aug 02 '21 at 06:31
  • 1
    It works :) Just had to change `"exFAT"` to `"EXFAT"` for correct syntax. Thanks! – Momoro Aug 03 '21 at 04:33
  • @Momoro curious how windows all of the sudden has case sensitive commands – online Thomas Aug 03 '21 at 08:43
  • 1
    You'd think `exFAT` would be the correct syntax, but alas, `EXFAT` – Momoro Aug 05 '21 at 04:13
1

I have also tried this and worked:

public bool FormatUSB(string driveLetter, string fileSystem = "FAT32", bool quickFormat = true,
                                   int clusterSize = 4096, string label = "USB_0000", bool enableCompression = false)
    {
        //add logic to format Usb drive
        //verify conditions for the letter format: driveLetter[0] must be letter. driveLetter[1] must be ":" and all the characters mustn't be more than 2
        if (driveLetter.Length != 2 || driveLetter[1] != ':' || !char.IsLetter(driveLetter[0]))
            return false;

        //query and format given drive 
        //best option is to use ManagementObjectSearcher

        var files = Directory.GetFiles(driveLetter);
        var directories = Directory.GetDirectories(driveLetter);

        foreach (var item in files)
        {
            try
            {
                File.Delete(item);
            }
            catch (UnauthorizedAccessException) { }
            catch (IOException) { }
        }

        foreach (var item in directories)
        {
            try
            {
                Directory.Delete(item);
            }
            catch (UnauthorizedAccessException) { }
            catch (IOException) { }
        }

        ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"select * from Win32_Volume WHERE DriveLetter = '" + driveLetter + "'");
        foreach (ManagementObject vi in searcher.Get())
        {
            try
            {
                var completed = false;
                var watcher = new ManagementOperationObserver();

                watcher.Completed += (sender, args) =>
                {
                    Console.WriteLine("USB format completed " + args.Status);
                    completed = true;
                };
                watcher.Progress += (sender, args) =>
                {
                    Console.WriteLine("USB format in progress " + args.Current);
                };

                vi.InvokeMethod(watcher, "Format", new object[] { fileSystem, quickFormat, clusterSize, label, enableCompression });

                while (!completed) { System.Threading.Thread.Sleep(1000); }


            }
            catch
            {

            }
        }
        return true;
    }
    #endregion

Maybe it will help.

Răzvan Bălan
  • 33
  • 1
  • 13
  • Question: Does this also change the format of the drive? e.g. if the drive wasn't FAT32 before formatting, would the filesystem be FAT32 **after formatting with this code?** – Momoro Apr 29 '20 at 07:50