1. 程式人生 > >根據程序控制代碼 獲得可執行檔案路徑 的幾種方法

根據程序控制代碼 獲得可執行檔案路徑 的幾種方法

通過程序控制代碼,獲得可執行檔案的路徑,主要有以下幾種方法:

第一種方法:也是最常用的方法,是通過GetModuleFileNameEx函式獲得可執行檔案的模組路徑,這個函式從Windows NT 4.0開始到現在的Vista系統都能使用,向後相容性比較好。

【函式原型】呼叫失敗將返回0。注:程序的控制代碼須有PROCESS_QUERY_INFORMATION 和 PROCESS_VM_READ許可權。

DWORD
		WINAPI
		GetModuleFileNameExW(
		__in HANDLE hProcess,//標程序的控制代碼
		__in_opt HMODULE hModule,//目標模組的控制代碼(當此引數為NULL時函式返回的是程序可執行檔案的路徑)
		__out_ecount(nSize) LPWSTR lpFilename,//存放路徑的字串緩衝區
		__in DWORD nSize//表示緩衝區的大小
		);

GetModuleFileNameEx 的使用例子

#include <Psapi.h>
#pragma comment (lib,"Psapi.lib")
//...
HANDLE h_Process=OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,ProcessID);
wchar_t path[MAX_PATH+1];
if(!GetModuleFileNameEx(h_Process,NULL,path,MAX_PATH+1))
    return false;
//...

注意:GetModuleFileNameEx函式在64位系統下,獲取不到64位程序的可執行檔案路徑

第二種方法:GetProcessImageFileName函式,這個函式在Windows XP及其以後的系統中都能使用,使用此函式返回的路徑不是通常的系統碟符,如"C:\...",而是驅動層的表示方式"\Device\HarddiskVolume1\...",所以使用起來不是很方便。

【函式原型】函式失敗將返回0。注:程序控制代碼需要有PROCESS_QUERY_INFORMATION的許可權。

DWORD
		WINAPI
		GetProcessImageFileNameW (
		__in HANDLE hProcess,//目標程序的控制代碼
		__out_ecount(nSize) LPWSTR lpImageFileName,//存放路徑的字串緩衝區
		__in DWORD nSize//表示緩衝區的大小
		);

注意:呼叫 GetModuleFileNameEx 和 GetProcessImageFileName 需要包含Psapi.h標頭檔案,並鏈接到Psapi.lib。

第三種方法:使用Windows Vista新增的函式QueryFullProcessImageName,由於是Vista新增的,所以相容性不好。

【函式原型】函式失敗將返回FALSE。

BOOL
		WINAPI
		QueryFullProcessImageNameW(
		__in HANDLE hProcess,//目標程序的控制代碼
		__in DWORD dwFlags,//一般設為0,表示返回的路徑是Win32的路徑格式,如"C:\..."
		__out_ecount_part(*lpdwSize, *lpdwSize) LPWSTR lpExeName,//存放路徑的字串緩衝區
		__inout PDWORD lpdwSize//表示緩衝區的大小
		);
dwFlags,如將其設為PROCESS_NAME_NATIVE將返回"\Device\HarddiskVolume1\..."這樣的格式路徑。呼叫此函式的控制代碼須有PROCESS_QUERY_INFORMATION 或 PROCESS_QUERY_LIMITED_INFORMATION 的許可權,並且只能在Vista或更高版本的系統中使用。
第四種方法:其實也是最靠譜的方法!使用GetProcessImageFileName ,不過該函式返回的格式是DOS格式,需要再通過與 LogicalDriveStrings 比對拼接出程序可執行檔案的完整路徑。方法如下:
/// @brief		獲取指定程序所對應的可執行(EXE)檔案全路徑
/// @param[in]	hProcess : 程序控制代碼。
/// @param[out]	szFilePath : 程序控制代碼hProcess所對應的可執行檔案路徑
///	@remark		hProcess必須具有PROCESS_QUERY_INFORMATION 或 PROCESS_QUERY_LIMITED_INFORMATION 許可權
///	@return		獲取成功返回true,其餘false
bool GetProcessFilePath(IN HANDLE hProcess, OUT std::wstring& szFilePath)
{
	szFilePath = _T("");
	TCHAR tsFileDosPath[MAX_PATH + 1];
	ZeroMemory(tsFileDosPath, sizeof(TCHAR)*(MAX_PATH + 1));
	if (0 == GetProcessImageFileName(hProcess, tsFileDosPath, MAX_PATH + 1))
	{
		return false;
	}

	// 獲取Logic Drive String長度
	UINT uiLen = GetLogicalDriveStrings(0, NULL);
	if (0 == uiLen)
	{
		return false;
	}

	PTSTR pLogicDriveString = new TCHAR[uiLen + 1];
	ZeroMemory(pLogicDriveString, uiLen + 1);
	uiLen = GetLogicalDriveStrings(uiLen, pLogicDriveString);
	if (0 == uiLen)
	{
		delete[]pLogicDriveString;
		return false;
	}

	TCHAR szDrive[3] = TEXT(" :");
	PTSTR pDosDriveName = new TCHAR[MAX_PATH];
	PTSTR pLogicIndex = pLogicDriveString;

	do
	{
		szDrive[0] = *pLogicIndex;
		uiLen = QueryDosDevice(szDrive, pDosDriveName, MAX_PATH);
		if (0 == uiLen)
		{
			if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
			{
				break;
			}

			delete[]pDosDriveName;
			pDosDriveName = new TCHAR[uiLen + 1];
			uiLen = QueryDosDevice(szDrive, pDosDriveName, uiLen + 1);
			if (0 == uiLen)
			{
				break;
			}
		}

		uiLen = _tcslen(pDosDriveName);
		if (0 == _tcsnicmp(tsFileDosPath, pDosDriveName, uiLen))
		{
			wchar_t buf[1024];
			swprintf_s(buf, 1024, L"%s%s", szDrive, tsFileDosPath + uiLen);
			wchar_t *pstr = buf;
			szFilePath = std::wstring(pstr);

			break;
		}

		while (*pLogicIndex++);
	} while (*pLogicIndex);

	delete[]pLogicDriveString;
	delete[]pDosDriveName;

	return true;
}

相關推薦

根據程序控制 獲得執行檔案路徑方法

通過程序控制代碼,獲得可執行檔案的路徑,主要有以下幾種方法: 第一種方法:也是最常用的方法,是通過GetModuleFileNameEx函式獲得可執行檔案的模組路徑,這個函式從Windows NT 4.0開始到現在的Vista系統都能使用,向後相容性比較好。 【函式

C語言中沒有main函式生成執行程式的方法

轉自:http://www.linuxidc.com/Linux/2013-09/90061.htm 1、define預處理指令 這種方式很簡單,只是簡單地將main字串用巨集來代替,或者使用##拼接字串。示例程式如下: #include <stdio.h>

Maven打包執行Jar的方法

一、無依賴其他任何jar <build> <plugins> <plugin> <groupId>org.apache.maven.plugins&

程序控制HANDLE獲得程序主視窗的控制HWND

一個程序可以擁有很多主視窗,也可以不擁有主視窗,所以這樣的函式是不存在的,所幸的是,相反的函式是有的。所以我們可以呼叫EnumWindows來判斷所有的視窗是否屬於這個程序。  typedef struct tagWNDINFO  ​{  ​DWORD dwProc

mfc 根據視窗控制(HWND)殺死程序

先列舉桌面所有的視窗的標題或者類名。根據類名或者標題得知該視窗的控制代碼(HWND)。然後再殺死程序。看程式碼: BOOL bTerminateProcess = FALSE; HWND hwndE

根據視窗控制來獲取程序ID

[DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID

C++ 源執行的詳細過程

靜態 main 類型 替代 三種 靜態鏈接庫 表達式 行處理 pil   編譯,編譯程序讀取源程序(字符流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,再由匯編程序轉換為機器語言,並且按照操作系統對可執行文件格式的要求鏈接生成可執行程序。源代碼--&

lsof-檢視程序控制

  [email protected]:~# lsof COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1

C# 呼叫win32API 獲取程序控制 有毛用???

private void button2_Click(object sender, EventArgs e) { Process[] ProceddingCon = Process.GetProcesses(); //獲得所有程序 Int

C++通過程序名獲取程序控制

記錄下一段,比較常用的程式碼。 // 強殺定期刪除程序 void CDogThread::Quit() { // 結束強殺定期刪除程序 HANDLE hProcess = GetProcessHa

解決 無法啟動除錯。繫結控制無效 開始執行(不除錯) 錯誤

【摘要】VS.NET"試圖執行專案時出錯:無法啟動除錯。繫結控制代碼無效"解決辦法 不要急著重灌.在選單欄裡面選擇"除錯">>"開始執行(不除錯)" 試試,如果這樣能成功,就不需要重灌 【全文】VS.NET"試圖執行專案時出錯:無法啟動除錯。繫結控制代碼無效"解決辦法 不要急著重灌.

FastReport呼叫程序控制,設定視窗置頂

應用場景 在使用第三方列印外掛,FastReport時,選擇列印xps,點選列印,彈出檔案另存為對話方塊,但是此對話方塊不會出現在軟體的最前面,而且會一直佔用程序,點選軟體介面出現假死情況。 解決方案 思路1.設定關閉列印進度視窗,此視窗會一直置頂,而且取消按鈕失效2.列印

Windows程序控制數限制

GDIProcessHandleQuota項設定GDI控制代碼數量,預設值為2710(16進位制)/10000(10進位制),該值的允許範圍為 256 ~ 16384 ,將其調整為大於預設的10000的值。如果您的系統配置了2G或更多內容,不妨將其設定為允許的最大值 16384(10進位制);USERProc

[Delphi]如何通過程序控制判斷該程序是否已退出?

GetExitCodeProcess    看似可以,但是仔細看MSDN,有這麼一句話:“Warning  If a process happens to return STILL_ACTIVE (259) as an error code, applications th

模組控制程序控制的區別?

         在WINDOWS下,模組指的是EXE和DLL等資料載入到記憶體中的影像,模組控制代碼又是比較特殊的,它跟一般的控制代碼不一樣,模組控制代碼指向的就是EXE和DLL等的在記憶體的位置(就是指向它們的資料起始位置);程序控制代碼只是WINDOWS用來標識某個程

python selenium 獲得當前視窗控制/獲得當前視窗

1. 獲得當前視窗控制代碼:    driver.current_window_handles2. 獲得當前所有一開啟的視窗控制代碼:   driver.window_handles3.切換視窗:    driver.switch_to.window()        #引數

MFC通過對話方塊視窗控制獲得對話方塊物件指標

MFC在很多的對話方塊操作中,我們經常要用到在一個對話方塊中呼叫另一個對話方塊的函式或變數.可以用如下方法來解決. HWND hWnd=::FindWindow(NULL,_T("視窗名"));      //得到對話方塊的控制代碼C***Dialog* pWnd= (C*

通過程序名得到程序控制(tlhelp的方法)(ring3)

這個是因為我在網上搜只搜到列舉控制代碼的感覺很不方便,所以寫下這個僅供參考 HANDLE sub2(WCHAR* processname) {PROCESSENTRY32 pe32 = { 0 };// 在本程序中拍一個所有程序的快照HANDLE hModuleSnap

linux whereis-查找二進制程序等相關文件路徑

手冊 linux命令大全 文件的 情況 指定 spa 推薦 key 就是 推薦:更多Linux 文件查找和比較 命令關註:linux命令大全 whereis命令用來定位指令的二進制程序、源代碼文件和man手冊頁等相關文件的路徑。 whereis命令只能用於程序名的搜索,而

案例——檔案控制(pipe)增多tomcat模組定位方法

問題描述:tomcat檔案控制代碼數持續增長 定位方法: 定位檔案控制代碼洩漏前需要收集的必要資訊: tomcat初始啟動時的檔案控制代碼數、對tomcat的詳細lsof結果、以及tomcat的記憶體dump; 按時間段對tomcat的檔案控制代碼數進行統計(每小時、