Question:
How can I find the name of the program file (EXE) associated with another process? I've tried various combinations of GetModuleFileName, GetModuleInstance, and GetModuleHandle, but nothing seems to work.
Answer:
Download the code for this article: CQA0207.exe (72KB)
The problem with these calls is that they work only for modules loaded within the current running process, not modules in a different process. For that, you need something else, and here the road forks. If you're writing for Windows NT® 4.0, Windows 2000, or Windows XP, you can use PSAPI, a relatively new DLL with functions to get information about processes and modules. If you're writing for Windows 95, Windows 98, or Windows Me, you'll have to use ToolHelp. Since I'm so modern, I'll show you how to do it the PSAPI way. For help with ToolHelp, see Article Q175030, "HOWTO: Enumerate Applications in Win32" on MSDN®.
One of the functions in PSAPI is GetModuleFileNameEx. It takes a process and module handle and gets the name of the module. How do you know which module in a process is the EXE that started it? There's another PSAPI function, EnumProcessModules, that stuffs an array with module handles for all the modules in a process. The first entry is always the main module, so you can write
DWORD count;to get the first HMODULE, then call GetModuleFileNameEx. To show how it works in practice, I wrote a little program, lp, that lists processes with their module names and main windows (see Figure 2 ). Figure 3 shows a sample run. (Note that Windows Explorer and Outlook both have two "main" windows.)
HMODULE hm[1];
EnumProcessModules(hProcess, hm, 1, &count);
Figure 3 Sample Run
The lp program uses a third PSAPI function, EnumProcesses, to enumerate all the running processes, but following the same idea as CWindowIterator and CMainWindowIterator from the previous question, I encapsulated the gory aspects of EnumProcesses and EnumProcessModules in two iterator classes, CProcessIterator and CProcessModuleIterator .With these classes in hand, lp is pretty straightforward. To iterate the processes, try the following:
CProcessIterator itp;And here's how to get the name of the EXE that created the process:
for (DWORD pid=itp.First(); pid; pid=itp.Next()) {
// handle each process
}
CProcessModuleIterator itm(pid);Since lp displays just the base module file name, not the full path name, I use another PSAPI function, GetModuleBaseName, instead of GetModuleFileNameEx. And since CProcessModuleIterator opens the process to enumerate the modules, I don't have to call OpenProcess. Instead, I can use CProcessModuleIterator::GetProcessHandle to get the already open process handle. Then lp uses CMainWindowIterator with each process to display the HWNDs of all the main windows. The bulk of lp is the logic to interpret command-line switches. For example, -c lists the window class names, and -t the titles.
HMODULE hModule = itm.First(); // .EXE
TCHAR modname[_MAX_PATH];
GetModuleBaseName(itm.GetProcessHandle(),
hModule, modname, _MAX_PATH);
Since that was so easy, I wrote lp again just for fun, this time in C# .Not surprisingly, things are a lot easier with .NET. There's no need for PSAPI or home-grown iterator classes; .NET already has all the classes you need to navigate processes and modules. Process.GetProcesses returns an array of Process objects, all the processes in the system. From each Process object you can get its main module and window handle.
Process[] procs = Process.GetProcesses();p.MainModule is the main (EXE) module (to get all of them, use p.Modules, a ProcessModuleCollection) and p.MainWindowHandle is the main window handle. (See my comments at the end of the preceding question about this strange but useful property.) While lp is a lot simpler in C#, all that ease-of-programming comes at a cost. When I run the C++ version of lp, the response is instantaneous. From the moment I press Enter to the moment the output appears, there's no delay I can humanly perceive. With .NET, it takes a long second—even with 768MB. C# and .NET just can't deliver the speed of C/C++ and native APIs. This should come as no surprise, knowing all that goes on behind the magic curtain. Of course, no programmer in his right mind would use .NET to write a console app, except as a learning exercise. That would be like firing up the space shuttle to get groceries. Did you ever notice the "net" in .NET? That means .NET is aimed at Web apps, where a few bazillion extra CPU cycles is nothing among friends, and gigabyte servers can be preloaded up the wazoo.
int len = procs.GetLength(0);
for (int i=0; i<len; i++) {
Process p = procs[i];
if (p.Id!=0) {
int hwnd = p.MainWindowHandle.ToInt32();
if (hwnd!=0) { // if has a main window:
ProcessModule pm = p.MainModule;
String modname = pm.ModuleName;
•••
}
}
}
Update
In my May column , Destin Szelong asked a question about function hiding. This happens when you have a base class with overloaded virtual functions and you override one in a derived class. The other functions are not automatically inherited, because once the compiler finds the function name in the derived scope, it looks no further. In May, I showed how to get around the function hiding problem by defining a derived class function that explicitly calls the base class.
class D : public B {As several readers including guru Scott Meyers pointed out, there's another way.
public:
virtual void test(int x) {
B::test(x); // call base explicitly
}
};
class D : public B {This brings B::test into the scope of D. It has the advantage that you don't have to rewrite D if someone expands B with more overloaded test functions. Not to mention it requires less typing! When you use using, all overloaded B::test functions come into D's scope and are thus inherited. This may be an advantage or disadvantage, depending on what you're trying to do. If you want to keep some test functions hidden from consumers of D, you can use my first method (call base explicitly), or make the functions you want to hide private or protected. If you read Scott's book More Effective C++ (Addison-Wesley, 1995), you'll learn on pages 143-144 that you can even use using to circumvent the privacy of base classes.
public:
using B::test;
// other test overrides
};
class B { // some classThis trick is expedient when B should properly be hidden, but has one or two functions you want to expose. All of which goes to prove that in C++, there's never only one way to skin a cat.
public:
func1();
func2(double d);
virtual test();
virtual test(int x);
};
// D is privately derived from B
class D : private B {
public:
// make all B::test fns public!
using B::test;
};
Happy programming!