我没有用C ++编写太多代码,因为HS和我很生锈/没有经验。
我想查找计算机上的所有正在运行的进程,并使用其名称填充列表框控件。我创建了一个C ++ win form应用程序,在表单加载事件处理程序中,我有以下代码 -
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
// Proccess monitor class
ProcessMonitor oMonitor;
// Array pointer
string* processes = NULL;
// Call method in process monitor class called get processes,
// pass int array pointer as parameter
oMonitor.GetProcesses(processes);
// Iterate through array
for (int i = 0; i < sizeof(processes) / sizeof(string); i++)
{
}
}
};
希望代码/评论足够直接。
这就是我的GetProcesses方法 -
void ProcessMonitor::GetProcesses(string processNames[])
{
// Array to hold process ID's
DWORD aProcesses[1024], cbNeeded, cProcesses;
// Iterator
unsigned int i;
// If no running processes can be detected exit function
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return;
// Get number of running processes
cProcesses = cbNeeded / sizeof(DWORD);
// Instantiate array that was passed in
// ***NOTE*** I think this is where my problem lies,
// as I passed in a pointer to an array, not an actual array
processNames = new string[cProcesses];
// Iterate through array and initialize all indicies to an empty string
for ( int j = 0; j < sizeof(processNames) / sizeof(string); i++)
{
processNames[i] = "";
}
// Enumerate through processes and fill array with process names
for ( i = 0; i < cProcesses; i++ )
{
if( aProcesses[i] != 0 )
{
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
/*Given a handle to a process, this returns all the modules running within the process.
The first module is the executable running the process,
and subsequent handles describe DLLs loaded into the process.*/
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
{
//This function returns the short name for a module,
//typically the file name portion of the EXE or DLL
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
processNames[i] = szProcessName;
}
}
CloseHandle( hProcess );
}
}
}
我相信我的代码的问题是我没有实例化我的数组,直到它已经在GetProcesses方法中。当代码返回到调用窗口窗体时,指向我传入的数组的指针为空。我猜我要做的是在将数组作为参数传递给函数之前实例化数组。问题是我不知道数组需要的大小,直到我确定机器上正在运行的进程数。
我意识到我可以将GetProcesses函数分解为两个调用,一个用于确定数组所需的大小,另一个用于填充数组。问题是如果你检查条件 -
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return;
该条件下的调用将使用所有进程ID填充aProcesses数组。我不想两次这样做。
对于我做错的事,有没有人有任何想法?
如果我真的离开这里我会道歉,我暂时没有用C ++编写任何东西。
答案 0 :(得分:1)
ProcessMonitor :: GetProcesses(string processNames [])
我认为你需要将指针传递给函数
不太确定语法
ProcessMonitor :: GetProcesses(string * processNames [])
,因为 processNames = new string [cProcesses]; 将在本地分配它,它将不会返回...
(哦,是的,我认为托管C ++是世界上最糟糕的。但这是我的看法。)
答案 1 :(得分:0)
字符串和向量是您在C ++中的朋友:)
#include <string>
#include <vector>
typedef std::vector<std::string> StringVector;
StringVector ProcessMonitor::GetProcesses()
{
StringVector ret;
// Array to hold process ID's
DWORD aProcesses[1024], cbNeeded, cProcesses;
// Iterator
unsigned int i;
// If no running processes can be detected exit function
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return;
// Enumerate through processes and fill array with process names
for ( i = 0; i < cProcesses; i++ )
{
if( aProcesses[i] != 0 )
{
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]);
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
/*Given a handle to a process, this returns all the modules running within the process.
The first module is the executable running the process,
and subsequent handles describe DLLs loaded into the process.*/
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
{
//This function returns the short name for a module,
//typically the file name portion of the EXE or DLL
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
// CHANGE HERE!!!
ret.push_back(szProcessName);
}
}
CloseHandle( hProcess );
}
}
return ret; // return vector back to caller.
}
请致电:
StringVector ret = monitor.GetProcesses();