Я поддерживаю код, написанный кем-то просто до того, как они уйдут на пенсию, что означает, что я не могу найти их, чтобы задавать вопросы. 🙂 Это в основном оболочка C ++ для запуска программы. Часть кода, о которой идет речь, такова:
BOOL bSuccess = CreateProcess(NULL, (char *)strBatFile.c_str(),
NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, strLocalWorkingDir.c_str(), &si, &pi );
if( bSuccess )
{
DWORD dwMillisec = INFINITE;
DWORD dwWaitStatus = WaitForSingleObject( pi.hProcess, dwMillisec );
if( dwWaitStatus == WAIT_OBJECT_0 )
{
DWORD dwExitCode = NULL;
GetExitCodeProcess( pi.hProcess, &dwExitCode );
nRet = (int)dwExitCode;
}
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
}
else
nRet = START_PROCESS_FAILED;
Если одновременно запускается только один экземпляр, он всегда работает нормально. Однако, если несколько запускаются в течение очень короткого периода времени, примерно у половины из них dwExitCode имеет значение 1 вместо 0, даже если процесс не завершается сбоем, а файл журнала, который записывает внутренняя программа, завершается.
Таким образом, чтобы уточнить, процесс всегда запускается нормально, и он всегда входит в операторы if, но это значение dwExitCode, установленное GetExitCodeProcess, которое не содержит ожидаемого. Так как мы проверяем ошибки на этом, мы отмечаем кучу этих прогонов как незавершенные, когда на самом деле все в порядке.
Есть ли способ, которым это значение может быть установлено в нечто иное, чем код завершения процесса? И / или есть ли утилита, которую я мог бы запустить одновременно, чтобы подтвердить, что коды выхода — это то, что я думаю?
Спасибо!
ETA: Просто понял, что это помещает внутренний программный вызов в файл .bat — «C: \\ —flags и т. Д.», А затем вызывает его как командную строку во втором аргументе, а не просто вызывает его напрямую, используя lpApplicationName. Понятия не имею, если это имеет значение! Но когда я печатаю PID процесса, я вижу, что это PID для процесса cmd.exe, и тогда у нашей программы есть дочерний PID. Однако, когда я прослеживаю в Process Monitor, я вижу, что родительский и дочерний выходы завершаются с кодом выхода 0.
Нашел это! Само приложение фактически возвращало код ошибки 0 … это была оболочка вокруг него, которая возвращала 1. И это было связано с тем, что файл .bat во втором аргументе. Имя генерировалось с течением времени, поэтому оно получалось в точности одинаковым, если несколько экземпляров выполнялись слишком близко друг к другу. Вот почему внутреннее приложение будет работать нормально … там всегда был файл bat с таким именем. Но были конфликты доступа, когда разные экземпляры пытались сгенерировать или очистить летучую мышь, насколько я могу судить.
В качестве подтверждения концепции я просто добавил текущий PID в конец имени файла, и все работало отлично. Теперь мне просто нужно решить реальное исправление, которое, я думаю, скорее всего полностью избавится от всего механизма bat-файлов и вызовет приложение напрямую.
Уф! Спасибо всем за помощь! К сожалению, фрагмент кода, который я включил, не содержал оскорбительной строки, но все приведенные выше советы помогли мне сузить проблему. 🙂
Других решений пока нет …