Как извлечь RAR-файл в C #? - PullRequest
4 голосов
/ 13 июля 2010

Я хочу извлечь файлы .rar с помощью оболочки cmd, поэтому я написал такой код:

string commandLine = @"c:\progra~1\winrar\winrar e  c:\download\TestedU.rar c:\download";
ProcessStartInfo PSI = new ProcessStartInfo("cmd.exe");
PSI.RedirectStandardInput = true;
PSI.RedirectStandardOutput = true;
PSI.RedirectStandardError = true;
PSI.UseShellExecute = false;
Process p = Process.Start(PSI);
StreamWriter SW = p.StandardInput;
StreamReader SR = p.StandardOutput;
SW.WriteLine(commandLine);
SW.Close(); 

Первый раз, когда он работал нормально, во второй раз, когда ничего не отображалось.

Ответы [ 9 ]

4 голосов
/ 13 июля 2010

Используйте SevenZipSharp , так как это немного лучше, чем работать с некоторыми .exe-файлами.

private ReadOnlyCollection<string> ExtractArchive(string varPathToFile, string varDestinationDirectory) {
        ReadOnlyCollection<string> readOnlyArchiveFilenames;
        ReadOnlyCollection<string> readOnlyVolumeFilenames;
        varExtractionFinished = false;
        varExtractionFailed = false;
        SevenZipExtractor.SetLibraryPath(sevenZipDll);
        string fileName = "";
        string directory = "";
        Invoke(new SetNoArgsDelegate(() => {
                                         fileName = varPathToFile;
                                         directory = varDestinationDirectory;
                                     }));
        using (SevenZipExtractor extr = new SevenZipExtractor(fileName)) {
            //string[] test = extr.ArchiveFileNames.

            readOnlyArchiveFilenames = extr.ArchiveFileNames;
            readOnlyVolumeFilenames = extr.VolumeFileNames;
            //foreach (string dinosaur in readOnlyDinosaurs) {
            //MessageBox.Show(dinosaur);
            // }
            //foreach (string dinosaur in readOnlyDinosaurs1) {
            // // MessageBox.Show(dinosaur);
            // }
            try {
            extr.Extracting += extr_Extracting;
            extr.FileExtractionStarted += extr_FileExtractionStarted;
            extr.FileExists += extr_FileExists;
            extr.ExtractionFinished += extr_ExtractionFinished;

                extr.ExtractArchive(directory);
            } catch (FileNotFoundException error) {
                if (varExtractionCancel) {
                    LogBoxTextAdd("[EXTRACTION WAS CANCELED]");
                } else {
                    MessageBox.Show(error.ToString(), "Error with extraction");
                    varExtractionFailed = true;
                }
            }
        }
        varExtractionFinished = true;
        return readOnlyVolumeFilenames;
    }

  private void extr_FileExists(object sender, FileOverwriteEventArgs e) {
        listViewLogFile.Invoke(new SetOverwriteDelegate((args) => LogBoxTextAdd(String.Format("Warning: \"{0}\" already exists; overwritten\r\n", args.FileName))), e);
    }
    private void extr_FileExtractionStarted(object sender, FileInfoEventArgs e) {
        listViewLogFile.Invoke(new SetInfoDelegate((args) => LogBoxTextAdd(String.Format("Extracting \"{0}\"", args.FileInfo.FileName))), e);
    }
    private void extr_Extracting(object sender, ProgressEventArgs e) {
        progressBarCurrentExtract.Invoke(new SetProgressDelegate((args) => progressBarCurrentExtract.Increment(args.PercentDelta)), e);
    }
    private void extr_ExtractionFinished(object sender, EventArgs e) {
        Invoke(new SetNoArgsDelegate(() => {
                                         //pb_ExtractWork.Style = ProgressBarStyle.Blocks;
                                         progressBarCurrentExtract.Value = 0;
                                         varExtractionFinished = true;
                                         //l_ExtractProgress.Text = "Finished";
                                     }));
    }

Конечно, вам нужно немного подправить вещи и использовать некоторые из ваших собственных вещей. Но для примера я добавил несколько дополнительных методов.

3 голосов
/ 13 июля 2010

Вы можете пропустить средний шаг и вызвать winrar.exe с параметрами прямо вместо первого создания экземпляра cmd.exe

Также вы можете взглянуть на 7-zip SDK

2 голосов
/ 31 августа 2010
UnRar("C:\\Download\\sampleextractfolder\\", filepath2);

private static void UnRar(string WorkingDirectory, string filepath)
{

    // Microsoft.Win32 and System.Diagnostics namespaces are imported

    //Dim objRegKey As RegistryKey
    RegistryKey objRegKey;
    objRegKey = Registry.ClassesRoot.OpenSubKey("WinRAR\\Shell\\Open\\Command");
    // Windows 7 Registry entry for WinRAR Open Command

    // Dim obj As Object = objRegKey.GetValue("");
    Object obj = objRegKey.GetValue("");

    //Dim objRarPath As String = obj.ToString()
    string objRarPath = obj.ToString();
    objRarPath = objRarPath.Substring(1, objRarPath.Length - 7);

    objRegKey.Close();

    //Dim objArguments As String
    string objArguments;
    // in the following format
    // " X G:\Downloads\samplefile.rar G:\Downloads\sampleextractfolder\"
    objArguments = " X " + " " + filepath + " " + " " + WorkingDirectory;

    // Dim objStartInfo As New ProcessStartInfo()
    ProcessStartInfo objStartInfo = new ProcessStartInfo();

    // Set the UseShellExecute property of StartInfo object to FALSE
    //Otherwise the we can get the following error message
    //The Process object must have the UseShellExecute property set to false in order to use environment variables.
    objStartInfo.UseShellExecute = false;
    objStartInfo.FileName = objRarPath;
    objStartInfo.Arguments = objArguments;
    objStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    objStartInfo.WorkingDirectory = WorkingDirectory + "\\";

    //   Dim objProcess As New Process()
    Process objProcess = new Process();
    objProcess.StartInfo = objStartInfo;
    objProcess.Start();
    objProcess.WaitForExit();


    try
    {
        FileInfo file = new FileInfo(filepath);
        file.Delete();
    }
    catch (FileNotFoundException e)
    {
        throw e;
    }



}
1 голос
/ 17 июля 2012

Получил ответ.попробуйте это:

 System.Diagnostics.Process proc = new System.Diagnostics.Process();
 //Put the path of installed winrar.exe
 proc.StartInfo.FileName = @"C:\Program Files\WinRAR\unrar.exe";
 proc.StartInfo.CreateNoWindow = true;
 proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
 proc.EnableRaisingEvents = true;

 //PWD: Password if the file has any
 //SRC: The path of your rar file. e.g: c:\temp\abc.rar
 //DES: The path you want it to be extracted. e.g: d:\extracted

 //ATTENTION: DESTINATION FOLDER MUST EXIST!

 proc.StartInfo.Arguments = String.Format("x -p{0} {1} {2}", PWD, SRC, DES);


 proc.Start();
1 голос
/ 13 июля 2010

Вы забыли добавить поток для ошибок чтения.Если WINRAR ведет себя правильно, вы найдете вывод ошибок при добавлении потока для его чтения.

0 голосов
/ 11 марта 2016

Мы также можем использовать это,

string SourceFile = @"G:\SourceFolder\125.rar";
string DestinationPath = @"G:\Destination\";
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = @"G:\Software\WinRAR.exe";
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.EnableRaisingEvents = false;            
process.StartInfo.Arguments = string.Format("x -o+ \"{0}\" \"{1}\"", SourceFile, DestinationPath);
process.Start();
0 голосов
/ 20 декабря 2012

9 Ответы, только Сам Мусави отвечает на ваш вопрос напрямую, но никто не говорит вам, что не так.Ссылаясь на руководство WinRAR:

... команда: WinRAR x Fonts *.ttf NewFonts\
извлечет * .ttf файлы из архива Шрифты в папку NewFonts
Вам необходимо использовать трейлингобратную косую черту, как в примере выше для обозначения папки назначения.

И это именно то, чего не хватает там на c:\download.Сейчас он пытается извлечь файл c: \ download из архива в текущий каталог.Как это могло сработать в первый раз - загадка.

0 голосов
/ 13 июля 2010

Как предположил Кьяртан, использование 7-Zip SDK может быть лучшим вариантом, чем порождение внешнего исполняемого файла в зависимости от вашего использования:

7-Zip SDK - это библиотека C / C ++, но http://sevenzipsharp.codeplex.com/имеет библиотеку .Net вокруг 7-Zip SDK, что облегчает использование в .NET.

0 голосов
/ 13 июля 2010

Вы можете использовать эту библиотеку напрямую: http://sevenziplib.codeplex.com/

SevenZipLib - это легкий, простой в использовании управляемый интерфейс к библиотеке 7-zip.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...