7 Zip Extraer

Iniciado por rigorvzla, 1 Diciembre 2017, 01:57 AM

0 Miembros y 2 Visitantes están viendo este tema.

rigorvzla

Hola de nuevo amigos, como en el post anterior se logro un codigo para comprimir un archivo por medio del openfilediag, en este nuevo post ya hay gran parte del trabajo hecho, solo que no veo, y no doy con el problema no poder extraer, con la linea de comando.

espero alguien pueda ver y corregir este codigo

   using System;
   using System.Collections.Generic;
   using System.Linq;
   using System.Text;
   using System.Threading.Tasks;
   using System.Windows;
   using System.Windows.Controls;
   using System.Windows.Data;
   using System.Windows.Documents;
   using System.Windows.Input;
   using System.Windows.Media;
   using System.Windows.Media.Imaging;
   using System.Windows.Navigation;
   using System.Windows.Shapes;
   
   using Microsoft.Win32; //Necesario para el uso de OpenFileDialog
   using System.Diagnostics; //Necesario para el uso de ProcessStartInfo y Precess
   using System.IO; //Necesario para el uso de File y StreamWriter
   
   namespace WpfApplication1
   {
       /// <summary>
       /// Lógica de interacción para MainWindow.xaml
       /// </summary>
       public partial class MainWindow : Window
       {
           public MainWindow()
           {
               InitializeComponent();
           }
   
           private void Button_Click_1(object sender, RoutedEventArgs e)
           {
   
               OpenFileDialog ofd = new OpenFileDialog();
   
                   ofd.Title = "Archivos a comprimir";
                   ofd.Filter = "All files|*.7z; *.rar; *.zip; *.iso";
                   ofd.Multiselect = true;
                   if ((ofd.ShowDialog() == true))
                   {
                       StreamWriter sw = new StreamWriter("listfile.lst");
                       //Crea una lista de archivos
                       foreach (string n in ofd.FileNames)
                       {
                           sw.WriteLine(n);
                       }//foreach
                       sw.Close();
                       int mx = 1;
   
                       string targetName = "Example";
                       //Carpeta de destino
                       string pathDestination = "Prueba\\";
                       ProcessStartInfo p = new ProcessStartInfo();
                       p.FileName = "7za.exe";
   
                       p.Arguments = "a " + pathDestination + targetName + " @listfile.lst" + " -t7z -mx" + mx; <--- ERROR DE ARGUMENTOS (segun mi criterio)
                       p.WindowStyle = ProcessWindowStyle.Hidden;
                       Process x = Process.Start(p);
                       x.WaitForExit();
                       File.Delete("listfile.lst");
                   } //if
   
           }
       }
   }
   
   


busque en internet y decia que debia colocar la letra "x" en donde va "a" pero al hcerlo nada ocurre, alguna solucion del porque eso pasa? gracias de antemano

Eleкtro

#1
Cita de: rigorvzla en  1 Diciembre 2017, 01:57 AMbusque en internet y decia que debia colocar la letra "x" en donde va "a" pero al hcerlo nada ocurre, alguna solucion del porque eso pasa? gracias de antemano

Sin ánimo de ofender, ¿pero como pretendes utilizar un lenguaje de programación de alto nivel para desarrollar un algoritmo que ejecute un programa command-line, si nisiquiera conoces la sintaxis del programa que quieres ejecutar, ni tampoco has adquirido un dominio de dicho lenguaje de programación a nivel usuario?. En serio, ¿no crees que algo está fallando en tu modo de ejecución?, basicamente estás queriendo construir la casa por el tejado...

Cita de: rigorvzla en  1 Diciembre 2017, 01:57 AMen el post anterior se logro un codigo para comprimir un archivo

Efectivamente, date cuenta de que ya publicaste un thread en el que no sabías cual era el comando de 7-Zip para comprimir ni tampoco comprendías como ejecutar el programa desde .NET, y ahora publicas un nuevo thread por que no sabes cual es el comando de 7-Zip para descomprimir ni como ejecutar el programa desde .NET.

En aquél thread se te ofrecieron varias soluciones y explicaciones que no pudiste entender o no quisiste leer, y al final ese thread se convirtió en una acumulación de comentarios llegando a tres páginas enteras por que practicamente no comprendías nada de lo que se te explicaba por parte de los usuarios que te ayudaron.

Sinceramente, ¿a ti todo lo que acabo de decir te parece bien?. ¿De que nos serviría a nosotros corregirte el código y decirte cual es el fallo (que es bien facil por cierto), si tú vas a seguir sin estudiar lo básico del lenguaje, la sintaxis/comandos de 7-Zip, y al final no habrás aprendido nada por tu cuenta?.

Es tu responsabilidad primero estudiar, practicar y aprender lo básico del lenguaje, y entonces, y solo entonces ya podrás ponerte a desarrollar códigos como este y formular preguntas específicas en el foro para las dudas que tengas.

Lo cierto es que estás programando a palos de ciego sin saber lo que haces ni como hacerlo, y ese no es el camino adecuado para intentar programar absolutamente nada, de hecho, así lo único que conseguirás es que la gente se canse de ofrecerte ayuda... por que probablemente será necesario llenar 2 o 3 páginas de comentarios para que comprendas cualquier cosa...

Ojo, no te estoy llamando tonto ni nada por el estilo, simplemente digo que estás haciendo las cosas en el orden incorrecto por que quieres desarrollar códigos sin haber aprendido el aprendizaje básico de .NET, y así es normal que te atasques y necesites ayuda para solucionar cualquier pequeña cosa...




Yo en tu lugar, empezaría por aprender como es la sintaxis del programa (el comando para descomprimir te lo pone aquí):


Ahí tienes todo lo que necesitas saber, una vez sepas cual es el comando ya puedes aplicarlo en tu algoritmo de C#, pero primero deberías estudiar lo básico del lenguaje C# y de .NET Framework hasta obtener un dominio del lenguaje a nivel usuario, insisto.


PD: espero no haberme pasado demasiado escribiéndote esta crítica constructiva, pero considero que el tipo de ayuda más responsable que se le puede ofrecer a alguien en estas circunstancias, es llamándole la atención para intentar hacerle comprender que las cosas no se hacen así... que esa persona también ha de poner de su parte para que le ayuden.

Un saludo!








okik

#2
Mira esto

https://sevenzip.osdn.jp/chm/cmdline/commands/extract.htm

https://sevenzip.osdn.jp/chm/cmdline/commands/extract_full.htm



Lo que no entiendo es como por ti mismo no has sabido resolver el problema
Código (csharp) [Seleccionar]

p.Arguments = "a " + pathDestination + targetName + " @listfile.lst" + " -t7z -mx" + mx;


Debes recordar que 7za.exe cuando se usa un directorio no sabe interpretar espacios por ejemplo "C:\Nueva Carpeta", este directorio no sería encontrado y se deben usar las dobles comillas. Por ello en C# debes usar   \" antes y al final del directorio completo que representa la doble comilla [ " ]
Ej.:
Código (csharp) [Seleccionar]
string pathName = ofd.FileName;  //devuelve C:\\Nueva Carpeta

Esto se pondría de la siguiente manera
"a " + "\"" + pathName  + "\"" + ...

y equivale a:
a "C:\Nueva Carpeta"


DESCOMPRIMIR
En cuanto a descomprimir, a estas alturas ya deberías saber como va esto.

Lo primero el código que expones es para comprimir, como ya sabrás y los comandos a usar son de diferente manera. Además en el otro hilo ya te expuse todos los comandos de 7za.exe, y dice claramente usar e o x para descomprimir. La diferencia es que el segundo  crea las carpetas que contenga el archivo comprimido. Es decir los directorios completos comprimidos.

La forma
Una forma de hacerlo sería esta.

(En WPF  y C#)

Código (csharp) [Seleccionar]

using System.Windows;
using Microsoft.Win32; //Necesario para el uso de OpenFileDialog
using System.Diagnostics; //Necesario para el uso de ProcessStartInfo y Precess
namespace WpfApplication1
{
   /// <summary>
   /// Lógica de interacción para MainWindow.xaml
   /// </summary>
   public partial class MainWindow : Window
   {
       public MainWindow()
       {
           InitializeComponent();
       }

       private void Button_Click_1(object sender, RoutedEventArgs e)
       {
           OpenFileDialog ofd = new OpenFileDialog();

           ofd.Title = "Archivos a descomprimir";
           ofd.Filter = "Zip file|*.zip; *.7z;*.iso";
           ofd.Multiselect = true;
           if ((ofd.ShowDialog() == true))
           {              
             
               string zipName = ofd.FileName;
               //Carpeta de destino
               string pathDestination = "Unzip\\";
               string typeFiles = "*.*";  //aquí el tipo de archivos a descomprimir ej: "*.exe"; [*.* = all files]
               ProcessStartInfo p = new ProcessStartInfo();
               p.FileName = "7za.exe";

               //e archive.zip -oc:\soft *.cpp -r
               //e ARCHIVO_ZIP -oDIRECTORIO_DESTINO TIPO_DE_ARCHIVOS_A_DESCOMPRIMIR
               //-r subdirectorios recurrentes
               //-y Sobrescribe los archivos si ya existen
               // \" equivale a "

               // e Extrae todo en un mismo directorio (sin carpetas)        
               //p.Arguments = "e " + "\"" + zipName + "\"" + " -o" + "\"" + pathDestination + "\" " + typeFiles + " -r";

               //x  Extre todo con directorios completos (con subcarpetas)
               p.Arguments = "x " + "\"" + zipName + "\"" + " -o" + "\"" +
               pathDestination + "\" " + typeFiles + " -r -y";
               p.WindowStyle = ProcessWindowStyle.Hidden;
               Process x = Process.Start(p);
               x.WaitForExit();  
           } //if
       }
   }
}



Nótese la variable
Código (csharp) [Seleccionar]

string pathDestination = "Unzip\\";


Esto crea una carpeta y ahí descomprime el archivo. Lo suyo es crear un botón y mostrar un cuadro de diálogo para seleccionar un directorio de destino, o al menos la opción de seleccionarlo. El cual se introduciría en la variable pathDestination .

Nótese también el uso de filtros en el cuadro de diálogo para permitir seleccionar solamente archivos zip, 7z y iso.

Código (csharp) [Seleccionar]

ofd.Filter = "Zip file|*.zip; *.7z;*.iso";




Fíjate en el uso de -y
Esto es el equivalente a responder YES

Resulta que al ocultar la ventana de consola no ves que cuando los archivos que vas a descomprimir ya existen en el directorio de destino, 7za.exe te pregunta si quieres sobrescribir y debes responder.

(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit?

Para evitarlo se usa  -y




Da la sensación que no entiendes los códigos y te limitas a hacer copias y pegas de códigos completos que sabes que hacen esto o aquello. Si entiendes el código simplemente modificas cuatro cosa y punto.

Debes practicar las cosas por separado. El manejo de cuadros de diálogo por ejemplo. Y en el caso de 7za.exe, en lugar de ponerte a intentar usar comandos desde NET, primero prueba a hacerlo desde un archivo CMD o BAT y pones...


7za.exe e prueba.zip  -oD:\Unzip *.exe -r
pause


[dentro de Prueba.zip]
- demo.exe
- prueba.txt
- \mi carpeta\demo2.exe

o pones...

7za.exe x prueba.zip -oD:\Unzip *.* -r
pause


Con "pause" evitas que la consola se cierre automáticamente y puedas leer si hubo algún tipo de error, el cual podrás corregir.

Una vez tengas claro como usar los comandos lo aplicas desde NET.



Una forma equivalente a usar un archivo cmd o bat desde NET es ejecutar la clase process usando cmd en lugar del Shell del sistema operativo. Y pausar la ventana de consola para ver la información.


Código (csharp) [Seleccionar]

               p.Arguments = "/K 7za.exe  x " + "\"" + zipName + "\"" + " -o" + "\"" +
               pathDestination + "\" " + typeFiles + " -r";
               p.UseShellExecute = false; //no usar el shell del sistema operativo
               p.FileName = "cmd"; //usar cmd.exe
               p.WindowStyle = ProcessWindowStyle.Normal ;




rigorvzla

#3
No elektro nada de ofender, por que es la realidad y si lo tengo muy claro en deber empezar a leer mas de c# y programacion orientada a obejos, en efecto si habia visto ejemplos donde saliean "\" estos parentecis cosas que no sabia para que eran, cosa que entiendo ya, "palos de ciego" me causo gracias por que es verdad y hasta yo mismo me incomodo por no saber realmente lo que hago, y en ocasiones resolver asuntos solo por mera casualidad o suerte, esta ayuda la agradezco enteramente y ya eh estado bajando videos tutoriales para empaparme del asunto, como deberia ser, procurare al terminar este problema de extraccion , plantear una duda generada por el material de estudio, es posible hacerlo? gracias nuevamente y  me pondre manos a la obra con la guia de okik al regresar del trabajo, buen dia y gracias. (nota no descomprime "*.rar" , " *.iso") y lei en la pagina que si lo hace, hay q hacerlo de manera distinta , ya que con zip y 7z va sin novedad.

Eleкtro

#4
Cita de: rigorvzla en  1 Diciembre 2017, 10:48 AM(nota no descomprime "*.rar" , " *.iso") y lei en la pagina que si lo hace

En el manual de 7-Zip en los enlaces que te mostré, se puede leer lo siguiente:

Cita de: https://sevenzip.osdn.jp/chm/cmdline/index.htm7za.exe (a = alone) is a standalone version of 7-Zip. 7za.exe supports only 7z, cab, zip, gzip, bzip2, Z and tar formats. 7za.exe doesn't use external modules.

Entonces, si quieres extraer archivos ISO y RAR tienes que usar 7z.exe (no 7za.exe). También puedes usar la herramienta command-line unrar.exe (incluida en WinRAR) para la extracción de archivos RAR.

...¿ves por que primeramente hay que leer para informarse y conocer las propiedades del programa que quieres ejecutar desde "X" lenguaje de programación?.

Saludos!








okik

Cita de: Eleкtro en  1 Diciembre 2017, 12:02 PM
Entonces, si quieres extraer archivos ISO y RAR tienes que usar 7z.exe (no 7za.exe). También puedes usar la herramienta command-line unrar.exe (incluida en WinRAR) para la extracción de archivos RAR.

Pues mira no sabía que con 7za.exe no se podía descomprimir ISO. Siempre he usado 7z.exe, el que me descargué hace un tiempo. Pero nunca traté de descomprimir ISO. Tampoco ahora con 7za.exe para el ejemplo, pero como @rigorvzla lo puso en su código, di por hecho que se debía poder y lo puse en los filtros del cuadro abrir.

Efectivamente no se puede con 7za.exe y si con 7z.exe, lo acabo de testar.

rigorvzla

#6
en efecto como el amigo okik dijo si resulto tal cual solo cambie el exe y todo lo deje como estaba, gracias de nuevo, me pondre a aprender de videos y los docuemntos que me facilito elektro para continuar en mi proyecto y no andar perdido o no tanto, feliz noche , ya solo me queda colocar un boton para cancelar la accion por que al comenzar a extraer ya no hay vuelta atras si te arrepientees,eso lo hice pero buscar una forma de que la pausa mientras comprime o descomprime , no me inabilite todo el programa y me deje usar el boton de cancelar, tengo varias opciones que probare y les cuento despues de mi resultado, gracias de nuevo

Eleкtro

#7
Cita de: rigorvzla en  2 Diciembre 2017, 03:34 AMya solo me queda colocar un boton para cancelar la accion por que al comenzar a extraer ya no hay vuelta atras si te arrepientees,eso lo hice pero buscar una forma de que la pausa mientras comprime o descomprime , no me inabilite todo el programa y me deje usar el boton de cancelar, tengo varias opciones que probare y les cuento despues de mi resultado, gracias de nuevo

Vuelve a leer:
Cita de: Eleкtro en 21 Noviembre 2017, 13:56 PM
Lo más apropiado para obtener un control absoluto y eficiente sobre el procedimiento de compresión y descompresión de 7-Zip sería que implementases las funciones exportadas en la librería 7z.dll mediante Platform Invoking, puedes ver un ejemplo ya hecho aquí:

....entiendo que esto es mucho pedir ya que estás empezando en .NET y desconoces muchos conceptos todavía, así que descartamos esa opción, pero sería preferible que en lugar de lo que estás haciendo actualmente llamando al executable 7za.exe sin más, en lugar de eso al menos utilizases la librería SevenZipSharp (a pesar de que esté bastante desactualizada), ya que al menos proporciona un modo mucho más seguro y sofisticado de control mediante su estructuración de código orientado a eventos, esto te permimtiría controlar facilmente el progreso de compresión/descompresión y cualquier error suscribiéndote al evento correspondiente, además de ofrecer la gran ventaja de poder usar enumeraciones y tipos/clases que representan las diversas funcionalidades de 7-Zip y todos esos parámetros que le pasas por command-line al executable 7za.exe.

Ya te avisé del camino que debías elegir para hacer esto medianamente bien. Ahora te pasa lo que era evidente desde un principio, que quieres controlar cosas que sencillamente están fuera de las limitaciones de interoperabilidad entre tu código y el proceso 7z.exe.

Puesto que estás llevando esta tarea de la forma menos eficiente posible, es decir, ejecutando el proceso externo 7z.exe en vez de usar la librería nativa de 7-Zip (7z.dll) o en su defecto la librería administrada SevenZipSharp, la única opción viable y más o menos eficiente para pausar de forma arbitraria el procedimiento de compresión/descompresión es recurrir a la función SuspendThread y ResumeThread de la API de Windows:


Ten en cuenta que 7z.exe usará varios threads para la compresión, así que tendrás que enumerar y pausar todos los threads del proceso. Ejemplo en pseudo-código:

Código (csharp) [Seleccionar]
Process p = Process.GetProcessesByName("7z").SingleOrDefault();

foreach (ProcessThread t in p.Threads) {
   Pausar_o_Continuar_Thread(t.Id);
}


Pero las funciones SuspendThread y ResumeThread solo aceptan como parámetro un handle al thread, así que para poder pausar o continuar un thread primero tienes que usar la función de Windows OpenThread con el identificador del thread obtenido, y pasándole como argumento la petición de acceso (el flag THREAD_SUSPEND_RESUME) para permitir la suspensión del thread...


Ejemplo en pseudo-código:
OpenThread(ThreadAccessRights.SuspendResume, True, threadId)




En resumen, que aquí te estarías metiendo de lleno en terreno pantanoso con el uso de código no administrado y un poco de administración de hilos de procesos externos y handles del sistema operativo, y primero tendrías que estudiar más las cosas básicas del lenguaje C# y de .NET Framework en general antes de intentar meterte en temas de Platform Invoking... o esperar que @Okik te regale todo el código hecho en C# con las indicaciones que acabo de dar.

Todavía estás a tiempo de tomar el primer consejo que te di cuando publicaste este tipo de preguntas en el foro, es decir, aun puedes retroceder y ponerte a usar la librería nativa 7z.dll o en su defecto la librería administrada SevenZipSharp, siendo esta última mucho más sencilla de aplicar para cualquier nivel de aprendizaje, pero aun así es necesario estudiar más antes de ponerse a usar nada de eso, por que requieren cierto tipo de conocimientos adicionales.

PD: para mi framework comercial ElektroKit implementé todo este tipo de funcionalidades, me refiero: "pausar un proceso", suspender o reanudar un thread, e incluso tengo un cliente completo de la libreria SevenZipSharp orientado a eventos para representar el procedimiento de compresión y descompresión de lo más abstracto y sencillo posible (y si, soporta el formato RAR4/RAR5 e ISO), aunque todas estas funcionalidades las hice en el lenguaje VB.NET, no C#, pero si quieres que te muestre algún código de esos en VB.NET para hacerte una idea pues... solo tienes que pedirlo, aunque ya te aviso que son códigos "grandecitos" y... probablemente puedan resultar confusos para cierto nivel de aprendizaje.

Saludos.








rigorvzla

hola de nuevo, les cuento que en efecto lei temas relacionados a los threads o (hilos) y bueno ... entendi poco para variar ,, pero como ante la adversidad el ingenio aflora, lo resolvi cerrando el proceso desde la aplicacion base y listo, ya a este punto dare por terminado este tema agradecido por los que me asistieron y empezar a informarme del tema , muuuchas gracias y gracias por los tutoriales que me dejaron en post anteriores ya hay tela de donde cortar para empeparse del asunto