Autor
|
Tema: extraer adjuntos de correos EML (Leído 4,924 veces)
|
adla
Desconectado
Mensajes: 13
|
hola, tengo una carpeta con correos en eml, ¿como puedo hacer un programa para extraerlos todos por lotes en una nueva carpeta?, por favor si teneis algun codigo en vb6 que haga esto o me vale una aplicacion compilada en otro lenguaje que se elija una carpeta y extraiga todos los eml en otra. Gracias
|
|
|
En línea
|
|
|
|
adla
Desconectado
Mensajes: 13
|
doy mas información, porque no consigo hacerlo, creo que la idea la tengo pero no me centro, estoy con una medicación fuerte para la ansiedad y la depresión que no me deja pensar. 1. la idea es abrir el fichero .eml y recorrerlo hasta encontrar "filename=" que contiene el nombre del adjunto, algo asi: Private Sub VerContenido(Fichero As String) Dim Canal As Integer Dim Cadena As String Dim NombreArchivo As String Dim Contenido As String Dim Adjunto As String Dim t As Integer If Len(Fichero) = 0 Then Exit Sub NombreArchivo = "" Contenido = "" Adjunto = "" Canal = FreeFile() Open Fichero For Input As #Canal Do While Not EOF(Canal) 'lee una linea del fichero origen Line Input #Canal, Cadena ' Si la variable NombreArchivo esta vacia el contenido se añade a Contenido ' Aqui se guarda todo el mensaje del correo menos los adjuntos en txt If NombreArchivo = "" Then Contenido = Contenido + Cadena + Chr$(13) + Chr$(10) ' Si se ha encontrado el nombre de un adjunto ' el contenido del adjunto se guarda en la variable Adjunto If NombreArchivo <> "" Then If Cadena <> "" Then Adjunto = Adjunto + Cadena End If End If ' Si encontramos "filename=" quiere decir que hay un adjunto t = InStr(LCase(Cadena), "filename=") If t > 0 Then NombreArchivo = Mid$(Cadena, t + 10) NombreArchivo = Left(NombreArchivo, Len(NombreArchivo) - 1) End If Loop Close #Canal ' Cierra el archivo. End Sub 2. Ahora tenemos dos variables, Contenido con todo el mensaje menos los adjuntos que se guardaria como aguaococacola.txt y la variable Adjunto que contiene el adjunto codificado en Base64, habria que pasar esa codificación a binario y guardarla como aguaococacola.pps, para eso he encontrado estas funciones: ' Codificar y Decodificar en BASE64 Public Function DecodeBase64(ByVal strData As String) As Byte() Dim objXML As Object Dim objNode As Object Set objXML = CreateObject("MSXML2.DOMDocument") Set objNode = objXML.createElement("b64") objNode.dataType = "bin.base64" objNode.Text = strData DecodeBase64 = objNode.nodeTypedValue Set objNode = Nothing Set objXML = Nothing End Function Public Function EnecodeBase64(ByVal strData As String) As Byte() Dim objStream As Object Dim objNode As Object Dim objXML As Object Dim bArray() As Byte Set objStream = CreateObject("ADODB.Stream") With objStream .Type = 2 .Open .Charset = "unicode" .WriteText strData .Flush .Position = 0 .Type = 1 .read (2) bArray = .read .Close End With Set objXML = CreateObject("MSXML2.DOMDocument") Set objNode = objXML.createElement("b64") objNode.dataType = "bin.base64" objNode.nodeTypedValue = bArray EnecodeBase64 = objNode.Text Set objStream = Nothing Set objNode = Nothing Set objXML = Nothing End Function 3. Si hay varios adjuntos se tiene que repetir el proceso. a). Tengo problemas para encontrar el final del adjunto. b). No sé como pasar la variable Adjunto para que funcione la decodificacion Base64 c). No sé como guardar el archivo Adjunto una vez pasado a binario. He intentado varias cosas pero todas me dan error. Alguien me puede ayudar Gracias, un saludo.
|
|
|
En línea
|
|
|
|
AlbertoBSD
Programador y
Moderador Global
Desconectado
Mensajes: 3.705
🏴 Libertad!!!!!
|
Te puedo ayudar , pero no tengo compilador de VB ni de tecnologías Microsoft en este momento, pasame un archivo EML y con gusto le hecho un ojo para extraer todas los adjuntos, por cierto que ya debería de existir un programa que haga eso no?
Edito ya vi la estructura del archivo y no esta tan complicada. Pregunta: Quieres todos los adjuntos incluidos los que aparecen en el body del mensaje como imagenes y demas o solo considerados realmente "attachment" ? Las imágenes del body y demás tienen un "inline" en el código ejemplo Content-Disposition: inline; filename="background.gif" O solo los "attachment" Content-Disposition: attachment; filename="attachment.txt" Saludos!
|
|
« Última modificación: 10 Noviembre 2020, 16:59 pm por AlbertoBSD »
|
En línea
|
|
|
|
adla
Desconectado
Mensajes: 13
|
Te puedo ayudar , pero no tengo compilador de VB ni de tecnologías Microsoft en este momento, pasame un archivo EML y con gusto le hecho un ojo para extraer todas los adjuntos, por cierto que ya debería de existir un programa que haga eso no?
Edito ya vi la estructura del archivo y no esta tan complicada. Pregunta: Quieres todos los adjuntos incluidos los que aparecen en el body del mensaje como imagenes y demas o solo considerados realmente "attachment" ? Las imágenes del body y demás tienen un "inline" en el código ejemplo Content-Disposition: inline; filename="background.gif" O solo los "attachment" Content-Disposition: attachment; filename="attachment.txt" Saludos! he encontrado esto: https://www.enmimaquinafunciona.com/pregunta/51267/como-extraer-los-datos-adjuntos-de-archivos-eml-con-la-linea-de-comandos-de-windowspero no funcionan los enlaces.. aqui puedes descargar un zip que contiene un eml con un solo adjunto.. la idea es que extraiga todos los adjuntos, aunque este solo contiene uno. Solo los adjuntos pero si son imagenes tambien, no los logos que tenga el cuerpo. Muchas gracias Alberto.
|
|
« Última modificación: 10 Noviembre 2020, 17:27 pm por adla »
|
En línea
|
|
|
|
AlbertoBSD
Programador y
Moderador Global
Desconectado
Mensajes: 3.705
🏴 Libertad!!!!!
|
Lo hice pero actualmente solo para un solo archivo eml, ya que me da flojera hacerlo para todo un directorio y que busque los archivos eml etc etc etc... Lo hice en C. se que este es el subforo de VB, pero la verdad VB no me gusta mucho para este tipo de operaciones, de hechos me gusta el VBA para automatizar trabajos en Excel Imagen de prueba que funciona: Y el archivo se crea en el directorio pasado como segundo parametro. Por cierto si el siguiente código fuente si se compila en algunos compiladores de Windows puede dar muchos warning, pero con gcc de MinGW no me tira ningun warning ni error como esta en la imagen. /* gcc -o dump_eml.exe dump_eml_attachments.c */ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<stdint.h> static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; static char *decoding_table = NULL; static int mod_table[] = {0, 2, 1}; unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length); void build_decoding_table(); void base64_cleanup(); int open_and_extract_from_eml(char *filename,char *path_destino); int isEmptyLine(char *line); char *content_disposition = "Content-Disposition: attachment;"; int main(int argc, char **argv ) { if(argc != 3) { printf("Uso: %s <Carpeta_con_EMLs> <Carpeta_destino_adjuntos>\n",argv [0]); } open_and_extract_from_eml(argv[1],argv[2]); return 0; } int open_and_extract_from_eml(char *filename,char *path_destino) { FILE *eml_file, *temp_file; char *dest_file,*temp0,*temp1; char *line,*buffer_base64 = NULL,*buffer_decoded; char *full_writen_file; int len_dest_file_name,offset,len_content_disposition,len_base64_line,len_base64_buffer, len_output,len_path_destino,entrar; len_content_disposition = strlen(content_disposition ); len_path_destino = strlen(path_destino ); eml_file = fopen(filename ,"rb"); offset = 0; while(!feof(eml_file ) && fgets(line ,1024,eml_file ) != NULL ) { if(memcmp(line ,content_disposition ,len_content_disposition ) == 0) { printf("Encontrado: %s",line ); temp0 = strstr(line ,"filename="); if(temp0 ==NULL ) { //tal vez la proxima linea? fgets(line ,1024,eml_file ); } temp0 = strstr(line ,"filename="); if(temp0 !=NULL ) { temp1 = strstr(temp0 +10,"\""); if(temp1 == NULL) { //No hay " finales } len_dest_file_name = temp1 - (line + (temp0 - line) + 10 ); //printf("len_dest_file_name %i\n",len_dest_file_name); dest_file = malloc(len_dest_file_name +1); strncpy(dest_file ,(line + (temp0 - line ) + 10),len_dest_file_name ); dest_file[len_dest_file_name] = '\0'; fgets(line ,1024,eml_file ); //printf("Nueva linea leida \"%s\"",line); if(!isEmptyLine(line)) { //Deberia de ser una linea vacia; } buffer_base64 = NULL; offset = 0; entrar = 1; while(entrar && fgets(line ,1024,eml_file ) != NULL && !isEmptyLine (line ) ) { //leemos hasta la proxima linea vacia o hasta encontrar un '=' al final de la linea len_base64_line = strlen(line ); buffer_base64 = realloc(buffer_base64 ,offset +len_base64_line +1); if(line[len_base64_line-1] == '\n' || line[len_base64_line-1] == '\r'){ line[len_base64_line-1] ='\0'; len_base64_line--; } if(line[len_base64_line-1] == '\n' || line[len_base64_line-1] == '\r'){ line[len_base64_line-1] ='\0'; len_base64_line--; } memcpy(buffer_base64 +offset ,line ,len_base64_line ); offset+=len_base64_line; if(line[len_base64_line-1] == '=') { entrar = 0; } } buffer_base64[offset] = '\0'; //printf("Encoded buffer: %s\n",buffer_base64); len_base64_buffer = strlen(buffer_base64 ); buffer_decoded = base64_decode(buffer_base64,len_base64_buffer,&len_output); buffer_decoded[len_output] = '\0'; /* printf("OK\n"); printf("Decoded buffer: %s\n",buffer_decoded); printf("Path destino: %s\n",path_destino); printf("len_dest_file_name: %i\n",len_dest_file_name); printf("len_path_destino: %i\n",len_path_destino); */ full_writen_file = malloc(len_dest_file_name + len_path_destino +10); sprintf(full_writen_file ,"%s/%s",path_destino ,dest_file ); printf("Destino: %s\n",full_writen_file ); temp_file = fopen(full_writen_file ,"wb"); fwrite(buffer_decoded ,1,len_output ,temp_file ); } else { printf("Se encontro %s, pero no se encontro Filename omitiendo!\n",content_disposition ); } } } } int isEmptyLine(char *line) { if(line[0] == '\0' || line[0] == '\n' || line[0] == '\r') return 1; return 0; } unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length) { if (decoding_table == NULL) build_decoding_table(); if (input_length % 4 != 0) return NULL; *output_length = input_length / 4 * 3; if (data[input_length - 1] == '=') (*output_length)--; if (data[input_length - 2] == '=') (*output_length)--; unsigned char *decoded_data = malloc(*output_length ); if (decoded_data == NULL) return NULL; for (int i = 0, j = 0; i < input_length;) { uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6); if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF; if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF; if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF; } return decoded_data; } void build_decoding_table() { for (int i = 0; i < 64; i++) decoding_table[(unsigned char) encoding_table[i]] = i; } void base64_cleanup() { }
El programa lo puedes utilizar para todo un directorio pero con ayuda de batch creo recordar que existe una instrucción for que te ayuda a procesar todos los archivos de un subdirectorio y pasarlos a un programa. Saludos!
|
|
« Última modificación: 14 Noviembre 2020, 06:29 am por AlbertoBSD »
|
En línea
|
|
|
|
adla
Desconectado
Mensajes: 13
|
hola, muchas gracias por todo, pero no consigo que me extraiga el adjunto.. no aparece la imagen adjunta, esta aqui http://www.franci.es/tmp/eml-no.jpg
|
|
« Última modificación: 11 Noviembre 2020, 09:31 am por adla »
|
En línea
|
|
|
|
Danielㅤ
Desconectado
Mensajes: 1.825
🔵🔵🔵🔵🔵🔵🔵
|
Hola, en el primer parámetro tenes que pasar un directorio y vos estás pasando un solo archivo, tenés que indicar un directorio donde estén todos esos archivos que querés procesar. Además el segundo parámetro le estás indicando una unidad como ubicación pero no una carpeta y es recomendable que crees una carpeta para alojar todos los archivos destinos, por ejemplo el comando podría ser: "D:\agua o cocacola" "D:\Adjuntos de correos EML" Saludos
|
|
« Última modificación: 11 Noviembre 2020, 13:52 pm por [D]aniel »
|
En línea
|
|
|
|
AlbertoBSD
Programador y
Moderador Global
Desconectado
Mensajes: 3.705
🏴 Libertad!!!!!
|
hola, muchas gracias por todo, pero no consigo que me extraiga el adjunto..
Que tal ya veo algo no esta bien pero no puedo saber que es si no veo el eml que le pasas, si gustas puedes mandarme el EML a mi correo, mi informacion esta por ahi publica
|
|
|
En línea
|
|
|
|
adla
Desconectado
Mensajes: 13
|
Hola, en el primer parámetro tenes que pasar un directorio y vos estás pasando un solo archivo, tenés que indicar un directorio donde estén todos esos archivos que querés procesar. Además el segundo parámetro le estás indicando una unidad como ubicación pero no una carpeta y es recomendable que crees una carpeta para alojar todos los archivos destinos, por ejemplo el comando podría ser: "D:\agua o cocacola" "D:\Adjuntos de correos EML" Saludos no le paso la ruta porque el ejecutable y el archivo estan en la misma carpeta de hecho lo encuentra. He probado poniendo la ruta entera, con la carpeta creada, con la misma carpeta de entrada y con todo lo que se me ha pasado por la cabeza pero he subido solo una imagen. Gracias, Saludos
|
|
|
En línea
|
|
|
|
AlbertoBSD
Programador y
Moderador Global
Desconectado
Mensajes: 3.705
🏴 Libertad!!!!!
|
No se si todos tus eml tengan algún detalle, uno de ellos como te comente por correo estaba "dañado", se supone que deberia de estar X cantidad de información en una línea y en tu archivo tenia un salto de linea en medio eso colgó el programa. Ya funciona para los ejemplos que me pasaste mira las imágenes El codigo esta actualizado en el post donde lo publique, en este mismo Hilo. Saludos
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Extraer voz de un archivo o extraer la musica solamente !!!!!
Multimedia
|
magnox
|
2
|
3,927
|
28 Septiembre 2004, 17:16 pm
por theloop
|
|
|
Envíar Mail con adjuntos vía DOS!
PHP
|
ka0s
|
2
|
1,969
|
14 Junio 2009, 22:56 pm
por ka0s
|
|
|
Adjuntos en Hotmail
Mensajería
|
layuka
|
2
|
2,907
|
21 Julio 2011, 21:55 pm
por layuka
|
|
|
ePedido de programa para Extraer archivos de correos WinMail
Software
|
adrimar66
|
0
|
2,808
|
21 Diciembre 2013, 07:15 am
por adrimar66
|
|
|
Extraer adjuntos de 9000 .eml
Scripting
|
Thortium
|
1
|
5,330
|
5 Noviembre 2020, 20:24 pm
por adla
|
|