天天看點

日常工作問題總結(三十一)windows擷取路徑的幾個函數GetCurrentDirectory,GetModuleFileName,GetFullPathName

     windows現在具體有多少個擷取路徑的函數本人不清楚,今天暫時講下上面提到的幾個windows函數。

1.GetCurrentDirectory

DWORD GetCurrentDirectory(DWORDnBufferLength,

//sizeofdirectorybuffer

LPTSTRlpBuffer

//directorybuffer

);

函數功能

擷取目前程序的目前目錄。 注意目前目錄這東西有點怪異,本來确實是可執行檔案的所在目錄,但是當用檔案對話框成功打開一個檔案後,該目錄就被修改為被打開的檔案所在目錄。比如在程式中使用"123.txt"這樣的檔案名,希望将它存儲在exe檔案所在目錄中,但是當使用者用檔案對話框打開一個檔案"F:\456.txt"後,這個123.txt會被存儲到F盤下。(VC2005下的情況,其他VC版本待驗證)

參數說明

參數 類型及說明 nBufferLength 緩沖區的長度 lpBuffer 指定一個預定義字串,用于裝載目前目錄

傳回值

調用成功 傳回裝載到lpBuffer的位元組數。 使用GetLastError函數可獲得錯誤資訊。

2.GetModuleFileName,GetFullPathName

DWORD GetFullPathName(
 
LPCTSTR lpFileName, // file name
 
DWORD nBufferLength, // size of path buffer,建議取值為:MAX_PATH
 
LPTSTR lpBuffer, // path buffer
 
LPTSTR *lpFilePart // address of file name in path
 
);
 
功能說明
 
從一指定檔案得到檔案的路徑
 
參數說明
 
LPCTSTR lpFileName, 指定檔案的名字
 
DWORD nBufferLength,緩存區的大小
 
LPTSTR lpBuffer, 用于存放路徑的緩存區
 
LPTSTR *lpFilePart 檔案名的起始位址
           
DWORD WINAPI GetModuleFileName(
HMODULE hModule,
LPTSTR lpFileName,
DWORD nSize
);
           
GetModuleFileName(NULL,szText,MAX_PATH);//隻有第一個參數為NULL,傳回目前子產品的PathName,否則傳回對應dll路徑
GetFullPathName("",MAX_PATH,szText,NULL);//根據第一個參數提供的檔案名(可用相對路徑,8.3格式)擴充到含驅動器和目錄
           
GetModuleFileName 是取一個子產品(exe,dll)在磁盤上的路徑。
 GetFullPathName 是把一個8.3格式(dos)的路徑轉換為長檔案名格式。
           

3.GetCurrentDirectory()和GetMoudleFileName()差別

char* pCurrDir = new char[260];
 ::GetCurrentDirectory(260,pCurrDir);
 delete pCurrDir;

 char* pModuleDir = new char[260];
 ::GetModuleFileName(NULL,pModuleDir,260);
 delete pModuleDir;
           

上面代碼執行完成後(調試狀态):

pCurrDir:"C:\\Users\\dell\\Desktop\\共享記憶體\\MySharedServer\\MySharedServer"

pModuleDir:"C:\\Users\\dell\\Desktop\\共享記憶體\\MySharedServer\\Debug\\MySharedServer.exe"

還記得上面看GetCurrentDirectory()函數的函數描述麼?什麼是目前程序的目前目錄?

我自己寫了一些代碼進行測試,一般在一個程序空間内,這兩個得到的位址差別在于“有沒有***.exe”應用程式的名稱,其他都是一緻的,那麼為什麼有目前目錄這個概念?

詳解:

GetCurrentDirectory這個是函數原型,他是主要是作用是擷取程式的目前目錄,大部分指的是目前運作程式所在的運作目錄。記得這個地方說的是大部分情況,不是所有,有些特殊的情況會傳回時其他的路徑。

LPSTR lpath("C:\\Users\\dell\\Desktop\\共享記憶體\\MySharedServer\\Debug\\MySharedServer.exe");
	if( !CreateProcess( NULL,
		lpath,
		 NULL, 
		NULL,
		FALSE,//1.重點
		 0,
 		NULL,
 		NULL, 
		&m_ClientSI,
		&m_ClientPI) )
	{
		ZeroMemory( &m_ClientSI, sizeof(m_ClientSI) );
		m_ClientSI.cb = sizeof(m_ClientSI);
	}
           

上面代碼不要看字面意思,思路是:用client1程序建立子程序client2,而在client2程序中使用GetCurrentDirectory()和GetModuleFileName()兩個函數,此時得出的結果是完全不一樣的。

GetCurrentDirectory()得到的是client1用戶端的運作目錄,GetModuleFileName()得到的還是Client2.exe的應用程式目錄。

//下面的一段代碼主要是獲得目前程式的運作目錄(.exe)所在的目錄
{
    CString path; 
    GetModuleFileName(NULL,path.GetBufferSetLength(MAX_PATH+1),MAX_PATH); 
    path.ReleaseBuffer(); 
    int pos = path.ReverseFind('\\'); 
    path = path.Left(pos); 
}
           

後來檢視了一些資料,微軟也承認這個函數有時候不是那麼恰當,他的這個擷取的值收到很多的影響,是以如果隻是為了擷取目前程式運作路徑,建議使用GetModuleFileName這個函數來處理,這個比較準,因為他獲得是目前運作程式的存儲路徑。