cómo obtener el nombre de archivo largo a partir de uno corto

5
Cómo obtener el nombre de archivo largo a partir de uno corto Este artículo ha sido posible gracias a la colaboración de Pere Llaveria. Con la aparición de Windows 95 surgió el formato largo en los nombres de archivos. Hay aplicaciones, sin embargo, que por una u otra razón necesitan trabajar con nombres de archivo en formato corto, es decir, con un nombre de archivo limitado a 8 caracteres más 3 de extensión. Por suerte se añadió en el API de Windows la función GetShortPathName, la cual nos permite obtener un nombre de archivo en formato corto a partir de su formato largo. Sin embargo, en Windows 95 no existe ninguna función que nos permita realizar el proceso contrario. Recientemente se ha incluido la función GetLongPathName en el API, pero se requiere Windows 98. Podemos olvidarnos de utilizar la función GetFullPathName. A pesar de su nombre, no se obtiene un nombre de archivo en formato largo a partir de uno corto. Su cometido es el de generar un nombre completo de archivo a partir de la unidad y directorio actuales. Si le pasamos como primer parámetro la ruta completa de un archivo en formato corto, nos devolverá lo mismo en su tercer parámetro como se muestra en el ejemplo 1. Ejemplo 1 char lpszShortPath[_MAX_PATH]; char lpszLongPath[_MAX_PATH]; char* filepart; lstrcpy(lpszShortPath, "C:\\ARCHIV~1\\ACCESO~1\\MSPAINT.EXE"); GetFullPathName(lpszShortPath, _MAX_PATH, lpszLongPath, &filepart); // lpszLongPath contiene "C:\\ARCHIV~1\\ACCESO~1\\MSPAINT.EXE"

Upload: alejo-consultor

Post on 21-Oct-2015

13 views

Category:

Documents


6 download

DESCRIPTION

nombre archivo

TRANSCRIPT

Page 1: Cómo obtener el nombre de archivo largo a partir de uno corto

Cómo obtener el nombre de archivo largo a partir de uno corto

Este artículo ha sido posible gracias a la colaboración de Pere Llaveria.

Con la aparición de Windows 95 surgió el formato largo en los nombres de archivos. Hay

aplicaciones, sin embargo, que por una u otra razón necesitan trabajar con nombres de archivo

en formato corto, es decir, con un nombre de archivo limitado a 8 caracteres más 3 de

extensión. Por suerte se añadió en el API de Windows la función GetShortPathName, la cual

nos permite obtener un nombre de archivo en formato corto a partir de su formato largo.

Sin embargo, en Windows 95 no existe ninguna función que nos permita realizar el proceso

contrario. Recientemente se ha incluido la función GetLongPathName en el API, pero se

requiere Windows 98.

Podemos olvidarnos de utilizar la función GetFullPathName. A pesar de su nombre, no se

obtiene un nombre de archivo en formato largo a partir de uno corto. Su cometido es el de

generar un nombre completo de archivo a partir de la unidad y directorio actuales. Si le

pasamos como primer parámetro la ruta completa de un archivo en formato corto, nos

devolverá lo mismo en su tercer parámetro como se muestra en el ejemplo 1.

Ejemplo 1

char lpszShortPath[_MAX_PATH];

char lpszLongPath[_MAX_PATH];

char* filepart;

lstrcpy(lpszShortPath, "C:\\ARCHIV~1\\ACCESO~1\\MSPAINT.EXE");

GetFullPathName(lpszShortPath, _MAX_PATH, lpszLongPath, &filepart);

// lpszLongPath contiene "C:\\ARCHIV~1\\ACCESO~1\\MSPAINT.EXE"

Page 2: Cómo obtener el nombre de archivo largo a partir de uno corto

Por otro lado, si sólo le pasamos un nombre de archivo sin especificar la ruta completa,

GetFullPathName generará una ruta a partir de la unidad y directorio en el que nos

encontremos actualmente como se muestra en el ejemplo 2.

Ejemplo 2

lstrcpy(lpszShortPath, "MSPAINT.EXE");

// cambiamos de directorio

SetCurrentDirectory("C:\\WINDOWS\\ESCRIT~1");

GetFullPathName(lpszShortPath, _MAX_PATH, lpszLongPath, &filepart);

// lpszLongPath contiene "C:\\WINDOWS\\ESCRIT~1\\MSPAINT.EXE"

// cambiamos de nuevo de directorio

SetCurrentDirectory("C:\\WINDOWS");

GetFullPathName(lpszShortPath, _MAX_PATH, lpszLongPath, &filepart);

// ahora lpszLongPath contiene "C:\\WINDOWS\\MSPAINT.EXE"

Hay sin embargo una manera de obtener el nombre de un archivo en formato largo y es

utilizando la función del shell SHGetFileInfo. Para ello hay que especificar

SHGFI_DISPLAYNAME en su quinto parámetro. Pero hay un pequeño problema, sólo convierte

la última parte de la ruta completa, es decir, en el caso de tener por ejemplo la ruta

C:\WINDOWS\ESCRIT~1\MIPRIM~1.EXE únicamente podríamos obtener

MiPrimerPrograma.exe correspondiente a MIPRIM~1.EXE como se muestra en el ejemplo 3.

Ejemplo 3

SHFILEINFO sfi;

Page 3: Cómo obtener el nombre de archivo largo a partir de uno corto

lstrcpy(lpszShortPath, "C:\WINDOWS\ESCRIT~1\MIPRIM~1.EXE");

SHGetFileInfo(lpszShortPath, 0, &sfi, sizeof(sfi), SHGFI_DISPLAYNAME);

strcat(lpszLongPath, sfi.szDisplayName);

// lpszLongPath contiene "MiPrimerPrograma.exe"

Debido a esto es necesario llamar a la función SHGetFileInfo para cada subdirectorio

especificado en la ruta del nombre completo empezando desde el primer nivel de

subdirectorio. Seguidamente se muestra la función definitiva:

Función definitiva

DWORD GetLongPathName2(LPCSTR lpszShortPath, LPSTR lpszLongPath, DWORD cchBuffer)

{

DWORD ret;

char shortPath[_MAX_PATH];

char longPath[_MAX_PATH];

char tempPath[_MAX_PATH];

char* backslash = "\\"; // carácter donde debemos detenernos cada vez

char* token;

SHFILEINFO sfi;

ret = 0;

// comprobamos que se trata de un nombre de archivo o ruta existente

if (GetFileAttributes(lpszShortPath) != -1)

{

Page 4: Cómo obtener el nombre de archivo largo a partir de uno corto

lstrcpy(shortPath, lpszShortPath);

token = strtok(shortPath, backslash);

ZeroMemory(tempPath, sizeof(tempPath));

strcat(tempPath, token); // ej. "C:"

strcat(tempPath, backslash); // ej. "C:\"

// empezamos a generar el nombre en formato largo

lstrcpy(longPath, token);

// leemos el primer directorio o nombre de archivo

token = strtok(NULL, backslash);

while (token != NULL)

{

// añadimos el siguiente subdirectorio o nombre de archivo

strcat(tempPath, token);

// añadimos la barra "\" al final,

// no importa si se añade al final de un nombre de archivo

strcat(tempPath, backslash);

// obtenemos el nombre en formato largo en el campo sfi.szDisplayName

SHGetFileInfo(tempPath, 0, &sfi, sizeof(sfi), SHGFI_DISPLAYNAME);

// vamos añadiendo lo último convertido a la cadena en formato largo

strcat(longPath, backslash);

Page 5: Cómo obtener el nombre de archivo largo a partir de uno corto

strcat(longPath, sfi.szDisplayName);

// leemos el siguiente directorio o nombre de archivo,

// si ya se han leído todos, devolverá un puntero nulo

token = strtok(NULL, backslash);

}

// obtenemos el número de caracteres que forman el nombre completo

ret = strlen(longPath);

if (cchBuffer >= ret)

{

// copiamos el nombre obtenido en el primer parámetro de la función

lstrcpy(lpszLongPath, longPath);

}

}

return ret;

}