none
Shrink, create partition in C# without DiskPart RRS feed

  • 问题

  • Here's what I want to do.

    First, get drive information, then check the partition information to see if there is only a single partition, or 2 (or more) small partitions.  If this is the case, I want to shrink the large partition to 50% of it's size, create a new partition in the free space, format it and assign a drive letter.

    I would prefer to do this without using DiskPart, but it may not be possible.  I haven't created any DiskPart scripts before.

    If I have to use DiskPart, I'm thinking I'll have to get drive information using DriveInfo.GetDrives, then generate a script using the information from there.

    Since I'd be creating 2 identical partitions, I'd be able to see if the C: and D: drives are the same size, and see if there is anything already stored on D:.

    Can this be done exclusively in C#, or will I have to execute DiskPart in order to accomplish this?

    Andy

    2012年7月18日 15:02

答案

  • Its a large job. You need to split this down into separate tasks and work with each task at a time. Then you can formulate specific questions. For gaining information on the hard drive and for low-level access to the hard drive from C# I wrote this:

    Low Level Disk Access

    Start with this --- then when you have the information on the drive that you require and know about the contents you can re-ask the second part of your question.

    You can get information on the content of your drive from the Master File Table using C#. The last link does this using C# as well, so if you merge my two examples you will have the core to your application.


    Digital Forensic Software Developer
    CCS LABS Digital Forensic Software
    Mark as Answer or Vote up if useful thank you!

    2012年7月18日 16:12
  • That looks much more complicated than I wanted it to be.

    I ended up using DiskPart as it turned out to be simpler, even though it does bring up a command window to run it.  (Setting the ProcessStartInfo.WindowStyle to either hidden or minimized didn't work).

    Here is the code I used to split the drive in half.

                long cSize = 0, dSize = 0;
                #region Setup partitions
                // Get drive information
                DriveInfo[] AllDrives = DriveInfo.GetDrives();
                // Get size information for C: and D: drives
                for (int x = 0; x < AllDrives.Length; x++) {
                    if (AllDrives[x].Name == @"C:\")
                        cSize = AllDrives[x].TotalSize;
                    if (AllDrives[x].Name == @"D:\")
                        dSize = AllDrives[x].TotalSize;
                }
                long meg = 1024 * 1024;                     // 1 megabyte
                long offs = 100 * meg;                      // 100 megabytes
                // If the size of the D drive is within 100meg of the size of the C drive, do nothing
                if ((cSize < (dSize - offs)) || (cSize > (dSize + offs))) {
                    dSize = cSize / 2;                      // Cut the drive size in half
                    dSize = (cSize - dSize) / meg;          // Convert to size in megabytes
                    // Note: if the file doesn't exist, no exception is thrown
                    File.Delete(sd + "dpScript.scr");       // Delete the script, if it exists
                    // Create the script to resize C and make D
                    File.AppendAllText(sd + "dpScript.scr",
                        string.Format(
                        "SELECT DISK=0\n" +                         // Select the first disk drive
                        "SELECT VOLUME=C\n" +                       // Select the C: drive
                        "SHRINK DESIRED={0} MINIMUM={0}\n" +        // Shrink to half the original size
                        "CREATE PARTITION PRIMARY\n" +              // Make the D: drive partition
                        "ASSIGN LETTER=D\n" +                       // Assign it's letter
                        "FORMAT FS=NTFS LABEL=\"TPS\" QUICK\n" +    // Format it
                        "EXIT", dSize));                            // And exit
                    RunProgram(sys + "DiskPart.exe", "/s " + sd + "dpScript.scr", false, true);
                    File.Delete(sd + "dpScript.scr");               // Delete the script file
                    Cursor.Current = Cursors.Default;
                }
                #endregion

    The prototype for RunProgram is:

    private void RunProgram(string path, string arguments, bool progress, bool hidden);

    Anyway, it seems to be doing the job.

    Andy

    2012年7月18日 18:37

全部回复

  • Its a large job. You need to split this down into separate tasks and work with each task at a time. Then you can formulate specific questions. For gaining information on the hard drive and for low-level access to the hard drive from C# I wrote this:

    Low Level Disk Access

    Start with this --- then when you have the information on the drive that you require and know about the contents you can re-ask the second part of your question.

    You can get information on the content of your drive from the Master File Table using C#. The last link does this using C# as well, so if you merge my two examples you will have the core to your application.


    Digital Forensic Software Developer
    CCS LABS Digital Forensic Software
    Mark as Answer or Vote up if useful thank you!

    2012年7月18日 16:12
  • That looks much more complicated than I wanted it to be.

    I ended up using DiskPart as it turned out to be simpler, even though it does bring up a command window to run it.  (Setting the ProcessStartInfo.WindowStyle to either hidden or minimized didn't work).

    Here is the code I used to split the drive in half.

                long cSize = 0, dSize = 0;
                #region Setup partitions
                // Get drive information
                DriveInfo[] AllDrives = DriveInfo.GetDrives();
                // Get size information for C: and D: drives
                for (int x = 0; x < AllDrives.Length; x++) {
                    if (AllDrives[x].Name == @"C:\")
                        cSize = AllDrives[x].TotalSize;
                    if (AllDrives[x].Name == @"D:\")
                        dSize = AllDrives[x].TotalSize;
                }
                long meg = 1024 * 1024;                     // 1 megabyte
                long offs = 100 * meg;                      // 100 megabytes
                // If the size of the D drive is within 100meg of the size of the C drive, do nothing
                if ((cSize < (dSize - offs)) || (cSize > (dSize + offs))) {
                    dSize = cSize / 2;                      // Cut the drive size in half
                    dSize = (cSize - dSize) / meg;          // Convert to size in megabytes
                    // Note: if the file doesn't exist, no exception is thrown
                    File.Delete(sd + "dpScript.scr");       // Delete the script, if it exists
                    // Create the script to resize C and make D
                    File.AppendAllText(sd + "dpScript.scr",
                        string.Format(
                        "SELECT DISK=0\n" +                         // Select the first disk drive
                        "SELECT VOLUME=C\n" +                       // Select the C: drive
                        "SHRINK DESIRED={0} MINIMUM={0}\n" +        // Shrink to half the original size
                        "CREATE PARTITION PRIMARY\n" +              // Make the D: drive partition
                        "ASSIGN LETTER=D\n" +                       // Assign it's letter
                        "FORMAT FS=NTFS LABEL=\"TPS\" QUICK\n" +    // Format it
                        "EXIT", dSize));                            // And exit
                    RunProgram(sys + "DiskPart.exe", "/s " + sd + "dpScript.scr", false, true);
                    File.Delete(sd + "dpScript.scr");               // Delete the script file
                    Cursor.Current = Cursors.Default;
                }
                #endregion

    The prototype for RunProgram is:

    private void RunProgram(string path, string arguments, bool progress, bool hidden);

    Anyway, it seems to be doing the job.

    Andy

    2012年7月18日 18:37