2010-04-15 37 views
29

necesito para acceder a algunos archivos con fstream en mi aplicación C++ en Windows. Estos archivos están ubicados en subcarpetas de la carpeta donde se encuentra mi archivo exe.C++ [Windows] Ruta a la carpeta donde se encuentra el ejecutable

  • ¿Cuál es la manera más fácil y más importante: la forma más segura de obtener la ruta a la carpeta del ejecutable actual?
+0

Algo más sofisticado que usar argv [0] que es un parámetro para int main (int argc, char * argv []) y analizarlo? – Minok

Respuesta

39

Use GetModuleHandle y GetModuleFileName para averiguar de dónde se está ejecutando su ejecutable.

HMODULE hModule = GetModuleHandleW(NULL); 
WCHAR path[MAX_PATH]; 
GetModuleFileNameW(hModule, path, MAX_PATH); 

Luego pele el nombre exe del camino.

+2

¿Hay alguna manera de hacer esto sin la API Win32? – asas

+2

@asas: No, no es una manera fácil y segura. –

+1

@asas: ¿Escribir una aplicación para Windows C++ sin usar la API Win32? Como usar Qt en su lugar? –

1

Por defecto, el directorio que el ejecutable se ejecuta desde debería ser el punto de partida. Por lo tanto, abrir un archivo en una subcarpeta debe ser tan fácil como

fstream infile; 
infile.open(".\\subfolder\\filename.ext"); 

dentro de su programa.

Sin embargo, no hay una manera real de GARANTIZAR esto siempre funcionará a menos que utilice un marco que envuelva las características necesarias (me gustaría ver el impulso), o el uso de la API de Windows directamente como GetModuleFileName (como sean e sugerido)

+3

¿Qué? ¿Alguna vez has oído hablar de * correr en *? No tiene que decirme que la ruta en la que se ejecuta el ejecutable es la predeterminada ... – asas

+0

Con todo el respeto, no tengo idea de lo que acaba de decir. No estoy seguro de lo que está haciendo referencia con * ejecutar *. Además, el texto en una página web no necesariamente comparte los significados de sus insinuaciones y elipsis. Entonces, explique qué quiere decir su segunda oración. – KevenK

+3

En caso de que malinterprete: cada proceso tiene su propio valor que representa el directorio actual. De forma predeterminada, este valor debe establecerse en el directorio en el que se encuentra el archivo ejecutable. Puede consultar este directorio usando las llamadas API para 'GetCurrentDirectory()' o configurarlo usando 'SetCurrentDirectory()'. Aunque me doy cuenta de que esta no es una solución exacta para su problema (como dije en el texto original), la información no está incorrecta http://msdn.microsoft.com/en-us/library/aa363806.aspx. Si creía que valía la pena votar, no estoy seguro de que comprenda el uso previsto del sistema de votación aquí. – KevenK

20

GetThisPath.h

/// dest is expected to be MAX_PATH in length. 
/// returns dest 
///  TCHAR dest[MAX_PATH]; 
///  GetThisPath(dest, MAX_PATH); 
TCHAR* GetThisPath(TCHAR* dest, size_t destSize); 

GetThisPath.cpp

#include <Shlwapi.h> 
#pragma comment(lib, "shlwapi.lib") 

TCHAR* GetThisPath(TCHAR* dest, size_t destSize) 
{ 
    if (!dest) return NULL; 
    if (MAX_PATH > destSize) return NULL; 

    DWORD length = GetModuleFileName(NULL, dest, destSize); 
    PathRemoveFileSpec(dest); 
    return dest; 
} 

mainProgram.cpp

TCHAR dest[MAX_PATH]; 
GetThisPath(dest, MAX_PATH); 

Actualización: PathRemoveFileSpec está en desuso en Windows 8. Sin embargo, el reemplazo, PathCchRemoveFileSpec, está disponible en Windows 8 + solamente. (Gracias a @askalee por el comentario)

Creo que por debajo de este código podría funcionar, pero lo estoy dejando el código anterior hasta allí hasta que se vetado el código de abajo. No tengo un compilador configurado para probar esto en este momento. Si usted tiene la oportunidad de probar este código, por favor enviar un comentario diciendo si este código a continuación trabajó y en qué sistema operativo que la prueba. ¡Gracias!

GetThisPath.h

/// dest is expected to be MAX_PATH in length. 
/// returns dest 
///  TCHAR dest[MAX_PATH]; 
///  GetThisPath(dest, MAX_PATH); 
TCHAR* GetThisPath(TCHAR* dest, size_t destSize); 

GetThisPath.cpp

#include <Shlwapi.h> 
#pragma comment(lib, "shlwapi.lib") 

TCHAR* GetThisPath(TCHAR* dest, size_t destSize) 
{ 
    if (!dest) return NULL; 

    DWORD length = GetModuleFileName(NULL, dest, destSize); 
#if (NTDDI_VERSION >= NTDDI_WIN8) 
    PathCchRemoveFileSpec(dest, destSize); 
#else 
    if (MAX_PATH > destSize) return NULL; 
    PathRemoveFileSpec(dest); 
#endif 
    return dest; 
} 

mainProgram.cpp

TCHAR dest[MAX_PATH]; 
GetThisPath(dest, MAX_PATH); 
+6

+1 para 'PathRemoveFileSpec', no lo sabía. – lambdas

+3

Parece que PathRemoveFileSpec está en desuso: http://msdn.microsoft.com/en-us/library/windows/desktop/bb773748(v=vs.85).aspx, use PathCchRemoveFileSpec en su lugar. – askalee

+2

@askalee Parece que vale la pena señalar que solo es compatible con las aplicaciones de escritorio Win8 (y superiores) –

Cuestiones relacionadas