《Windows API巡礼》---GetCurrentDirectory和GetModuleFileName
使用GetCurrentDirectory和SetCurrentDirectory可以获取程序的当前目录,使用GetModuleFileName可以获取模块的路径,如果以NULL为参数调用GetModuleFileName,将会返回当前模块的路径。如果在程序主模块(.exe)中获取当前模块路径,便可以从当前的路径中提取出程序运行时所在的路径。下面分别介绍:
1)GetCurrentDirectory函数用于获取当前进程所在的目录:
DWORD WINAPI GetCurrentDirectory(
__in DWORD nBufferLength, //路径字符串缓冲区的大小(TCHAR为单位)
//需包含结尾null字符所需空间,一般赋值为MAX_PATH
__out LPTSTR lpBuffer //指向获取的路径字符串,字符串以null结尾
);
当指定参数nBufferLength为0,lpBuffer为NULL时,函数将返回所需缓冲区的大小;
返回值:
成功时,返回写到缓冲区的字符数,不包括结尾null字符;
失败时,返回值是0,可用GetLastError()获得进一步错误信息;
如果lpBuffer指向的缓冲区大小不足,返回值将指定所需的缓冲区大小(字符数,包括null结束符)。
函数用法实例:
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define BUFSIZE MAX_PATH //缓冲区大小
int main(int argc, TCHAR **argv)
{
TCHAR buffer[BUFSIZE];
DWORD dwRet;
dwRet = GetCurrentDirectory(BUFSIZE, buffer);
if(dwRet == 0) //函数执行失败
{
printf("GetCurrentDirectory failed (%d)/n", GetLastError());
return 1;
}
if(dwRet > BUFSIZE) //缓冲区空间不足
{
printf("Buffer too small, need %d characters/n", dwRet);
return 1;
}
_tprintf(TEXT("The current directory is : %s/n"), buffer); //控制台输出进程当前目录
system("pause");
return 0;
}
2)SetCurrentDirectory函数用于设置进程的当前目录:
BOOL WINAPI SetCurrentDirectory(
__in LPCTSTR lpPathName //要设置的路径值
);
返回值:
成功时,返回非0值,表示获取的字符串的长度;
失败时,返回0值,调用GetLastError()函数查看进一步错误信息
3)GetModuleFileName函数用于获得模块的文件名,当第一个参数为NULL时,表示获取当前模块的路径:
DWORD WINAPI GetModuleFileName(
__in_opt HMODULE hModule, //模块句柄
__out LPTSTR lpFilename, //返回的模块的全路径
__in DWORD nSize //lpFilename指向的缓冲区的大小(TCHAR为单位)
);
返回值:
成功时,返回非零值,表示获取的路径的字符串长度;
失败时,返回零值。
实例程序如下:
#include <windows.h>
#include <stdio.h>
#include <tchar.h> //包含_tprintf等函数
#include <Strsafe.h> //包含StringCchCopy函数(最低配置Windows XP with SP2、Windows Server 2003 with SP1)
/************************************************
* 功能:获取当前目录、获取程序所在目录、¡
* 获取模块路径
************************************************/
int main(int argc, TCHAR **argv)
{
//用于存储当前路径
TCHAR szCurrentDirectory[MAX_PATH];
//用于存储模块路径
TCHAR szModulePath[MAX_PATH];
//Kernel32文件名与句柄
LPTSTR szKernel32 = TEXT("kernel32.dll");
HMODULE hKernel32 = NULL;
//当前路径的长度,可用于判断获取是否成功
DWORD dwCurDirPathLen;
//获取进程当前目录
dwCurDirPathLen = GetCurrentDirectory(MAX_PATH, szCurrentDirectory);
if(dwCurDirPathLen == 0)
{
printf("获取当前目录错误/n");
return 0;
}
_tprintf("进程的当前目录为:%s/n", szCurrentDirectory);
//将进程当前目录设置为"C:/"
if(SUCCEEDED(StringCchCopy(szCurrentDirectory, MAX_PATH, "C://")))
{
if(!SetCurrentDirectory(szCurrentDirectory))
{
printf("设置当前目录失败/n");
return 0;
}
printf("已经设置当前目录为:%s/n", szCurrentDirectory);
//在当前目录下创建子目录"ASCE1885"
CreateDirectory("ASCE1885", NULL);
//再次获取系统当前目录
dwCurDirPathLen = GetCurrentDirectory(MAX_PATH, szCurrentDirectory);
if(dwCurDirPathLen == 0)
{
printf("获取当前目录失败/n");
return 0;
}
_tprintf("再次获取的当前目录为:%s/n", szCurrentDirectory);
}
//使用NULL参数,获取本模块的路径
if(!GetModuleFileName(NULL, szModulePath, MAX_PATH))
{
printf("获取模块路径错误/n");
return 0;
}
_tprintf("本模块路径为:%s/n", szModulePath);
//获取Kernel32.dll的模块句柄
hKernel32 = LoadLibrary(szKernel32);
//使用Kernel32.dll的模块句柄获取其路径
if(!GetModuleFileName(hKernel32, szModulePath, MAX_PATH))
{
printf("获取Kernel32模块路径失败/n");
return 0;
}
_tprintf("Kernel32模块路径是:%s/n", szModulePath);
system("pause");
return 0;
}
几点需要注意的:
1)在进程中使用相对路径,则相对路径的起始点是程序的当前路径而不是可执行文件所在的路径;
2)进程的当前路径在默认情况下是应用程序可执行文件所在的路径;
3)模块路径和程序的当前路径是两个概念,进程的主程序和进程中所加载的所有DLL都是进程的模块。
posted on 2010-06-30 20:10 android开发实例 阅读(1458) 评论(0) 编辑 收藏 举报