Hi,
I have one .Net Exe file when i click on that i need to get path of that Exe in My MFC code,how can i get this ,please help me on this.
Thanks
Abhi
Printable View
Hi,
I have one .Net Exe file when i click on that i need to get path of that Exe in My MFC code,how can i get this ,please help me on this.
Thanks
Abhi
There are several ways to get a process path (different by the calling one) but no one is simple.
Here is an example using WMI (Windows Management Instrumentation):
And here is a usage example:Code:#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "comsuppw.lib")
HRESULT CProcHelper::GetProcessPath(const CStringW& strExeFile, CStringW& strPath, BOOL& bFound)
{
// NOTE: don't forget a call to AfxOleInit in InitInstance of application class.
bFound = FALSE;
// initialize the IWbemLocator interface
IWbemLocator *pLoc = NULL;
HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL,
CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
if(FAILED(hr))
{
return hr;
}
// create a connection to WMI namespace.
IWbemServices *pSvc = NULL;
hr = pLoc->ConnectServer(bstr_t("ROOT\\CIMV2"),
NULL, NULL, 0, NULL, 0, 0, &pSvc);
if(FAILED(hr))
{
pLoc->Release();
return hr;
}
// set security levels on the proxy
hr = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
if(FAILED(hr))
{
pSvc->Release();
pLoc->Release();
return hr;
}
// do query
IEnumWbemClassObject* pEnum = NULL;
hr = pSvc->ExecQuery(bstr_t("WQL"),
bstr_t("SELECT Name, ExecutablePath FROM Win32_Process"),
WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnum);
if(FAILED(hr))
{
pSvc->Release();
pLoc->Release();
return hr;
}
// get each processes enumeration
IWbemClassObject *pclsObj;
ULONG uReturn = 0;
while(pEnum)
{
pEnum->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if(0 == uReturn)
break;
// get properties values
VARIANT vtName;
pclsObj->Get(L"Name", 0, &vtName, 0, 0);
if(!strExeFile.CompareNoCase(vtName.bstrVal))
{
VARIANT vtExecutablePath;
pclsObj->Get(L"ExecutablePath", 0, &vtExecutablePath, 0, 0);
strPath = vtExecutablePath.bstrVal;
VariantClear(&vtExecutablePath);
bFound = TRUE; // successfully found
break;
}
VariantClear(&vtName);
}
// cleanup
pclsObj->Release();
pEnum->Release();
pSvc->Release();
pLoc->Release();
return hr;
}
Code:void CMyDialog::OnBnClickedShowSomeProcesPath()
{
CString strPath;
BOOL bFound = FALSE;
CString strResult;
LPCTSTR pszExeFile = _T("some_executable.exe");
HRESULT hr = CProcHelper::GetProcessPath(pszExeFile, strPath, bFound);
if(FAILED(hr))
{
strResult.Format(_T("GetProcessPath failed\nError: %08x"), hr);
}
else if(! bFound)
{
strResult.Format(_T("Process '%s' not found"), pszExeFile);
}
else
{
strResult.Format(_T("%s path is '%s'"), pszExeFile, strPath);
}
AfxMessageBox(strResult);
}
Thank You.
Dont we have any Library Function to get the Path.
Cant I achieve it using GetModuleName and GetModuleFileName ?
-Abhi
For the GetModuleFileName you would need HMODULE handle of the executable. That you can retrieve by calling EnumProcessModules where you need a handle of the process associated with the executable. The process handle is returned when calling OpenProcess with mode PROCESS_QUERY_INFORMATION and input of the process ID. The process ID you can get by EnumProcesses if you know the name of the process.
If you only know the windows caption of the application but not the processname you can call EmumWindows or FindWindow to retrieve the windows handle of the main window. Then call GetWindowModuleFileName to retrieve path of executable.
AFAIK there is no Windows API function to directly retrieve the full path given the executable/process (other than caller process) name.
Here is another example using PSAPI (Process Status API) functions EnumProcesses, GetModuleBaseName, and GetModuleFileNameEx:
Not so much sweat like in case of using WMI, but sweat a little... ;)Code:#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
BOOL GetProcessPath(LPCTSTR pszExeFile, CString& strPath)
{
BOOL bFound = FALSE;
const DWORD cb = 1024; // assume enough
DWORD dwBytesReturned = 0;
DWORD dwIDs[cb];
if(::EnumProcesses(dwIDs, cb, &dwBytesReturned))
{
size_t size = dwBytesReturned / sizeof(DWORD);
CString strBaseName;
const DWORD dwSize = MAX_PATH + 1;
for(size_t index = 0; index < size; index++)
{
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
FALSE, dwIDs[index]);
::GetModuleBaseName(hProcess, NULL,
strBaseName.GetBufferSetLength(dwSize), dwSize);
strBaseName.ReleaseBuffer();
if(!strBaseName.CompareNoCase(pszExeFile))
{
::GetModuleFileNameEx(hProcess, NULL,
strPath.GetBufferSetLength(dwSize), dwSize);
bFound = TRUE;
}
::CloseHandle(hProcess);
}
}
return bFound;
}
Thanks Alot..