c ++ - EnumProcesses - underlig adfærd

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har nogle underlige opførsel, mens du bruger WIndows API-funktion EnumProcesses ()


Jeg har en funktion til at bestemme, hvorvidt en proces med et bestemt navn allerede kører, hvilken levering forskellige resultater, hvis jeg åbner .executable manuelt (dobbeltklik) eller åbner det via shell.


Når jeg åbner den via shell, opdager den, at den kun kører 1 gang (selv), og alt er fint. Når jeg åbner den ved at dobbeltklikke på .exe-filen, returnerer funktionen dog sande (allerede kørende), fordi sløjfen lister mig den samme proces to gange.


For følgende kodestykker er det at nævne at:


this->thisExecutableFile


indeholder argv

Bedste reference

(initialiseret fra at køre programmet) for at få det eget procesnavn som du kan se her:


int main(int argc, char* argv[])
{
    ClientUpdate* update = ClientUpdate::getInstance();
    update->setThisExecutableFile(argv[0]);
    if (update->clientUpdateProcessIsRunning() == false) {
    ...


Mit mål er at finde ud af, om en anden forekomst af denne proces allerede kører, og i så fald afslutte den.


Her er min kode:


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;
}


Jeg ved, at basisbanen er anderledes, når du bruger dobbeltklik på filen eller kalder den via shell. (shell producerer kun filnavn, mens doubleclick sender hele stien + filnavn til argv

Andre referencer 1

), men jeg fik det problem ved at bruge


boost::filesystem::path p(this->thisExecutableFile);
p.fileName()


Hvilket returnerer det korrekte filnavn (uden sti) i begge tilfælde, jeg har tjekket med udskrivning.


Jeg er temmelig forundret, hvorfor EnumProcesses () returnerer mig den samme fil to gange, når du kalder filen via doubleclick i stedet for shell. Det er ikke gydning to behandlet og i taskmanager Jeg kan ikke se noget som dette heller.


Er det en fejl eller jeg skal vide noget om den metode, jeg ikke kunne finde i docs?

Andre referencer 2


Takket være hint af Richard Critten var jeg i stand til at ordne det. Min metode er meget mindre nu og lettere. (Også sandsynligvis også meget mere effektiv og scanner hele processtakken.): D


Her er løsningen


bool ClientUpdate::clientUpdateProcessIsRunning()
{

    HANDLE hMutex = CreateMutexA(NULL, TRUE, "client-updater-mtx");
    DWORD dwErr = GetLastError();
    return dwErr == ERROR\_ALREADY\_EXISTS;
}


Tak!