Извлекать ISO с WinRar автоматически с помощью C# или партии
Я пытаюсь извлечь ISO в папку с тем же именем без.iso в конце.
У меня проблема с winrar, так как он не запустит распаковку, когда я начну с поиска, начиная с папки с ISO.
ОБНОВЛЕНО с кодом ответа
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));
}
}
Пользователь выбирает папку для извлечения (.ISO) для извлечения. Затем я использую его в Process.Start() в фоновом режиме. Кажется, что это открывает программное обеспечение для монтирования и не извлекает ISO в нужное имя папки.
Заранее спасибо за помощь.
Или если бы кто-нибудь мог дать мне пакет для извлечения ISO и вызова его из C# с передачей в Extract и именем папки, что также было бы полезно.
Спасибо
4 ответа
Если внешние библиотеки классов в порядке!
Тогда используйте SevenZipSharp
или же .NET DiscUtils
извлечь ISO...
Эти две библиотеки классов могут управлять ISO и извлекать их!
За DiscUtils
Вы можете найти некоторые коды для управления ISO [ CDReader
Класс] по ссылке, которую я предоставил.
Но для SevenZipSharp
Пожалуйста, изучите источник ClassLibrary и найдите код для извлечения или Google, чтобы найти его!
Чтобы получить имя папки просто используйте Path.GetFileNameWithoutExtension((string)ISOFileName)
который вернется "ISOFile"
для iso по имени "ISOFile.iso"
, И тогда вы можете использовать его с желаемым путем.
ОБНОВИТЬ
Код для извлечения 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) + "\\");
За работой! Проверено мной!
И, конечно, вы всегда можете добавить больше оптимизации в код...
Этот код просто базовый!
Для UDF или для создания файлов Windows ISO после обслуживания (DISM) без необходимости вышеуказанный принятый ответ не работает для меня, поэтому я попробовал этот метод работы с 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
Недавно я столкнулся с такой проблемой извлечения.iso. Попробовав несколько способов, 7zip сделал всю работу за меня, вам просто нужно убедиться, что в вашей системе установлена последняя версия 7zip. Может быть, это поможет попробовать {
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);
}
}
Попробуй это:
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, оно будет работать так же.
Насколько я вижу в вашем текущем коде, нет команды для извлечения файла, и нет пути к файлу, который нужно извлечь. Попробуйте этот пример и дайте мне знать, если он работает =]
PS Если вы хотите скрыть экран извлечения, вы можете установить YourProcessInfo.WindowStyle
в ProcessWindowStyle.Hidden
,