Question

I'm trying to extract an ISO to a folder with the same name without .iso on the end.

I'm having a problem with winrar as it will not start the extract when I start up with the seach starting in the folder with the ISO.

UPDATED with answer code

private void ExtractISO(string toExtract, string folderName)
    {
        // reads the ISO
        CDReader Reader = new CDReader(File.Open(toExtract, FileMode.Open), true);
        // passes the root directory the folder name and the folder to extract
        ExtractDirectory(Reader.Root, folderName /*+ Path.GetFileNameWithoutExtension(toExtract)*/ + "\\", "");
        // clears reader and frees memory
        Reader.Dispose();
    }

    private void ExtractDirectory(DiscDirectoryInfo Dinfo, string RootPath, string PathinISO)
    {
        if (!string.IsNullOrWhiteSpace(PathinISO))
        {
            PathinISO += "\\" + Dinfo.Name;
        }
        RootPath += "\\" + Dinfo.Name;
        AppendDirectory(RootPath);
        foreach (DiscDirectoryInfo dinfo in Dinfo.GetDirectories())
        {
            ExtractDirectory(dinfo, RootPath, PathinISO);
        }
        foreach (DiscFileInfo finfo in Dinfo.GetFiles())
        {
            using (Stream FileStr = finfo.OpenRead())
            {
                using (FileStream Fs = File.Create(RootPath + "\\" + finfo.Name)) // Here you can Set the BufferSize Also e.g. File.Create(RootPath + "\\" + finfo.Name, 4 * 1024)
                {
                    FileStr.CopyTo(Fs, 4 * 1024); // Buffer Size is 4 * 1024 but you can modify it in your code as per your need
                }
            }
        }
    }

    static void AppendDirectory(string path)
    {
        try
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }
        catch (DirectoryNotFoundException Ex)
        {
            AppendDirectory(Path.GetDirectoryName(path));
        }
        catch (PathTooLongException Ex)
        {
            AppendDirectory(Path.GetDirectoryName(path));
        }
    }

The user selects the folder to extract (.ISO) toExtract. I then use it in the Process.Start() in the background worker. That just seems to open the mounting software and doesn't extract the ISO to the desired folder name.

Thanks in advance for your help.

Or if anyone could give me a batch to extract the ISO instead and to call it from c# passing toExtract and the folder name that would be helpful too.

Thanks

Was it helpful?

Solution

If external Class Libraries are OK!

Then use SevenZipSharp or .NET DiscUtils to extract ISO's...

These two ClassLibraries can manage ISO and Extract them!

For DiscUtils you can find some codes for ISO Management [CDReader Class] at the Link I provided.

But For SevenZipSharp, Please Explore the ClassLibrary source and find the Code to Extract or Google to find it!

To get the Name of the folder just use Path.GetFileNameWithoutExtension((string)ISOFileName) which will return "ISOFile" for an iso named "ISOFile.iso". And then you can use it with your desired path.

UPDATE

Code To Extract ISO Image with DiscUtils :

using DiscUtils;
using DiscUtils.Iso9660;

void ExtractISO(string ISOName, string ExtractionPath)
{
    using (FileStream ISOStream = File.Open(ISOName, FileMode.Open))
    {
        CDReader Reader = new CDReader(ISOStream, true, true);
        ExtractDirectory(Reader.Root, ExtractionPath + Path.GetFileNameWithoutExtension(ISOName) + "\\", "");
        Reader.Dispose();
    }
}
void ExtractDirectory(DiscDirectoryInfo Dinfo, string RootPath, string PathinISO)
{
    if (!string.IsNullOrWhiteSpace(PathinISO))
    {
        PathinISO += "\\" + Dinfo.Name;
    }
    RootPath += "\\" + Dinfo.Name;
    AppendDirectory(RootPath);
    foreach (DiscDirectoryInfo dinfo in Dinfo.GetDirectories())
    {
        ExtractDirectory(dinfo, RootPath, PathinISO);
    }
    foreach (DiscFileInfo finfo in Dinfo.GetFiles())
    {
            using (Stream FileStr = finfo.OpenRead())
            {
                using (FileStream Fs = File.Create(RootPath + "\\" + finfo.Name)) // Here you can Set the BufferSize Also e.g. File.Create(RootPath + "\\" + finfo.Name, 4 * 1024)
                {
                    FileStr.CopyTo(Fs, 4 * 1024); // Buffer Size is 4 * 1024 but you can modify it in your code as per your need
                }
            }
    }
}
static void AppendDirectory(string path)
{
    try
    {
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
    }
    catch (DirectoryNotFoundException Ex)
    {
        AppendDirectory(Path.GetDirectoryName(path));
    }
    catch (PathTooLongException Exx)
    {
        AppendDirectory(Path.GetDirectoryName(path));
    }
}

Use It with Like This :

ExtractISO(ISOFileName, Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\");

Working! Tested By Me!

And Of Course You can always add more Optimization to the code...

This Code is Just a Basic One!

OTHER TIPS

For UDF or for making Windows ISO Files after servicing(DISM) with out needs the above accepted answer is not working for me so i tried this working method with DiscUtils

using DiscUtils;
public static void ReadIsoFile(string sIsoFile, string sDestinationRootPath)
        {
            Stream streamIsoFile = null;
            try
            {
                streamIsoFile = new FileStream(sIsoFile, FileMode.Open);
                DiscUtils.FileSystemInfo[] fsia = FileSystemManager.DetectDefaultFileSystems(streamIsoFile);
                if (fsia.Length < 1)
            {
                MessageBox.Show("No valid disc file system detected.");
            }
            else
            {
                DiscFileSystem dfs = fsia[0].Open(streamIsoFile);                    
                ReadIsoFolder(dfs, @"", sDestinationRootPath);
                return;
            }
        }
        finally
        {
            if (streamIsoFile != null)
            {
                streamIsoFile.Close();
            }
        }
    }

public static void ReadIsoFolder(DiscFileSystem cdReader, string sIsoPath, string sDestinationRootPath)
    {
        try
        {
            string[] saFiles = cdReader.GetFiles(sIsoPath);
            foreach (string sFile in saFiles)
            {
                DiscFileInfo dfiIso = cdReader.GetFileInfo(sFile);
                string sDestinationPath = Path.Combine(sDestinationRootPath, dfiIso.DirectoryName.Substring(0, dfiIso.DirectoryName.Length - 1));
                if (!Directory.Exists(sDestinationPath))
                {
                    Directory.CreateDirectory(sDestinationPath);
                }
                string sDestinationFile = Path.Combine(sDestinationPath, dfiIso.Name);
                SparseStream streamIsoFile = cdReader.OpenFile(sFile, FileMode.Open);
                FileStream fsDest = new FileStream(sDestinationFile, FileMode.Create);
                byte[] baData = new byte[0x4000];
                while (true)
                {
                    int nReadCount = streamIsoFile.Read(baData, 0, baData.Length);
                    if (nReadCount < 1)
                    {
                        break;
                    }
                    else
                    {
                        fsDest.Write(baData, 0, nReadCount);
                    }
                }
                streamIsoFile.Close();
                fsDest.Close();
            }
            string[] saDirectories = cdReader.GetDirectories(sIsoPath);
            foreach (string sDirectory in saDirectories)
            {
                ReadIsoFolder(cdReader, sDirectory, sDestinationRootPath);
            }
            return;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
    }

it has extracted from a application source ISOReader but modified for my requirements

total source is available at http://www.java2s.com/Open-Source/CSharp_Free_CodeDownload/i/isoreader.zip

Try this:

string Desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Process.Start("Winrar.exe", string.Format("x {0} {1}",
   Desktop + "\\test.rar",
   Desktop + "\\SomeFolder"));

That would extract the file test.rar to the folder SomeFolder. You can change the .rar extention to .iso, it'll work the same.

As far as I can see in your current code, there is no command given to extract a file, and no path to the file that has to be extracted. Try this example and let me know if it works =]

P.S. If you'd like to hide the extracting screen, you can set the YourProcessInfo.WindowStyle to ProcessWindowStyle.Hidden.

I hace confrunted recently with this kind of .iso extraction issue. After trying several methods, 7zip did the job for me, you just have to make sure that the latest version of 7zip is installed on your system. Maybe it will help try {

            Process cmd = new Process();
            cmd.StartInfo.FileName = "cmd.exe";
            cmd.StartInfo.RedirectStandardInput = true;
            cmd.StartInfo.RedirectStandardOutput = true;
            cmd.StartInfo.CreateNoWindow = false;
            cmd.StartInfo.UseShellExecute = false;
            cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
            cmd.Start();

            cmd.StandardInput.WriteLine("C:");
            //Console.WriteLine(cmd.StandardOutput.Read());
            cmd.StandardInput.Flush();

            cmd.StandardInput.WriteLine("cd C:\\\"Program Files\"\\7-Zip\\");
            //Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            cmd.StandardInput.Flush();


            cmd.StandardInput.WriteLine(string.Format("7z x -y -o{0} {1}", source, copyISOLocation.TempIsoPath));
            //Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            cmd.StandardInput.Flush();
            cmd.StandardInput.Close();
            cmd.WaitForExit();
            Console.WriteLine(cmd.StandardOutput.ReadToEnd());
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message + "\n" + e.StackTrace);
            if (e.InnerException != null)
            {
                Console.WriteLine(e.InnerException.Message + "\n" + e.InnerException.StackTrace);
            }
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top