2010-07-13 7 views
3

Je veux extraire .rar fichiers en utilisant shell cmd j'ai donc écrit ce code:Comment extraire un fichier rar en C#?

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(); 

La première fois il a bien fonctionné, la deuxième fois qu'il affiche rien.

+0

Est-ce qu'un script Powershell ou cmd pas plus approprié? Y a-t-il une raison particulière pour laquelle vous voulez faire cela dans le code? –

+0

Voir aussi http://stackoverflow.com/questions/11737/net-library-to-unzip-zip-and-rar-files –

+0

La bibliothèque Chilkat référencée dans les travaux ci-dessus est un régal. Seule l'irritation est que son code non managé. – Murph

Répondre

2

Vous pouvez sauter l'étape intermédiaire et appelez le winrar.exe avec les paramètres directement au lieu de la première instanciation cmd.exe

Aussi, vous pouvez jeter un oeil à la 7-zip SDK

1

Vous avez oublié d'ajouter un flux pour les erreurs de lecture. Si WINRAR se comporte correctement, vous trouverez votre sortie d'erreur lorsque vous ajoutez le flux pour le lire.

3

Utilisez SevenZipSharp comme il est un peu meilleure façon de faire les choses à travailler alors avec quelques années .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"; 
            })); 
    } 

Bien sûr, vous avez besoin d'ajuster un peu les choses et d'utiliser vos propres trucs. Mais pour l'exemple j'ai ajouté quelques méthodes supplémentaires.

+0

Existe-t-il un moyen d'extraire les archives? Je veux dire sans utiliser l'événement ExtractionFinished –

0

Comme Kjartan a suggéré, en utilisant SDK 7-Zip est peut-être une meilleure option que fraie un exécutable externe en fonction de votre utilisation:

SDK 7-Zip est une bibliothèque C/C++, mais http://sevenzipsharp.codeplex.com/ a une bibliothèque .Net de autour du SDK 7-Zip, ce qui le rend plus facile à utiliser dans .NET.

2
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; 
    } 



} 
3

J'ai fait une implémentation pure C# unrar. Fonctionne également dans Silverlight (éventuellement WP & 7)

http://nunrar.codeplex.com/

+0

Supporte-t-il les fichiers RAR protégés par mot de passe? – Ali

+0

Actuellement, ce n'est pas le cas. Bien, je prévois d'ajouter cela à http://sharpcompress.codeplex.com qui est le code le plus frais basé sur nunrar – adamhathcock

+0

clair et direct. Merci –

1

I Got la réponse. essayez celui-ci:

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(); 
0

9 réponses, que Sam Mousavi répond à votre question directement, mais de Noone vous dire ce qui ne va pas. Citant le manuel WinRAR:

... la commande: WinRAR x Fonts *.ttf NewFonts\
va extraire les fichiers * .ttf de l'archive vers le dossier Fonts NewFonts
Vous devez utiliser la barre oblique inverse comme dans l'exemple ci-dessus pour indiquant le dossier de destination.

Et c'est exactement ce qui manque là-haut à c:\download. En ce moment, il tente d'extraire le fichier c: \ download à l'intérieur de l'archive dans le répertoire en cours. Comment cela pourrait fonctionner la première fois est un mystère.

Cette note vous a plu? Donnez-moi une réputation bien nécessaire! Je peux presque voter!

0

Nous pouvons également utiliser,

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(); 
Questions connexes