OpenProcess дескриптор недействителен. CloseHandle не работает

Я не знаю, что не так с моим кодом. Я уже поставил условие, когда дескриптор недействителен. это будет CloseHandle. но вроде не работает. этот код пытается получить имя процесса. когда я ввожу, существует PID. он возвращает processName. напротив, когда вход i не существует, PID, например 10000. дескриптор возврата недействителен. и исключение ошибки. но в моем коде я уже поставил условие, когда оно недействительно. он закроет ручку.

    std::wstring GetProcessNameById(DWORD i_processId)
{
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, i_processId);
    if (hProcess != NULL)
    {
        wchar_t processFilePath[MAX_PATH];
        if (GetModuleFileNameExW(hProcess, NULL, processFilePath, MAX_PATH))
        {
            CloseHandle(hProcess);
            wchar_t *processFileName = PathFindFileNameW(processFilePath);
            return processFileName;
        }
        else
        {
            CloseHandle(hProcess);
            SystemErrorMessage();
        }
    }
    else 
    {
        CloseHandle(hProcess);
        SystemErrorMessage();
    }
}

int main()
{
std::wcout << GetProcessNameById(10000);
return 0;
}

@RbMm вот что я думаю в случае успеха вернет processName. но когда не удалось. Я не возвращаюсь к wstring. может это так.

user10670595 18.11.2018 15:47

С самого начала не замечу, что ваша функция возвращает wstring - поскольку результатом в return processFileName; было неявное преобразование. но ваша логика с CloseHandle конечно неверна. вам нужен только один звонок CloseHandle, если он не ноль

RbMm 18.11.2018 16:00

@RbMm, я все равно не знаю, что ты имеешь в виду. Я снимаю остальную скобу. это все тот же результат. и, как я думаю, если я удалю внутреннюю скобку. как я могу узнать, вернул ли он недопустимый дескриптор.

user10670595 18.11.2018 16:05
OpenProcess возвращает либо 0, либо действительный дескриптор. и этот дескриптор не имеет атрибута защиты от закрытия в начале. CloseHandle конечно работает правильно. не закрывать руки не получится. ваш код не работает
RbMm 18.11.2018 16:09

@RbMm, так что 0 - это не то же самое NULL в С ++?

user10670595 18.11.2018 16:10

0 и NULL конечно же. и что ?

RbMm 18.11.2018 16:12

@RbMm причина. Я не понимаю, ты сказал, что не закрывайся, не работай. ваш код не работает.

user10670595 18.11.2018 16:14

в вашем коде 3 вызова CloseHandle - начните с удаления 2 из них. и чем использовать отладчик

RbMm 18.11.2018 16:15

Не меняйте вопрос после того, как был отправлен ответ на вопрос тот. Если у вас есть новый вопрос, нажмите кнопку Задать вопрос.

IInspectable 18.11.2018 16:23

@RbMm это уже правильно с логикой, если? когда я использую отладчик, он указывает мне на строку std :: wcout

user10670595 18.11.2018 16:24

@IInspectable, я не хочу менять вопрос. но тоже исправлю. если я продолжу ставить новый пробный код. это может?

user10670595 18.11.2018 16:25

нет, в вашем конкретном коде логика неверна. и просто воспользуйтесь отладчиком - для пошагового выполнения этой небольшой функции

RbMm 18.11.2018 16:27

@RbMm так как же быть? Я не понимаю, что ты говоришь с подсказкой. Я думаю, что это легко исправить, если логика. вызвать только api только там. его легче понять, если вы поместите хотя бы код.

user10670595 18.11.2018 16:29

@RbMm причина, слово устное. это имеет много значений, зависящих от того, кто это говорит.

user10670595 18.11.2018 16:29

в вашем коде должен быть только вызов один CloseHandle. и использовать отладчик

RbMm 18.11.2018 16:35

@RbMm Теперь я понимаю, я думаю, что теперь код должен понравиться. но когда я отлаживаю, он указывает мне на `_Pnext! = Nullptr; * _Pnext = (_Pnext) -> _ Mynextiter)` из xutulity

user10670595 18.11.2018 16:41

Прекратите изменять вопрос таким образом, чтобы аннулировать уже опубликованные ответы. Если у вас возник новый вопрос, вы знаете, что делать. Откатил изменения уже в третий раз.

IInspectable 18.11.2018 16:52

@RbMm я получаю ошибку как в этой ветке. stackoverflow.com/questions/16038954/unhandled-exception-err‌ или. это похоже на неудачу возврата здесь.

user10670595 18.11.2018 16:56

Это дополнительный вопрос. Эта ошибка проявляется только тогда, когда вы исправляете ошибку, о которой спрашивает этот вопрос. Это вызвано тем, что не все пути управления в вашей функции возвращают значение. Ваш компилятор уже сказал вам об этом. Не игнорируйте предупреждения компилятора.

IInspectable 18.11.2018 17:04
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
19
593
1

Ответы 1

Компактная версия вашего кода делает ошибку очевидной:

if (hProcess != NULL)
{
    // Left out for brevity
}
else 
{
    // Here, hProcess is NULL
    CloseHandle(hProcess);
    SystemErrorMessage();
}

По сути, это вызывает CloseHandle(NULL);, предположительно устанавливая код последней ошибки потока на ERROR_INVALID_HANDLE. SystemErrorMessage(), вероятно, слепо вызывает GetLastError (не оценивая, должен ли он), и выдает исключение, если возвращаемое значение не является ERROR_SUCCESS.

Чтобы это исправить, нужно исправить логическую ошибку (убрать вызов CloseHandle в ветке else, в которой у вас знатьhProcess недействителен). Когда закончите, переработайте всю обработку ошибок. Надежно работать не будет. Вы не можете вслепую вызывать GetLastError в любое время, когда вызов API не удался. Когда закончите с этим, изучите Идиома RAII, чтобы вам не пришлось писать код очистки вручную, как если бы вам приходилось делать с C.

но я думаю, что моя логика верна. как описание, возвращаемое значение OpenProcess. из msdn это Если функция завершается успешно, возвращаемое значение - открытый дескриптор указанного процесса. Если функция не работает, возвращаемое значение - ПУСТО (NULL). Чтобы получить расширенную информацию об ошибке, вызовите GetLastError.

user10670595 18.11.2018 15:42

я не знаю, чтобы указать мне, если нить. если ты думаешь, что моя логика неверна. Я просто делаю противоположное условие, но все равно if (hProcess == NULL) {} else {}

user10670595 18.11.2018 15:57

внутри фигурной скобки стоит getprocessname.

user10670595 18.11.2018 15:58

@IInspectable, пожалуйста, добавьте краткое описание ПОЧЕМУ GetLastError не работает повсеместно для всех Win32 api.

johnathan 18.11.2018 17:10

@joh Если вам нужен код ошибки, вы должны вызвать GetLastError немедленно после сбоя вызова. Любой промежуточный звонок может изменить код ошибки.

Raymond Chen 18.11.2018 20:59

Отказ не является ни обязательным, ни достаточным. Некоторые API устанавливают последний код ошибки в случае успеха (например, CreateMutex), другие не устанавливают его вообще, даже когда они терпят неудачу (как большинство / все вызовы GDI). Вот что написано в документации: «Вы должны вызвать функцию GetLastError немедленно, когда возвращаемое значение функции указывает, что такой вызов вернет полезные данные». Чтобы найти эту информацию, вам придется обращаться к документации по каждому вызову API.

IInspectable 19.11.2018 10:17

Другие вопросы по теме