Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: rigorvzla en 11 Mayo 2019, 03:55 am



Título: Como cancelar proceso de sevenzip
Publicado por: rigorvzla en 11 Mayo 2019, 03:55 am
Hola amigos sere breve con mi problema, uso la libreria SevenZipSharp para comprimir y extraer archivos, todo funciona de manera correcta, puedo comprimir y extraer, puedo obtener el progreso de la accion.

El problema radica en que NO puedo cancelar la accion en curso, ocurre que si puedo cancelar el siguiente proceso de compresion o extraccion, mas NO el que ya esta en proceso , podria alguien ayudarme con esto?

Código:
SevenZipBase.SetLibraryPath(path);
                        var tmp = new SevenZipCompressor();
                        tmp.ArchiveFormat = OutArchiveFormat.SevenZip;
                        tmp.CompressionMethod = SevenZip.CompressionMethod.Lzma;
                        tmp.CompressionLevel = CompressionLevel.Ultra;
                        tmp.FileCompressionStarted += (s, e) =>
                        {
                            e.Cancel = Cancelar;
                            Dispatcher.Invoke(() =>
                            {
                                des.txtTest.AppendText(String.Format("{0} {1}", e.FileName, Environment.NewLine));
                                des.txtTest.ScrollToEnd();
                            });
                        };
                        tmp.Compressing += (s, e) =>
                        {
                            e.Cancel = Cancelar;
                            Dispatcher.Invoke(() => des.lblPorcentaje.Content = (String.Format("[{0}%]", e.PercentDone)));
                        };
                        tmp.CompressionFinished += (s, e) => Dispatcher.Invoke(() => des.txtTest.AppendText(MultiLenguaje.biblioGra04));
                       tmp.CompressDirectory(folderToZip, destFile);

Este metodo:  tmp.CompressDirectory(folderToZip, destFile) es donde se realiza la accion y no encuentro como hacer que se cancele cuando lo quiero , me obliga a esperar a q termine esa accion para que luego en el siguiente proceso se cancele, (esto ocurre cuando se va a comprimir o extraer a mas de un archivo) pero en caso de ser un unico archivo y quiera cancelar el proceso Nno allo como no puedo.

Espero puedan ayudarme, gracias de antemano.


Título: Re: Como cancelar proceso de sevenzip
Publicado por: ThunderCls en 17 Mayo 2019, 07:14 am
Has probado con esto?

https://github.com/phillipp/SevenZipSharp/blob/737f9601955a2e1cdbcce658e9d610aa97d955c8/SevenZipTest/Program.cs#L136
http://www.vbforums.com/showthread.php?697661-RESOLVED-SevenZipSharp-aborting-compression

No he usado esta libreria pero al parecer todo se trata de la variable

Código
  1. e.Cancel = true;


Título: Re: Como cancelar proceso de sevenzip
Publicado por: rigorvzla en 17 Mayo 2019, 13:12 pm
Hola, gracias por tu respuesta, si probe con eso, pero no funciona en el proceso actual, cancelara el siguiente proceso, y me explicaron que una vez empezado el proceso de exraccion o compresion, no se puede manipular hasta que termine, mas si manipular antes de que se ejecute la accion.

Simplificando el asunto, puedo cancelar el proceso antes de que empiece mas no durante su ejecucion.


Título: Re: Como cancelar proceso de sevenzip
Publicado por: ThunderCls en 17 Mayo 2019, 14:34 pm
- En el segundo link que te puse hay alguien con el mismo problema que tu y logro solucionarlo, te aconsejaria echarle un ojo a su metodo.
- No se si sera una deficiencia de la libreria o si existe otro metodo, pero igual una forma no muy eficiente que pudiera funcionar seria poner este codigo de compresion dentro de un hilo y simplemente forzar el cierre del hilo cuanod quieras cancelar la compresion. Como dije, no eficiente o seguro pero pudiera resolverte el problema


Título: Re: Como cancelar proceso de sevenzip
Publicado por: Eleкtro en 17 Mayo 2019, 16:03 pm
No se de donde habrás tomado como ejemplo ese código, pero los datos del evento SevenZipCompressor.Compressing se representan mediante la clase SevenZip.ProgressEventArgs, la cual no implementa la interfaz SevenZip.ICancellable (como si que la implementa la clase SevenZip.FileNameEventArgs del evento SevenZipCompressor.FileCompressionStarted), así que no provee ninguna propiedad "Cancel" para poder cancelar la operación de compresión sobre el archivo actual. Mírate el código fuente de la librería.

Una solución sencilla y óptima (a falta de no tener la funcionalidad de cancelar compresión en la propia librería) podría ser la siguiente:
Cita de: https://archive.codeplex.com/?p=sevenzipsharp
I ended up using Thread.Abort() after getting the thread that the compression was occurring on. It's not a pretty solution, but it works.

De todas formas no me cansaré de advertir que SevenZipSharp es un wrapper obsoleto desde hace varios años, diría yo que desde antes de que se advirtiese con 1 o 2 años de antelación la muerte definitiva de la plataforma CodePlex. Por que recuerdo que años antes de que se advirtiese yo actualicé mi versión de SevenZipSharp y nunca más volví a ver una nueva release cuando quise buscar actualizaciones...

Es una librería literalmente muerta (descontinuada por el autor). Luego aparecieron un par de forks en GitHub del código original de CodePlex pero creo que ninguno es del autor original. No lo se a ciencia cierta, pero parecen ser forks de terceros (quienes además publican en NuGet) en los que supuestamente actualizan la versión de 7z.dll, la versión de .NET framework y poco o nada más.

En mi opinión personal, a menos que solo necesites hacer operaciones muy simples (y sincrónicas) de compresión o extracción, entonces no merece la pena usar SevenZipSharp. Mucho mejor recurrir a cualquier otro proyecto que sea activo, como por ejemplo DotNetZip (también conocido como Ionic Zip). Sacrificarías el ratio de compresión del algoritmo 7z, por la sofisticación. O eso, o le haces las modificaciones pertinentes al código fuente original de SevenZipSharp para implementar la cancelación, o usas directamente la librería nativa 7z.dll... es decir, implementar tu propio wrapper, lo cual sería la más tediosa/inviable de todas las opciones.

Aquí tienes unos ejemplos de compresión con cancelación usando la librería DotNetZip:
  • https://stackoverflow.com/a/50629483/1248295
  • https://www.whitebyte.info/programming/saveprogress-example-for-dotnetzip

Saludos.


Título: Re: Como cancelar proceso de sevenzip
Publicado por: rigorvzla en 18 Mayo 2019, 01:52 am
gracias como siempre elektro
Citar
De todas formas no me cansaré de advertir que SevenZipSharp es un wrapper obsoleto desde hace varios años

imagino que ya has dicho esto muuchas veces, ya se que no tiene solucion por parte del mismo wraper en este caso ya dejare la solucion que implemente (reinicar la aplicacion...) revisare los enlaces que has dejado y te agradezco la respuesta, en lo personal, sacrificar el algorismo de 7z no me gustaria ya que tiene una tasa de compresion muy buena, pero como dices tu ya seria cosa de ver para que tipo de trabajo lo usaria.

Gracias tremendas elektro tema aclarado y resuelto, lastima no hubo mas desarrollo de ese proyecto.


Título: Re: Como cancelar proceso de sevenzip
Publicado por: Eleкtro en 18 Mayo 2019, 07:56 am
en este caso ya dejare la solucion que implemente (reinicar la aplicacion...)

Te he indicado una solución que en principio sería más simple: Thread.Abort().

He probado el código que has mostrado, pero en Windows Forms. He forzado la cancelación llamando a Thread.Abort() en el thread del dispatcher del controlador del evento SevenZipCompressor.Compressing despues de X intervalo de tiempo, pero esto solo me ha funcionado cuando el modo de comprensión es SevenZip.CompressionMethod.Copy, es decir, sin compresión. La operación de compresión copiado se detiene al instante, pero con el método de compresión Lzma / Lzma2 no parece tener efecto. No me preguntes por qué. Quizás hice algo mal sin darme cuenta. Ya eliminé el código.

Aparte, más simple todavía y para no tener que lidiar con la excepción ThreadAbortException, he descubierto que simplemente anulando la instancia de SevenZipCompressor (en tu código reemplazarías eso de 'e.Cancel = Cancelar;' por: 'tmp = null;' en el controlador del evento SevenZipCompressor.Compressing) la operación de compresión también finaliza al instante. Pero de nuevo esto solo me ha funcionado con el método de compresión SevenZip.CompressionMethod.Copy.

Quizás tu obtengas resultados diferentes en tu código de WPF. Yo te lo dejo ahí.

Saludos


Título: Re: Como cancelar proceso de sevenzip
Publicado por: rigorvzla en 18 Mayo 2019, 13:39 pm
gracias, lo intentare, aunque probe ya de esas maneras y yo crei tambien que habia hecho algo malo, no en el copy, pero al parcer es la libreria de todos modos probare lo ultimo que mensionastes, pero creo q no tendra efecto, de todos modos gracias por la idea espero resulte buen dia.