Я не знаю, что не так с моим кодом. Я уже поставил условие, когда дескриптор недействителен. это будет 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;
}
С самого начала не замечу, что ваша функция возвращает wstring - поскольку результатом в return processFileName; было неявное преобразование. но ваша логика с CloseHandle конечно неверна. вам нужен только один звонок CloseHandle, если он не ноль
@RbMm, я все равно не знаю, что ты имеешь в виду. Я снимаю остальную скобу. это все тот же результат. и, как я думаю, если я удалю внутреннюю скобку. как я могу узнать, вернул ли он недопустимый дескриптор.
OpenProcess возвращает либо 0, либо действительный дескриптор. и этот дескриптор не имеет атрибута защиты от закрытия в начале. CloseHandle конечно работает правильно. не закрывать руки не получится. ваш код не работает
@RbMm, так что 0 - это не то же самое NULL в С ++?
0 и NULL конечно же. и что ?
@RbMm причина. Я не понимаю, ты сказал, что не закрывайся, не работай. ваш код не работает.
в вашем коде 3 вызова CloseHandle - начните с удаления 2 из них. и чем использовать отладчик
Не меняйте вопрос после того, как был отправлен ответ на вопрос тот. Если у вас есть новый вопрос, нажмите кнопку Задать вопрос.
@RbMm это уже правильно с логикой, если? когда я использую отладчик, он указывает мне на строку std :: wcout
@IInspectable, я не хочу менять вопрос. но тоже исправлю. если я продолжу ставить новый пробный код. это может?
нет, в вашем конкретном коде логика неверна. и просто воспользуйтесь отладчиком - для пошагового выполнения этой небольшой функции
@RbMm так как же быть? Я не понимаю, что ты говоришь с подсказкой. Я думаю, что это легко исправить, если логика. вызвать только api только там. его легче понять, если вы поместите хотя бы код.
@RbMm причина, слово устное. это имеет много значений, зависящих от того, кто это говорит.
в вашем коде должен быть только вызов один CloseHandle. и использовать отладчик
@RbMm Теперь я понимаю, я думаю, что теперь код должен понравиться. но когда я отлаживаю, он указывает мне на `_Pnext! = Nullptr; * _Pnext = (_Pnext) -> _ Mynextiter)` из xutulity
Прекратите изменять вопрос таким образом, чтобы аннулировать уже опубликованные ответы. Если у вас возник новый вопрос, вы знаете, что делать. Откатил изменения уже в третий раз.
@RbMm я получаю ошибку как в этой ветке. stackoverflow.com/questions/16038954/unhandled-exception-err или. это похоже на неудачу возврата здесь.
Это дополнительный вопрос. Эта ошибка проявляется только тогда, когда вы исправляете ошибку, о которой спрашивает этот вопрос. Это вызвано тем, что не все пути управления в вашей функции возвращают значение. Ваш компилятор уже сказал вам об этом. Не игнорируйте предупреждения компилятора.





Компактная версия вашего кода делает ошибку очевидной:
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.
я не знаю, чтобы указать мне, если нить. если ты думаешь, что моя логика неверна. Я просто делаю противоположное условие, но все равно if (hProcess == NULL) {} else {}
внутри фигурной скобки стоит getprocessname.
@IInspectable, пожалуйста, добавьте краткое описание ПОЧЕМУ GetLastError не работает повсеместно для всех Win32 api.
@joh Если вам нужен код ошибки, вы должны вызвать GetLastError немедленно после сбоя вызова. Любой промежуточный звонок может изменить код ошибки.
Отказ не является ни обязательным, ни достаточным. Некоторые API устанавливают последний код ошибки в случае успеха (например, CreateMutex), другие не устанавливают его вообще, даже когда они терпят неудачу (как большинство / все вызовы GDI). Вот что написано в документации: «Вы должны вызвать функцию GetLastError немедленно, когда возвращаемое значение функции указывает, что такой вызов вернет полезные данные». Чтобы найти эту информацию, вам придется обращаться к документации по каждому вызову API.
@RbMm вот что я думаю в случае успеха вернет processName. но когда не удалось. Я не возвращаюсь к wstring. может это так.