C++ 统计it运行的程序';s类名称

C++ 统计it运行的程序';s类名称,c++,winapi,C++,Winapi,我试图检测应用程序人员运行的实例数。他打开过我的申请表吗?两次?三次? 我试图通过进程名检查它的实例来检测它,但在windows中它是指针-人们可能会更改.exe名称,它不会计入最终的数字 那我怎么办呢?我想用类名(HWND?)而不是进程名来搜索它,但我该怎么做呢 这是我用于按进程名称检测的代码: int Platform::getMulticlientCount(const std::string& ProcessName) { PROCESSENTRY32 pe32 = {

我试图检测应用程序人员运行的实例数。他打开过我的申请表吗?两次?三次? 我试图通过进程名检查它的实例来检测它,但在windows中它是指针-人们可能会更改.exe名称,它不会计入最终的数字

那我怎么办呢?我想用类名(HWND?)而不是进程名来搜索它,但我该怎么做呢

这是我用于按进程名称检测的代码:

int Platform::getMulticlientCount(const std::string& ProcessName)
{
    PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    const char *cstr = ProcessName.c_str();
    int counter = 0;
    if (Process32First(hSnapshot, &pe32))
    {
        do
        {
            if (_tcsicmp(pe32.szExeFile, cstr) == 0)
            {
                counter++;
            }
        } while (Process32Next(hSnapshot, &pe32));
    }

    CloseHandle(hSnapshot);
    return counter;
}

下面是计算正在运行的实例的示例代码。当应用程序自行计算实例时,是否重命名二进制文件并不重要。我使用了一个文件来保持示例的简单性,但是注册表也可以工作。唯一缺少的是一个全局互斥来保护文件不受并发访问。嗯

#include <iostream>
#include <thread>
#include <fstream>

#include <Windows.h>

class GlobalCounter
{
public:
    GlobalCounter(const std::string& id)
    : _id(id)
    {
        const auto filename = "C:\\users\\twollgam\\" + id + ".counter";

        if (GlobalFindAtomA(id.c_str()) == 0)
        {
            std::ofstream(filename) << 1;

            std::cout << "I am the first instance." << std::endl;
        }
        else
        {
            auto counter = 0;

            std::ifstream(filename) >> counter;

            ++counter;

            std::ofstream(filename) << counter;

            std::cout << "I am the " << counter << " instance." << std::endl;
        }

        _atom = GlobalAddAtomA(id.c_str());
    }

    ~GlobalCounter()
    {
        const auto filename = "C:\\users\\twollgam\\" + _id + ".counter";
        auto counter = 0;

        std::ifstream(filename) >> counter;

        --counter;

        std::ofstream(filename) << counter;

        GlobalDeleteAtom(_atom);
    }

private:
    const std::string _id;
    ATOM _atom;
};

int main()
{
    const auto globalCounter = GlobalCounter("test");

    std::cout << "Hello World!\n";

    std::this_thread::sleep_for(std::chrono::seconds(30));

    return 0;
}
#包括
#包括
#包括
#包括
类全局计数器
{
公众:
全局计数器(常量标准::字符串和id)
:_id(id)
{
const auto filename=“C:\\users\\twollgam\\”+id+“.counter”;
if(GlobalFindAtomA(id.c_str())==0)
{

std::ofstream(filename)Remy的实例:

static int counter;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{

    char classname[MAX_PATH] = { 0 };
    GetClassNameA(hwnd,classname, MAX_PATH);
    if (_tcsicmp(classname, (char*)lParam) == 0)
        counter++;
    return true;
}
int Platform::getMulticlientCount(const std::string& ClassName)
{
    counter = 0;
    const char *cstr = ClassName.c_str();
    EnumWindows(EnumWindowsProc, (LPARAM)cstr);
    return counter;
}
如果还需要获取实例,请在
EnumWindowsProc
中:

HINSTANCE instance = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);
如果还需要获取processId,请在
EnumWindowsProc
中:

HINSTANCE instance = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);

“我想按类名(HWND?)而不是进程名来搜索它,但是我该怎么做呢?”-请看
FindWindow/Ex()
,或者
EnumWindows()
GetClassName()
既然这是您的应用程序,为什么不在启动时增加一个计数器,在应用程序退出时减少它?您必须将该计数器保留在共享内存区域中,例如内存映射文件中。或者使用作为一种快速而脏的方式来监视全局状态。如果应用程序终止而不运行析构函数,则此操作将失败(例如崩溃时)。与内核对象的句柄不同,操作系统不会自动释放全局atom表中字符串的引用计数。而且,由于您使用的是全局atom表,因此应确保使用唯一的名称(例如GUID的字符串表示)。