Está en la página 1de 5

Cmo obtener el nombre de archivo largo a partir de uno corto Este artculo ha sido posible gracias a la colaboracin de Pere

Llaveria.

Con la aparicin de Windows 95 surgi el formato largo en los nombres de archivos. Hay aplicaciones, sin embargo, que por una u otra razn necesitan trabajar con nombres de archivo en formato corto, es decir, con un nombre de archivo limitado a 8 caracteres ms 3 de extensin. Por suerte se aadi en el API de Windows la funcin 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 funcin que nos permita realizar el proceso contrario. Recientemente se ha incluido la funcin GetLongPathName en el API, pero se requiere Windows 98.

Podemos olvidarnos de utilizar la funcin 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 parmetro la ruta completa de un archivo en formato corto, nos devolver lo mismo en su tercer parmetro 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"

Por otro lado, si slo 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 funcin del shell SHGetFileInfo. Para ello hay que especificar SHGFI_DISPLAYNAME en su quinto parmetro. Pero hay un pequeo problema, slo 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 podramos obtener MiPrimerPrograma.exe correspondiente a MIPRIM~1.EXE como se muestra en el ejemplo 3.

Ejemplo 3

SHFILEINFO sfi;

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 funcin SHGetFileInfo para cada subdirectorio especificado en la ruta del nombre completo empezando desde el primer nivel de subdirectorio. Seguidamente se muestra la funcin definitiva:

Funcin 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 = "\\"; // carcter 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) {

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) { // aadimos el siguiente subdirectorio o nombre de archivo strcat(tempPath, token);

// aadimos la barra "\" al final, // no importa si se aade 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 aadiendo lo ltimo convertido a la cadena en formato largo strcat(longPath, backslash);

strcat(longPath, sfi.szDisplayName);

// leemos el siguiente directorio o nombre de archivo, // si ya se han ledo todos, devolver un puntero nulo token = strtok(NULL, backslash); }

// obtenemos el nmero de caracteres que forman el nombre completo ret = strlen(longPath);

if (cchBuffer >= ret) { // copiamos el nombre obtenido en el primer parmetro de la funcin lstrcpy(lpszLongPath, longPath); } }

return ret; }

También podría gustarte