GetModuleFileName function
Applies to: desktop apps only
Retrieves the fully qualified path for the file that contains the specified module. The module must have been loaded by the current process.
To locate the file for a module that was loaded by another process, use the GetModuleFileNameEx function.
Syntax
DWORD WINAPI GetModuleFileName( __in_opt HMODULE hModule, __out LPTSTR lpFilename, __in DWORD nSize );
Parameters
- hModule [in, optional]
-
A handle to the loaded module whose path is being requested. If this parameter is NULL, GetModuleFileName retrieves the path of the executable file of the current process.
The GetModuleFileName function does not retrieve the path for modules that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx.
- lpFilename [out]
-
A pointer to a buffer that receives the fully qualified path of the module. If the length of the path is less than the size that the nSize parameter specifies, the function succeeds and the path is returned as a null-terminated string.
If the length of the path exceeds the size that the nSize parameter specifies, the function succeeds and the string is truncated to nSize characters including the terminating null character.
Windows XP: The string is truncated to nSize characters and is not null-terminated.The string returned will use the same format that was specified when the module was loaded. Therefore, the path can be a long or short file name, and can use the prefix "\\?\". For more information, see Naming a File.
- nSize [in]
-
The size of the lpFilename buffer, in TCHARs.
Return value
If the function succeeds, the return value is the length of the string that is copied to the buffer, in characters, not including the terminating null character. If the buffer is too small to hold the module name, the string is truncated to nSize characters including the terminating null character, the function returns nSize, and the function sets the last error to ERROR_INSUFFICIENT_BUFFER.
Windows XP: If the buffer is too small to hold the module name, the function returns nSize. The last error code remains ERROR_SUCCESS. If nSize is zero, the return value is zero and the last error code is ERROR_SUCCESS.
If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError.
Remarks
If a DLL is loaded in two processes, its file name in one process may differ in case from its file name in the other process.
The global variable _pgmptr is automatically initialized to the full path of the executable file, and can be used to retrieve the full path name of an executable file.
Examples
For an example, see Installing a Service.
Requirements
|
Minimum supported client | Windows XP |
|---|---|
|
Minimum supported server | Windows Server 2003 |
|
Header |
|
|
Library |
|
|
DLL |
|
|
Unicode and ANSI names | GetModuleFileNameW (Unicode) and GetModuleFileNameA (ANSI) |
See also
Send comments about this topic to Microsoft
Build date: 3/6/2012
Here's a C++ wrapper for this function that takes care of appropriate buffer sizing and error checking. You may want to upgrade it to use TCHARs for unicode-aware applications.
<pre>std::string WindowsEnvironment::getExectablePath() {
std::vector<char> executablePath(MAX_PATH);
// Try to get the executable path with a buffer of MAX_PATH characters.
DWORD result = ::GetModuleFileNameA(
nullptr, &executablePath[0], static_cast<DWORD>(executablePath.size())
);
// As long the function returns the buffer size, it is indicating that the buffer
// was too small. Keep enlarging the buffer by a factor of 2 until it fits.
while(result == executablePath.size()) {
executablePath.resize(executablePath.size() * 2);
result = ::GetModuleFileNameA(
nullptr, &executablePath[0], static_cast<DWORD>(executablePath.size())
);
}
// If the function returned 0, something went wrong
if(result == 0) {
throw std::runtime_error("GetModuleFileName() failed");
}
// We've got the path, construct a standard string from it
return std::string(executablePath.begin(), executablePath.begin() + result);
}</pre>
- 4/8/2012
- Cygon4
This is probably by design, and passing that file name to CreateFile() to open the binary file will redirect back to the same file correctly.
However, calling Wow64DisableWow64FsRedirection() before calling GetModuleFileName() does NOT turn off this redirection give you the correct file name!! If you need the "true" file name for a module, this won't give it to you.
For example, a 32-bit program that does the following:
- Call Wow64DisableWow64FsRedirection() to disable file redirection.
- Call GetModuleHandle() to get the handle of a driver DLL that is already loaded. Since this is a 32-bit application, the module is actually in %windir%\SysWOW64\foo.dll.
- Call GetModuleFileName() to get the file name. This will return something like %windir%\System32\foo.dll
- Call CreateFile() to open the file. Since FS redirection is turned off, this will open the 64-bit version of the module, not the file that is actually loaded!
IMHO this should be considered a bug in either Wow64DisableWow64FsRedirection or GetModuleFileName; I'm not sure which one should be blamed.
I haven't tested this on Vista or Win7, but XP Professional 64-bit certainly behaves this way.
- 1/4/2010
- mTIE
This global variable is only valid in applications compiled with the ASCII libraries. When using unicode libraries _wpgmptr should be used instead.
There is a macro _tpgmptr defined in tchar.h which will automatically use the correct variable for the project configuration.
Note that this variable is considered unsafe. _get_pgmptr, _get_wpgmptr and _get_tpgmptr should be used instead if GetModuleFileName can't be.
- 11/27/2009
- Andrew Brock
For Windows Mobile Process ID can be used directly as handle.
- 9/6/2008
- Tuanruby
- 1/4/2009
- Thomas Lee