FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
|
#1
|
||||
|
||||
Cómo determinar el tamaño original de un archivo ejecutable
Hola a todos,
A ver si podéis echarme una mano con el siguiente problema. En uno de mis proyectos necesito adjuntar ciertos datos en un archivo ejecutable, esto es, en realidad adjunto un archivo a otro archivo, este último un ejecutable generado también con Delphi. Todo funciona bien, excepto si además cambio el icono de dicho archivo ejecutable. Para conseguir el tamaño original de un archivo ejecutable, me baso en el siguiente código de Angus Johnson:
La idea del anterior código es determinar el tamaño original de un archivo ejecutable, sin contar con el archivo que hemos adjuntado al mismo, puesto que este se "añade" al ejecutable, pero, no forma parte de sus "cabeceras" (no sé si me explico, porque, aquí me pierdo un poco, tengo que reconocerlo). Pues bien, en teoría esto ha de funcionar, sin embargo, el anterior código siempre retorna "0" en Windows NT (Windows 10, por ejemplo). Como se trata un código para Delphi 3, yo lo he "sabido" modificar un poco de este modo:
En efecto, el código modificado que muestro arriba no retorna "0", sin embargo, no tiene en cuenta el cambio del icono del ejecutable. Es decir, supongamos que el archivo ejecutable original tiene un tamaño de 100 bits. Ahora pueden darse dos casos: que el tamaño del icono a usar sea mayor o menor que el del ejecutable original: sea como sea, la función anterior retornará 100, es decir, no tendrá en cuenta que se ha cambiado el icono del ejecutable. Como para saber la cantidad de datos a leer del archivo ejecutable se determina por la fórmula: Tamaño Actual - Tamaño Original, dicha fórmula falla, en el sentido de que, por ejemplo, si se usado un icono de menor tamaño que el original, es posible que "Tamaño Actual" sea menor que "Tamaño Original", de modo que estaríamos leyendo una cantidad de datos negativa, o sea, que no podremos leer correctamente dichos datos. ¿Qué es lo que necesito? Tengo dudas sobre si los cambios que he introducido a la función de Angus Johnson son del todo correctos o no, de modo que esta función, o sea, la que determina el tamaño original del archivo ejecutable, la que esté causando los problemas: puesto que no tenga en cuenta el posioble cambio del icono. Hay que decir, que, si no se cambia el icono, todo funciona como se espera, pero, el cambio del icono es una opción para el usuario y no se puede simplemente eliminar. He probado varias cosas, por ejemplo, en la función original tenemos esta línea:
Como puede verse, en la modificación que yo he hecho dicha línea se ha transformado en esta otra:
Ahora bien, si trato de hacer lo siguiente, para tratar de ajustar más:
... dicha cambio implica que la función retorne de nuevo siempre "0". ¿Otras posibles causas del problema? Creo que el problema está determinado porque la función anterior no es capaz de tener en cuenta el cambio de icono en el archivo ejecutable. Pareciera que sigue "leyendo" el tamaño original del icono y así el resultado que ofrece está equivocado, tanto en el caso de que el icono a cambiar sea mayor o menor que el original. Pero, por otro lado, me queda también la duda de que pueda ser, precisamente, la función encargada de cambiar el icono, la que esté causando el problema, porque, de alguna forma no "actualize" el tamaño al del nuevo "icono/recurso". Sin embargo, la función encargada de cambiar el icono, originalmente escrita por Jordan Russell para Inno Setup, funciona por lo demás correctamente.
¿Alguna conclusión? Quiero pensar que, puesto que estoy tratando de traducir un código escrito en Delphi 3, que, además no comprendo muy bien, la función problemática no es la encargada de cambiar el icono, sino "GetExeSize", que, no consigue determinar bien el tamaño original del archivo ejecutable, es decir, no tiene en cuenta el posible cambio del icono. Pero la verdad es que no puedo concluir que ahí esté el problema... y por eso necesito de vuestra ayuda, puesto que tal vez alguno de vosotros esté más puesto que yo en estos asuntos y pueda ofrecer algo de luz al respecto. Por favor, si necesitáis cualquier otra información que se me haya olvidado, decídmelo y trataré de proporcionarla. ¡Muchas gracias a tod@s! Última edición por dec fecha: 28-02-2017 a las 10:45:51. |
#2
|
||||
|
||||
Pregunta tonta: ¿por qué no dejas el icono fuera?
|
#3
|
||||
|
||||
Hola,
De pregunta tonta nada... Gracias por responder Casimiro. Pero, ¿qué significa dejar el icono "fuera"? |
#4
|
||||
|
||||
Quiero decir, según he entendido, que si el usuario puede cambiar el icono del programa ¿por qué no lo cargas el ficherito desde disco?
|
#5
|
||||
|
||||
Hola,
He pensado algo parecido, desde luego, pero, la idea es que el icono "luzca" en el propio archivo ejecutable, es decir, no es tanto que dicho icono aparezca en el formulario u otro lugar, pero, en el mismo icono del ejecutable. En todo caso estaríamos obligando a distribuir el icono en cuestión junto con el ejecutable... que tendría un icono "original"... no sé... Casimiro... de veras que he pensado que simplemente decir, "no se puede cambiar el icono", pero, entiendo que no debo tomar dicho camino, pues, por mejorar algo, vamos a empeorar otra cosa. Yo creo que la función "GetExeSize" puede mejorarse, es decir, no está del todo bien adaptada por mí desde el código original de Angus Johnson, de modo que por ahí pueden ir los tiros... dicha función debería devolver el tamaño original de un ejecutable, teniendo en cuenta si se cambia el icono del mismo... que es lo que parece que no hace... aunque, como he dicho arriba, tal vez la función hace su trabajo bien (lo dudo, porque, yo mismo modifiqué dicha función para ser válida en Windows NT) y sea la función que actualiza el icono quien deja algo "sin actualizar"... |
#6
|
||||
|
||||
¿Pero lo de cambiar el icono y el tamaño del ejecutable es por alguna protección?
|
#7
|
||||
|
||||
Cita:
El código funciona bien en Todos los WIndows, el problema es el compilador. En delphi 7 no hay problema pero los que priorizan unicode, la fastidian, como siempre. Al usar PCHAR el compilados asume (malamente) un PWCHAR con lo que al incrementar el puntero se hace en múltiplos de 2 bytes. Esta es la modificación que debes hacer:
El código expuesto calcula el tamaño del ejecutable actual, pero puede modificarse para calcular el tamaño teórico de cualquier fichero ejecutable conociendo su ruta. El formato PE de los ejecutables de Windows, agrandes rasgos consta de: - Cabecera DOS 'MZ' : IMAGE_DOS_HEADE: 64 bytes - DOS Stub o subprograma encargado de avisar del error si no se ejecuta en Windows: 448 bytes - Firma PE: 'PE00': 4 Bytes. - Cabecera PE: IMAGE_FILE_HEADER: 20 Bytes. - Cabecera opcional: IMAGE_OPTIONAL_HEADER: 224 Bytes. (tamaño variable) - Cabeceras de sección: IMAGE_SECTION_HEADER: 40 Bytes cada una, número variable - Cuerpos de sección: código, datos importados y exportados, relocations, recursos... Tamaño indeterminado. Además, todo esto lleva una alineación con lo que la afirmación TamFile + TamIcono = NewTamfile es falsa. la siguiente clase es un fragmento de otra más completa para el manejo del PE que escribí hace ya algunos años con la funcionalidad de eliminar secciones de un ejecutable. El tema está aquí. Dado que es un foro restringido, voy a publicar un fragmento que permite calcular el tamaño teórico de un archivo ejecutable que no se está ejecutando. Si no coincide con el real, "algo se ha añadido sin permiso oficial al ejecutable" (aunque un buen "añadidor", ya se encargará de modificar todo el PE para oficializarlo).
El código no funcionará compilado a 64bits. Por otro lado, una forna de encontrar fácilmente el fin de fichero sin usar el PE, es adherirle al final una firma fija compuesta de una cadena conocida. Una búsqueda nos dará el tamaño de archivo, y a partir de esa firma podemos añadir más cosas al archivo inicial. Código:
Stub + Firma + DatosVarios. Saludos. Última edición por escafandra fecha: 01-03-2017 a las 22:31:48. |
#8
|
||||
|
||||
#9
|
||||
|
||||
Hola a todos,
Bueno, escafandra, qué puede uno decir... ¡muchas gracias! Acabo de probar con la función "GetExeSize" modificada por ti, y, en efecto, funciona como se espera sin problema alguno. Mejor aún, puesto que, probando de nuevo con el icono de 512 píxeles también funciona correctamente, es decir, la función calcula ahora el tamaño correcto del archivo ejecutable, teniendo en cuenta el cambio de icono, la firma del ejecutable, etc. Es para estar contento, pues, ciertamente, mi proyecto puede ahora trabajar sin problemas con archivos de más de 500 MB, de hecho de más de 1 GB. No ahora mismo, pero, esto me daría pie además a otros posibles proyectos similares. ¡Mejor imposible! Bueno... Cita:
Cita:
¡Muchas gracias de nuevo a todos! ¡Y muchas gracias a escafandra en particular, que pudo entender y traducir la función de Angus Johnson! P.D. Definitivamente he sido muy tonto dejando pasar tanto tiempo en preguntar aquí en el ClubDelphi: ¡mucho mejor me hubiera ido! Ahora toca agarrarse a aquello de que nunca es tarde, etc. Última edición por dec fecha: 02-03-2017 a las 08:18:13. |
#10
|
||||
|
||||
Hola a todos,
Pues nada, que, pasaba por aquí, y, me he dicho, voy a darle de nuevo las gracias a estos muchachos, que, ciertamente, lo merecen. ¡Muchas gracias de nuevo a todos por vuestra ayuda! |
#11
|
||||
|
||||
A escafandra, los demás sólo somos una cara bonita
LineComment Saludos |
#12
|
||||
|
||||
Cita:
Esta modificación del código original lo capacita para funcionar compilado a 64bits:
PD/ Una cosa más, la información de depuración puede alterar el tamaño del ejecutable con lo que es conveniente hacer las añadiduras al archivo una vez depurado el ejecutable y eliminada esta información. Saludos. Última edición por escafandra fecha: 03-03-2017 a las 00:55:18. |
#13
|
||||
|
||||
Hola a todos,
Te estás pasando ya escafandra, muchísimas gracias. No he probado con ejecutables de 64 bits pero lo haré en cuantito pueda. Respecto de la información de depuración, es cierto, que, tal vez desde otro punto de vista, ya me había topado con dicho problema, de modo que "fuerzo" a que el ejecutable "final" se compile en "modo release". Esto lo hago de una forma tal vez "bruta" pero efectiva, añadiendo estas líneas al comenzar el "begin" del archivo de proyecto del ejecutable en cuestión:
De este modo, si estamos en "modo debug", el "Remember that...", en este caso, causará un error de compilación que nos hará saber de no podemos seguir por dicho camino. Muchas gracias de nuevo escafandra, voy a intentar hacer las pruebas con 64 bits lo antes posible, y tal vez hasta pueda preparar algo más o menos genérico que compartir por aquí. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
determinar el tamaño de una fichero | lmpadron | C++ Builder | 5 | 14-11-2011 23:04:27 |
Determinar el tamaño óptimo de un datafile | SMTZ | Oracle | 2 | 03-02-2007 13:04:45 |
Form Vuelve al Tamaño original | Enan0 | Varios | 5 | 15-08-2006 18:53:14 |
como achicar el tamaño de mi Ejecutable | Patricio | Varios | 2 | 22-11-2005 13:48:45 |
Como determinar el tamaño de una base de dato ? | Raptor | Varios | 4 | 06-08-2004 02:17:56 |
|