1. 程式人生 > >獲得當前應用程式目錄的GetCurrentDirectory()和GetModuleFileName()函式 .

獲得當前應用程式目錄的GetCurrentDirectory()和GetModuleFileName()函式 .

bool CtestDlg::GetXMLMessage(void) 
{ 
    char cModulePath[MAX_PATH] = {0}; 
    ::GetModuleFileName(NULL, cModulePath, MAX_PATH); 
    ::PathRemoveFileSpec(cModulePath); 
  
    char cCurrentPath[MAX_PATH] = {0}; 
    ::GetCurrentDirectory(MAX_PATH, cCurrentPath); 
  
    string strPath = cModulePath; 
    strPath += "\\Log.xml"; 
  
    CMarkup markup; 
    if ((!markup.Load(strPath.c_str())) 
        || (!markup.IsWellFormed()) 
        || (!markup.FindElem(szUTPSDocRoot)) 
        ) 
    { 
        return false; 
    } 
  
    markup.IntoElem(); 
    ASSERT(0 == m_vecLogItem.size()); 
  
    LOGITEM li; 
    while (true) 
    { 
        if (!markup.FindElem(szItemLabel)) 
        { 
            break; 
        } 
  
        li.strName = markup.GetAttrib(szLabelName); 
        li.bShow = (markup.GetAttrib(szLabelShow)=="true" ? true : false); 
        li.strResourceID = markup.GetAttrib(szLabelResource); 
  
        m_vecLogItem.push_back(li); 
    } 
  
    return true; 
} 
  
void CtestDlg::PopulateList(void) 
{ 
    m_listLog.InsertColumn(0, "Name", LVCFMT_CENTER, 200); 
    m_listLog.InsertColumn(1, "Resource", LVCFMT_CENTER, 200); 
  
    vector<LOGITEM>::iterator it; 
    for (it=m_vecLogItem.begin(); it!=m_vecLogItem.end(); it++) 
    { 
        string strName = it->strName; 
        bool bShow = it->bShow; 
        string strResourceID = it->strResourceID; 
        if (bShow) 
        { 
            int nRow; 
            nRow = m_listLog.InsertItem(0, strName.c_str()); 
            m_listLog.SetItemText(nRow, 1, strResourceID.c_str()); 
        } 
    } 
}

實測(debug執行):
GetModuleFileName 得到 "f:\test\Debug\test.exe"
GetCurrentDirectory 得到 "f:\test"

我想得到當前exe,執行時的所在路徑。豈不是不能用GetCurrentDirectory,而一定要用GetModuleFileName。
再用PathRemoveFileSpec移去\test.exe,從而得到“f:\test\Debug”。

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× 在開發過程中經常需要獲得程式當前的執行目錄,這時就可以使用GetCurrentDirectory()和GetModuleFileName()函式,GetCurrentDirectory只是返回當前程序的當前目錄,而並不是程序的映象檔案(.exe)所在的目錄,GetCurrentDirectory()適用於XP等系統,,在WinCE上不能使用,GetModuleFileName()適用於WinCE2.0以後.

函式說明:

DWORD WINAPI GetModuleFileName(
HMODULE hModule,
LPTSTR lpFileName,
DWORD nSize
);
函式功能
  此函式得到當前應用程式的執行目錄,還包括應用程式的檔名。
引數說明
  hModule:要獲取檔名的模組名柄,可以是運用LoadLiberary得到的控制代碼,null表示當前模組
  lpFileName:輸出引數,存放取得的檔名
  nSize:lpFileName引數的長度

DWORD GetCurrentDirectory(
   DWORD nBufferLength, // size of directory buffer
   LPTSTR lpBuffer // directory buffer
   );
函式功能


 找到當前程序的當前目錄 (注意:當前目錄是可變的,如在vs2010環境下執行,得到的是工程檔案所在的目錄;如果在cmd下執行可執行檔案,此時的目錄就是exe檔案所在的目錄,此時與GetModuleFileName結果就相差一個可執行檔名。)
引數說明
  nBufferLength:lpBuffer緩衝區的長度
  lpBuffer:指定一個預定義字串,用於裝載當前目錄
返回值
 呼叫成功 返回裝載到lpBuffer的位元組數。

使用方法:
//下面的一段程式碼主要是獲得當前程式的執行目錄(.exe)所在的目錄
{
    CString path;
    GetModuleFileName(NULL,path.GetBufferSetLength(MAX_PATH+1),MAX_PATH);
    path.ReleaseBuffer();
    int pos = path.ReverseFind('\\');
    path = path.Left(pos);
}

GetModuleFileName函式
 

WINAPI DWORD GetModuleFileName(
HMODULE hModule,
LPWSTR lpFilename,
DWORD nSize
);

    GetBuffer和ReleaseBuffer是一套需要配合使用的函式, 與GetBufferSetLength相比, 優點是如果分配的空間大於實際儲存的字串(0結尾),ReleaseBuffer會把多餘申請的空間釋放, 歸還給系統; 但使用時需要注意以下問題: 如果要儲存的字串為abc(0結尾),則GetBuffer引數應至少為3; 如果要儲存的內容不是以0結尾, 比如是讀取檔案資料, 則GetBuffer引數如果大於檔案長度時,ReleaseBuffer引數一定要為檔案長度(如果GetBuffer引數為檔案長度的話不存在問題,ReleaseBuffer引數可以為預設-1)! GetBufferSetLength相對比較容易理解, 它申請一個指定長度的空間, 即使裡面最終儲存的字串長度小於申請的空間長度, 也不會將多餘空間釋放.

呼叫示例:
TCHAR *path = new TCHAR[MAX_PATH];
ZeroMemory(path, MAX_PATH);
// path == "d:\Project\Test\MFC\MFC\debug"
GetCurrentDirectory(MAX_PATH, path);
// path ==  "d:\Project\Test\MFC\debug\MFC.exe"
GetModuleFileName(NULL,path,MAX_PATH);

補充說明:
如果想得到一個已經載入的DLL檔案的路徑,可以運用以下方法:
char  strPath[MAX_PATH];  
GetModuleFileNameA(GetModuleHandle("你的DLL名字"),strPath,MAX_PATH);
int j=strlen(strPath);
for(j=strlen(strPath);strPath[j]!='\\';j--);
strPath[j]='\0'; 
其中strPath即為你的DLL檔案所在的目錄