使用WIndows API函数EnumProcesses()
时,我有一些奇怪的行为我有一个函数可以确定某个名称的进程是否已经在运行,哪个传递不同的结果,我手动打开.executable(双击)或通过shell打开它。
当我通过shell打开它时,它检测到它只运行一次(本身),一切都很好。当我在.exe文件上使用doubleclick打开它时,但该函数返回true(已经在运行),因为循环列出了两次相同的进程。
对于以下代码剪切,请提及:
this->thisExecutableFile
包含argv [0](从运行程序初始化)以获取自己的进程名称,如下所示:
int main(int argc, char* argv[])
{
ClientUpdate* update = ClientUpdate::getInstance();
update->setThisExecutableFile(argv[0]);
if (update->clientUpdateProcessIsRunning() == false) {
...
我的目标是找出此进程的另一个实例是否已在运行,在这种情况下退出它。
这是我的代码:
bool ClientUpdate::clientUpdateProcessIsRunning()
{
bool retVal = false;
uint16_t processCount = 0;
unsigned long aProcesses[1024], cbNeeded, cProcesses;
if(!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
return false;
cProcesses = cbNeeded / sizeof(unsigned long);
for(unsigned int i = 0; i < cProcesses; i++) {
if (aProcesses[i] == 0) {
continue;
}
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, aProcesses[i]);
wchar_t buffer[50];
GetModuleBaseNameW(hProcess, 0, buffer, 50);
CloseHandle(hProcess);
std::wstring tempBuffer(buffer);
std::string tempStringBuffer(tempBuffer.begin(), tempBuffer.end());
boost::filesystem::path p(this->thisExecutableFile);
if(_strcmpi(p.filename().string().c_str(), tempStringBuffer.c_str()) == 0) {
processCount++;
if(processCount > 1) {
retVal = true;
break;
}
}
}
return retVal;
}
我知道在文件上使用doubleclick或通过shell调用它时,基本路径是不同的。 (shell只生成文件名,而doubleclick将整个路径+文件名传递给argv [0])但我用
修复了这个问题boost::filesystem::path p(this->thisExecutableFile);
p.fileName()
在我使用print检查的两种情况下,返回正确的文件名(没有路径)。
我很困惑为什么EnumProcesses()在通过doubleclick而不是shell调用文件时两次返回相同的文件。它没有产生两个处理过的,在任务管理器中我也没有看到这样的东西。
这是一个错误还是我需要了解一些我在文档中找不到的方法?
答案 0 :(得分:1)
感谢理查德克里滕的暗示,我能够解决它。我的方法现在变得更小,更容易。 (也可能还有更多的性能,然后扫描整个进程堆栈。):D
这是解决方案
bool ClientUpdate::clientUpdateProcessIsRunning()
{
HANDLE hMutex = CreateMutexA(NULL, TRUE, "client-updater-mtx");
DWORD dwErr = GetLastError();
return dwErr == ERROR_ALREADY_EXISTS;
}
谢谢!