7-ZIp

Iniciado por rigorvzla, 21 Noviembre 2017, 04:21 AM

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

rigorvzla

Hola de nuevo amigos, despues de una batalla ganada en esta gran guerra jeje, me decido a usar (no se si llamarle api) de 7zip ya que quiero poder hacer click en un archivo cualquiera de mi pc y con una orden se comprima. alguien teine alguna idea? dejo un ejemplo que consegui pero no puedo llevar acabo ya que por mas click que hago enel archivo no me lo toma en cuenta al momento de ejecutar la orden.

string sourceName = "ExampleText.txt";
            string targetName = "Example.7z";

            // 1
            // Initialize process information.
            //
            ProcessStartInfo p = new ProcessStartInfo();
            p.FileName = "7za.exe";

            // 2
            // Use 7-zip
            // specify a=archive and -tgzip=gzip
            // and then target file in quotes followed by source file in quotes
            //
            p.Arguments = "a -t7z \"" + targetName + "\" \"" +
                sourceName + "\" -mx=9";
            p.WindowStyle = ProcessWindowStyle.Hidden;

            // 3.
            // Start process and wait for it to exit
            //
            Process x = Process.Start(p);
            x.WaitForExit();


SOlamente toma archivos en una ruta especifica y no una ruta cualquiera.
quice por iniciativa propia copiar en el portapapeles a ver si de ahi me lo tomaba y no. espero puedan ayudarme (aplicando la misma descripcion a descomprimir) y tomo este por que el winrar debe estar instalado en el huesped y el zip no tiene buena tasa de compresion.

Eleкtro

#1
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 7za.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.

Pero bueno, ya que en lugar de eso te has decidido por simplemente iniciar un executable externo sin más, entonces intenta hacerlo lo mejor posible, yo te sugiero crear un simple (muy simple) wrapper de 7za.exe a modo de función que se encargue de ejecutar el executable 7za.exe y al menos devolver el código de salida del proceso.

Aquí abajo te dejo un ejemplo que escribí. Nótese que el código lleva hard-coded la ubicación del executable 7za.exe y los parámetros command-line ("a -t7z -mx=9" etc) ...y más cosas. Se puede extender y perfeccionar el código para hacerlo todo más accesible a través de una clase que exponga propiedades para configurar el nivel de compresión, tipo de compresión, tamaño de diccionario, etcétera, pero eso requeriría definir toda clase de miembros entre enumeraciones, métodos/funciones y tipos, todo ello con su respectiva documentación XML lo que en general agrandaría mucho el código (miles de lineas, así son a veces los códigos que suelo publicar por el foro xD), pero no es plan ni de ponerme a reinventar la rueda (me refiero, existiendo la implementación de SevenZipSharp) ni tampoco es plan de extender más de lo necesario un sencillo ejemplo de código que simplemente funcione para resolverte una duda.

También cabe mencionar que al código le faltaría la capacidad de capturar e imprimir el búfer estándar de salida y el de error para así poder controlar el progreso/porcentaje de compresión y posibles errores por parte de (7za.exe), pero bueno, lo dejo así ya que el hecho de implementar el análisis de datos de los streams (el data parsing del std-out y std-err del proceso) sería mucho trabajo de más, y con esto ya considero más que suficiente para que puedas solucionar el problema que tienes...

En fin, aquí lo tienes:
Código (csharp) [Seleccionar]
// int result = CompressFile(@"C:\Filename.ext");
static public int CompressFile(string srcFilePath) {

   if (!File.Exists(srcFilePath)) {
       throw new FileNotFoundException(new FileNotFoundException().Message, srcFilePath);
   }

   string dstFilePath = Path.Combine(Path.GetDirectoryName(srcFilePath), Path.GetFileName(srcFilePath) + ".7z");
   if (File.Exists(dstFilePath)) {
       // Ignore and let 7za.exe replace/update the target file, or handle the file conflict scenario...
       // throw new NotImplementedException("File conflict error-handling not implemented.");
   }

   ProcessStartInfo startinfo = new ProcessStartInfo {
       FileName = "7za.exe",
       WorkingDirectory = @".\",
       Arguments = string.Format("a -t7z -mx=9 -mmt=on -ms=on \"{0}\" \"{1}\"", dstFilePath, srcFilePath),
       CreateNoWindow = true,
       ErrorDialog = true,
       ErrorDialogParentHandle = IntPtr.Zero,
       RedirectStandardError = false,
       RedirectStandardInput = false,
       RedirectStandardOutput = false,
       UseShellExecute = false,
       WindowStyle = ProcessWindowStyle.Hidden
   };

   string full7zPath = Path.Combine(startinfo.WorkingDirectory, startinfo.FileName);
   if (!File.Exists(full7zPath)) {
       throw new FileNotFoundException(new FileNotFoundException().Message, full7zPath);
   }

   using (Process p = new Process()) {
       p.StartInfo = startinfo;
       p.EnableRaisingEvents = false;

       p.Start();
       p.PriorityClass = ProcessPriorityClass.AboveNormal;
       p.WaitForExit(Timeout.Infinite);

       return p.ExitCode;
   }

}


Código (csharp) [Seleccionar]
// int result = await CompressFileAsync(@"C:\Filename.ext");
static public async Task<int> CompressFileAsync(string srcFilePath) {
   Task<int> t = Task.Factory.StartNew<int>(() => Compress(srcFilePath));
   return await t;
}


Modo de empleo sincrónico:
Código (csharp) [Seleccionar]
int result = CompressFile(@"C:\Filename.ext");

Modo de empleo asincrónico:
Código (csharp) [Seleccionar]
int result = await CompressFileAsync(@"C:\Filename.ext");

Si no entiendes algo del código, pregunta sin problemas. Si no entiendes los comentarios que puse en Inglés (como ya dijiste en otro comentario no te llevas bien con el Inglés)... bueno, lo siento pero yo no programo en Castellano, el Inglés es un requisito fundamental de la programación nos guste o no.

Saludos.








okik

#2
Ya @Elektro te a respondido muy bien mientras yo intentaba ver cual era tu error.

Te doy esta respuesta más simplista ya que el código que expones está bien, solo hay varios errores en el argumento.


Código (csharp) [Seleccionar]
p.FileName = "7za.exe";
Solo necesitas la de consola 7za.exe y 7za.dll. Si lo tienes en otro directorio debes especificarlo ej.: p.Filename = "D:\\7za.exe"


Los argumentos están mal. Debe ser:

a destino " "  archivo/s  -t7z -mx=9

Nota: El destino debe contener también el nombre del archivo y no hace falta poner extensión pues ya especificas el tipo de archivo  con "-t7z".

Igualmente si pones como destino "D:\\Example.7z" no hace falta poner "-t7z" porque 7za.exe ya establecería el formato de archivo correspondiente.

Código (csharp) [Seleccionar]
         string sourceName = "ExampleText.txt";
           string targetName = "Example";
           ProcessStartInfo p = new ProcessStartInfo();
           p.FileName = "7za.exe";

           p.Arguments = "a " +  targetName + " " + sourceName + " -t7z -mx=9";
           p.WindowStyle = ProcessWindowStyle.Hidden;

           Process x = Process.Start(p);
           x.WaitForExit();


Si lo hicieras así crearía una carpeta llamada prueba en el mismo directorio del programa:

         
Código (csharp) [Seleccionar]
string sourceName = "ExampleText.txt";
           string targetName = "Example";
           string pathDestination = "Prueba\\";
           ProcessStartInfo p = new ProcessStartInfo();
           p.FileName = "7za.exe";

           p.Arguments = "a " + pathDestination + targetName + " " + sourceName + " -t7z -mx=9";
           p.WindowStyle = ProcessWindowStyle.Hidden;

           Process x = Process.Start(p);
           x.WaitForExit();



Comandos 7za.exe v.17.1.0.0

Usage: 7za <command> [<switches>...] <archive_name> [<file_names>...]

<Commands>
 a : Add files to archive
 b : Benchmark
 d : Delete files from archive
 e : Extract files from archive (without using directory names)
 h : Calculate hash values for files
 i : Show information about supported formats
 l : List contents of archive
 rn : Rename files in archive
 t : Test integrity of archive
 u : Update files to archive
 x : eXtract files with full paths

<Switches>
 -- : Stop switches parsing
 @listfile : set path to listfile that contains file names
 -ai[r[-|0]]{@listfile|!wildcard} : Include archives
 -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives
 -ao{a|s|t|u} : set Overwrite mode
 -an : disable archive_name field
 -bb[0-3] : set output log level
 -bd : disable progress indicator
 -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line
 -bt : show execution time statistics
 -i[r[-|0]]{@listfile|!wildcard} : Include filenames
 -m{Parameters} : set compression Method
   -mmt[N] : set number of CPU threads
   -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra)
 -o{Directory} : set Output directory
 -p{Password} : set Password
 -r[-|0] : Recurse subdirectories
 -sa{a|e|s} : set Archive name mode
 -scc{UTF-8|WIN|DOS} : set charset for for console input/output
 -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files
 -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands
 -sdel : delete files after compression
 -seml[.] : send archive by email
 -sfx[{name}] : Create SFX archive
 -si[{name}] : read data from stdin
 -slp : set Large Pages mode
 -slt : show technical information for l (List) command
 -snh : store hard links as links
 -snl : store symbolic links as links
 -sni : store NT security information
 -sns[-] : store NTFS alternate streams
 -so : write data to stdout
 -spd : disable wildcard matching for file names
 -spe : eliminate duplication of root folder for extract command
 -spf : use fully qualified file paths
 -ssc[-] : set sensitive case mode
 -ssw : compress shared files
 -stl : set archive timestamp from the most recently modified file
 -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)
 -stx{Type} : exclude archive type
 -t{Type} : Set type of archive
 -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options
 -v{Size}[b|k|m|g] : Create volumes
 -w[{path}] : assign Work directory. Empty path means a temporary directory
 -x[r[-|0]]{@listfile|!wildcard} : eXclude filenames
 -y : assume Yes on all queries





rigorvzla


         [code=csharp] string sourceName = "ExampleText.txt";
           string targetName = "Example";
           string pathDestination = "Prueba\\";
           ProcessStartInfo p = new ProcessStartInfo();
           p.FileName = "7za.exe";

           p.Arguments = "a " + pathDestination + targetName + " " + sourceName + " -t7z -mx=9";
           p.WindowStyle = ProcessWindowStyle.Hidden;

           Process x = Process.Start(p);
           x.WaitForExit();


muchas gracias, buscaba la forma de que creara una carpeta y ahi almacenara el archivo comprimido ese punto estubo bueno @elektro muchas gracias por esa gran explicacion, @okika , este planteamiento esta excelente, ahora falta un detalle que es con lo que no doy, yo necesito hacer click en un archivo y sobrearlo, en ese punto cuando corra esos parametros , me tome el click y haga lo q debe hacer string sourceName = "ExampleText.txt"; este parametro no me capta lo que yo tenga el objeto seleccionado en ese momento ya que requiere una direccion predestianda . mi pregunta es como puedo dejar ese valor en blanco y que me tome el objeto que  tenga seleccionado con el click del raton, o que se cree un objeto con el clikck del raton para yo al tener ese valor capturado referenciarlo como archivo a comprimir.[/code]

okik

#4
Cita de: rigorvzla en 21 Noviembre 2017, 17:34 PM
mi pregunta es como puedo dejar ese valor en blanco y que me tome el objeto que  tenga seleccionado con el click del raton, o que se cree un objeto con el clikck del raton para yo al tener ese valor capturado referenciarlo como archivo a comprimir.

Es posible añadir tu programa al menú emegergente de propiedades de archivos de Windows. Que aparezca tu programa y crear compresión del archivo o archivos seleccionados pero se vuelve un tema más complejo.


Sin embargo puedes implementar tu propio explorador o más fácil aún utilizar un cuadro de diálogo.

Puedes usar el cuadro OpenFileDialog.

Luego aplicar el modo "multiselect" para comprimir multiples archivos

Introducelos en una lista, por ejemplo un archivo temporal listfile.lst, lst.tmp, listfile.txt, lo que prefieras.

Finalmente aplicas el comando:

a NameFileZip @listfile.lst -t7z



También puedes crear otro cuadro de diálogo para elegir el destino y nombre del archivo y tipo.

Ejemplo:

   
Código (csharp) [Seleccionar]
    using (OpenFileDialog ofd = new OpenFileDialog())
               {
                   ofd.Title = "Archivos a comprimir";
                   ofd.Filter = "All files|*.*";
                   ofd.Multiselect = true;
                   if ((ofd.ShowDialog() == DialogResult.OK))
                   {
                       System.IO.StreamWriter sw = new System.IO.StreamWriter("listfile.lst");
                       //Crea una lista de archivos
                       foreach (string n in ofd.FileNames)
                       {
                           sw.WriteLine(n);
                       }
                       sw.Close();
                   }
               }
       


               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";
               p.WindowStyle = ProcessWindowStyle.Hidden;
               Process x = Process.Start(p);
               x.WaitForExit();
               System.IO.File.Delete("listfile.lst");




he añadido  al código para borrar la lista una vez usada por 7za.exe
Código (csharp) [Seleccionar]
System.IO.File.Delete("listfile.lst");

También he cambiado el título al cuadro de diálogo porque le puse "Abrir imagen" que no es el caso   :P

También había una errata entre comillas porque puse
Código (csharp) [Seleccionar]
   p.FileName = "7z.exe";
y no
Código (csharp) [Seleccionar]
   p.FileName = "7za.exe";

He usado una versión más vieja la 16, por eso puse 7z.exe y no 7za.exe

Eleкtro

#5
Cita de: rigorvzla en 21 Noviembre 2017, 17:34 PM
yo necesito hacer click en un archivo y sobrearlo, en ese punto cuando corra esos parametros , me tome el click y haga lo q debe hacer string sourceName = "ExampleText.txt"; este parametro no me capta lo que yo tenga el objeto seleccionado en ese momento ya que requiere una direccion predestianda . mi pregunta es como puedo dejar ese valor en blanco y que me tome el objeto que  tenga seleccionado con el click del raton, o que se cree un objeto con el clikck del raton para yo al tener ese valor capturado referenciarlo como archivo a comprimir.

Disculpa pero no se te entiende nada, no se que es "sobrear" un archivo, ni tampoco "que me tome el click y haga lo que debe hacer", ¿que es lo que debe hacer?. Intenta explicar todo con mejor detalle, sin prisa pero sin pausa lo que quieres hacer, por que así no vamos a ninguna parte...

Lo que has dicho se puede interpretar de mil formas, como por ejemplo no sé si te puedes estar refiriendo a crear una shell-extensión y registrarla en el S.O. para añadir una nueva opción/comando al menú contextual de archivos, para que aparezca un comando personalizado cuando haces click derecho sobre un archivo, y ahí ya estariamos hablando de programación avanzada (que además requiere conocimiento de C/C++) que no sería una tarea apta para alguien que acaba de empezar en C# / .NET, pero bueno, no voy a suponer nada ni a explicar más de la cuenta por que no se entiende lo que quieres hacer y a lo mejor no es eso.

De todas formas es que estás formulando preguntas de programación avanzada que no van acorde al nivel actual de aprendizaje que llevas, son cosas que en mi humilde opinión no creo que las vayas a poder entender ni llevar a cabo sin la suficiente experiencia y la práctica, pides que te digan como hacer las cosas como panes, pero no muestras nada acerca de tu supuesta investigación, ¿donde has buscado?, ¿qué has intentado hacer por ti mismo?, ¿donde está el código que demuestra lo que te has esforzado en intentar?. Recuerda que aquí no le hacemos el trabajo a nadie.

...Aun así, voy a ser bueno, y te ofreceré soluciones:

· 1-A
Si te estás refiriendo a lo de añadir una opción al menú contextual de archivos, una forma más o menos sencilla de hacerlo sería a través de la librería de terceros SharpShell:
...la librería basicamente contiene un montón de wrappers de varios miembros de C++, es una librería con ciertas limitaciones por eso, pero es una manera cómoda y viable para desarrollar una shell-extension con código administrado y así evitar todo el embrollo que tendriams que implementar con código nativo....

· 1-B
Una forma cutre pero todavía más sencilla (mucho, mucho más sencilla) de hacerlo sería mediante el registro de Windows, simplemente agregando un par de claves. Es una forma muy sencilla como digo, y estoy seguro que puedes encontrar miles de ejemplos en Google si buscas por "cómo agregar programa al menú contextual de archivos". Evidentemente esto ya no sería una extensión de la shell, es una opción muy limitada en comparación, pero igual te podría servir para cumplir el objetivo que tengas... dependiendo de cual sea este (si es algo básico como hacer click derecho sobre un archivo para "cargar" ese archivo en tu programa, entonces esta metodología te sirve de sobra sin necesidad de crear una shell-extension).

· 2-A
Si por lo contrario te estás refiriendo a detectar cuando un elemento (archivo o directorio) es seleccionado en la instancia/ventana activa del explorador de Windows, la manera correcta de llevar a cabo esta tarea sería aplicando un hook al Explorer (al objeto ExplorerWindow), para escuchar los eventos de selección de elementos. Esto es algo que requeriría mucha investigación, análisis en profundidad del proceso Explorer.exe, es decir, de las llamadas internas a APIs y los parámetros que se utilicen, y bastante ensayo y error. Pides cosas muy avanzadas (también son avanzadas para mi, no soy un experto en hooks ni API hooks), evidentemente no tengo un ejemplo que mostrar, y dudo que haya alguno por Internet... basicamente por que es un tema complicado donde cualquier trabajo suele hacerse para uno mismo, y también es una necesidad o duda muy específica. De todas formas puedo recomendarte una librería comercial para .NET muy util con la que he trabajado en el pasado para este tipo de inyecciones: Deviare API Hook

· 2-B
Una forma cutre (no tan eficiente) de hacerlo sería mediante un objeto Timer para determinar cada poco intervalo de tiempo (100 ms por ejemplo) si existe algún archivo/carpeta seleccionado en la ventana que esté activa. Sería una solución basada en el uso de los wrappers de interfaces nativas que expone el objeto Shell.

Esta metodología tendría un gran inconveniente y es que realmente no estariamos detectando o suscritos a ningún "evento de selección de archivos" en el Explorer, sino que estariamos asumiendo ciertas cosas con un margen de error aceptable.

He escrito el siguiente ejemplo para aplicar esta metodología. Aquí lo tienes:

Código (csharp) [Seleccionar]
using System;
using System.Runtime.InteropServices;
using System.Security;

[SuppressUnmanagedCodeSecurity]
public sealed class SafeNativeMethods {

   // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633505%28v=vs.85%29.aspx
   [DllImport("User32.dll", SetLastError = false)]
   public static extern IntPtr GetForegroundWindow();

}


+

Código (csharp) [Seleccionar]
using System;
using System.Collections.Generic;

using Shell32;
using SHDocVw;


Código (csharp) [Seleccionar]
public static IEnumerable<FolderItem> GetSelectedItems() {

   IntPtr hwnd = SafeNativeMethods.GetForegroundWindow();

   // http://msdn.microsoft.com/en-us/library/windows/desktop/ff521731%28v=vs.85%29.aspx
   Shell shell = new Shell();
   ShellWindows windows = (ShellWindows)((IShellDispatch6)shell).Windows();

   foreach (InternetExplorer window in windows) {
       if (window.HWND == Convert.ToInt32(hwnd)) {
           foreach (FolderItem item in ((IShellFolderViewDual3)window.Document).SelectedItems()) {
               yield return item;
           }
           break;
       }
   }

}


+

Código (csharp) [Seleccionar]
using System;
using System.Collections.Generic;
using System.Linq;

using Shell32;


Código (csharp) [Seleccionar]
private void Timer1_Tick(object sender, EventArgs e) {

IEnumerable<FolderItem> items = GetSelectedItems();

if ( items.Any() ) {
IEnumerable<string> filepath = (from item in itemsitem.Path);

} else {
// No items selected, or none Explorer window has focus. (hard to debug)

}

}


El código de arriba requiere una referencia a las sigueintes librerías COM:
  • Microsoft Internet Controls
  • Microsoft shell Controls And Automation

Saludos!








okik

Cita de: Eleкtro en 21 Noviembre 2017, 20:33 PM
Disculpa pero no se te entiende nada, no se que es "sobrear" un archivo, ni tampoco "que me tome el click y haga lo que debe hacer", ¿que es lo que debe hacer?. Intenta explicar todo con mejor detalle, sin prisa pero sin pausa lo que quieres hacer, por que así no vamos a ninguna parte...
:xD
Hombre, yo creo con "sobrear" supongo que quiso escribir "sombrear" o sea seleccionar un archivo y con que me tome el click y haga lo que debe hacer" es que lo comprima.

Por eso yo le he puesto lo del cuadro de diálogo, porque puedes seleccionar (sobrear), hacer clic y que comprima los archivos.


Eleкtro

#7
Cita de: okik en 21 Noviembre 2017, 20:39 PMHombre, yo creo con "sobrear" supongo que quiso escribir "sombrear"

Lo se, pero el término "sombrear" sigue siendo muy poco acertado para intentar describir algo en el área de la informática / programación. Yo no tengo tan claro que se refiera a "seleccionar", basicamente por que ha dicho somrbear... no ha dicho seleccionar, clickar, pinchar, o pulsar. Creo que se me entiende xD. No se si parezco alguien muy exigente al decir esto, pero creo que es un requisito esencial tratar de utilizar las palabras adecuadas al formular una duda sobre programación... más que nada para evitar que se pueda mal interpretar, por que si se mal interpreta acabamos aquí dando mil soluciones distintas que nada tienen que ver con la duda real... y gastando "saliba" para nada, en vano.

Cita de: okik en 21 Noviembre 2017, 20:39 PMPor eso yo le he puesto lo del cuadro de diálogo, porque puedes seleccionar (sobrear), hacer clic y que comprima los archivos.

Se que no viene al caso lo que voy a decir, pero me apetece decirlo para rellenar un poco más este comentario xD... :

En cierto modo me ha gustado ver esta "compenetración", me refiero, cada uno le hemos explicado sobre diferentes cosas, jeje. Con el compañero NEBIRE me pasa igual. Bueno, es obvio que si ves que alguien ya ha explicado algo, pues el otro va a intentar aportar algo diferente, o algo adicional a la solución que ya se ha dado, o incluso alguna rectificación necesaria al código del otro. Está bien eso, por que cada uno aporta diferentes puntos de vista con sus respectivas soluciones, recomendaciones, pseudo-código, etc.

Bueno, creo que estoy haciendo demasiado offtopic desviandome del tema...

Un saludo.








rigorvzla

sin animos de ofender @elektro , me parecio tedioso leer tooodo ese poco texto que escribiste , pero las primeras lineas me dijeron de ti aspectos que no vienen al caso, te doy gracias por las respuestas y si, al parecer hago un programa de  programacion "avanzada", (cosa que no me va mal hasta el momento). encontre lo que queria  por mis medios  y obvio preguntando a personas que me dan respuestas claras , simples concisas y entendibles para cualquier nivel.

gracias a los que entendieron mi vocablo poco especifico etico profesional y burdo,  lastima no puderon saber responder se agradece tambien.

seguire preguntando si tengo dudas y agradecere de antemano a los que respondan mis inquietudes, supongo que es algo donde todos aprendemos creo que le llaman  "feedback" o " dialogo de ideas". gracias nuevamente su colaboracion para mis inquietudes.

Eleкtro

#9
Pues si que me ofende, me ofende que una persona formule una pregunta de programación, pero esa misma persona no esté dispuesta a leer una respuesta extensa y detallada para aprender o al menos para hacerse una idea de como hacer "X" cosa, y para colmo despreciar o infravalorar las expliacciones que te di, las cuales, como ya has dicho, no has leido.

Lo peor de todo es que respondiste para decir eso pero sigues sin aclararnos lo que querías decir con "sombrear", ni tampoco aclaraste cual era el problema, ni compartiste tu solución para los demás usuarios que anden en una situación parecida a la tuya. Eso también es casi ofensivo. Bueno, despues de leer todo lo que has dicho, inentaré tomármelo lo mejor que pueda, eso sí, mi "feedback" ya no lo tendrás a partir de este momento, aunque eso no te importe mucho, por que el que ha acabado perdiendo el tiempo escribiendo y compartiendo soluciones que no vas a leer, he sido yo.

La culpa es mia por hacerme expectativas con personas que no están dispuestas a leer, sino que más bien solo buscan "que le den códigos". Al menos tuviste el detalle de agradecer, lo tendré en cuenta, gracias a ti también... en ese aspecto.

EDITO: de todas formas me gustaría intentar que comprendas (suponiendo que este comentario no te parezca demasiado tedioso y lo leas) que siempre intento compactar la información lo mejor que puedo, pero hay un problema: es demasiada información, y al final se requiere de varias lineas para simplificar una explicación con tanta información que ofrecer, y creeme si te digo que lo hago (o al menos lo intento) y me salto intencionadamente muchos detalles importantes por el camino para no extenderlo mucho más.

Un saludo y suerte con tus cosas.