Вопрос по c# – извлекать ISO с WinRar автоматически с помощью C # или партии

3

Я пытаюсь извлечь ISO в папку с тем же именем без .iso в конце.

У меня проблема с winrar, так как он не запустит распаковку, когда я начну с поиска, который начинается в папке с ISO.

UPDATED with answer code

<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));
        }
    }
</code>

Пользователь выбирает папку для извлечения (.ISO) для извлечения. Затем я использую его в Process.Start () в фоновом режиме. Это просто открывает программное обеспечение для монтирования и не извлекает ISO в нужное имя папки.

Заранее спасибо за помощь.

Или если бы кто-нибудь мог дать мне пакет для извлечения ISO вместо этого и вызова его из c #, передавая в Extract и имя папки, что также было бы полезно.

Спасибо

@DavidHeffernan Будет ли эта часть из извлечения файла из ISO, это может быть использовано для извлечения полного. ISO? и как? ELSheepO
Вы должны быть в состоянии создать командный вызов и сделать это таким образом. Посмотрите здесьrespower.com/page_tutorial_unrar ThePower
Если вы можете извлечь файл, то вы можете извлечь весь .iso. Если вы хотите узнать, как это сделать, то вы можете прочитать документацию. David Heffernan
Как насчет использованияdiscutils.codeplex.com и, таким образом, избегая необходимости раскошелиться на какой-нибудь сторонний исполняемый David Heffernan
обращатьсяstackoverflow.com/questions/11737/… Romil Kumar Jain

Ваш Ответ

4   ответа
0

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

Что бы извлечь файлtest.rar в папкуSomeFolder, Вы можете изменить расширение .rar на .iso, оно будет работать так же.

Насколько я вижу в вашем текущем коде, нет команды для извлечения файла, и нет пути к файлу, который нужно извлечь. Попробуйте этот пример и дайте мне знать, если он работает =]

Постскриптум Если вы хотите скрыть экран извлечения, вы можете установитьYourProcessInfo.WindowStyle вProcessWindowStyle.Hidden.

Убедитесь, что вы добавили две обратные косые черты (\\ ) после рабочего стола. Иначе это читается какC:\User\MyUser\DesktopMyIsoImage.iso вместоC:\User\MyUser\Desktop\\MyIsoImage.iso
string MyDocuments = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); Process.Start("Winrar.exe", string.Format("x {0} {1}", toExtract, MyDocuments + "\\ISO DUMP!!" + folderName)); Это то, что я изменил, получив, что нет архива, toExtract - это полное расширение ISO, так как я распечатал его в текстовое поле, чтобы проверить его, и foldername - это папка, в которую я хочу его извлечь, то же имя, только без .iso на конце, который удален. ELSheepO
Здравствуйте, только что попробовал получить сообщение об ошибке "архивы не найдены" Я изменил код в фоновом режиме на то, что вы мне дали, и изменил файлы так, как я хотел, чтобы они были. string Desktop = Environment.GetFolderPath (Environment.SpecialFolder.Desktop); Process.Start (& quot; Winrar.exe & quot ;, string.Format (& quot; {0} {1} & quot ;, Desktop + txtToExtract.Text, Desktop + txtFolderName.Text)); ELSheepO
0

без потребностей вышеуказанный принятый ответ не работает для меня, поэтому я попробовал этот метод работы с 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());
        }
    }

он извлечен из источника приложения ISOReader, но изменен для моих требований

общий источник доступен наhttp://www.java2s.com/Open-Source/CSharp_Free_CodeDownload/i/isoreader.zip

10

Тогда используйтеSevenZipSharp или же.NET DiscUtils для извлечения ISO ...

Эти две библиотеки классов могут управлять ISO и извлекать их!

ЗаDiscUtils Вы можете найти некоторые коды для управления ISO [CDReader Класс] по ссылке, которую я предоставил.

Но дляSevenZipSharpПожалуйста, изучите источник ClassLibrary и найдите код для извлечения или Google, чтобы найти его!

Чтобы получить имя папки просто используйтеPath.GetFileNameWithoutExtension((string)ISOFileName) который вернется"ISOFile" для iso по имени"ISOFile.iso", И тогда вы можете использовать его с желаемым путем.

UPDATE

Код для извлечения ISO-образа с помощью 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));
    }
}

Используйте это как:

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

За работой! Проверено мной!

И, конечно, вы всегда можете добавить больше оптимизации в код ...

Этот код просто базовый!

Могут ли эти комментарии быть удалены сейчас?
@Kev Я удаляю большинство моих комментариев!
@ I.am.WritZ Какие ошибки? У меня не было проблем с извлечением. Все, что вы добавили, было правдой, чтобы скрыть вердикт? ELSheepO
Спасибо, что прошли лишнюю милю! Возможно, вы захотите использовать меньший буфер и цикл вместо чтения всего файла в память, чтобы упростить извлечение больших файлов (например, например,in Jon's answer here) и, возможно, повторно использовать один и тот же буфер между файлами, но все выглядит хорошо.
Вы не поняли код на сайте DiscUtils ...
0

ter 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);
            }
        }

Похожие вопросы