2

我正在维护某人退休前编写的代码这意味着我找不到他们来提问。:-) 这基本上是一个用于启动程序的 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 语句,但它是由 GetExitCodeProcess 设置的 dwExitCode 的值,它不包含预期的内容。由于我们对此进行了错误检查,因此我们将其中一些运行标记为不完整,而实际上它们都很好。

有什么方法可以将此值设置为与进程退出代码不同的值?和/或是否有一个我可以同时运行的实用程序来确认退出代码是我认为的?

谢谢!

ETA: 刚刚意识到这是将内部程序调用放在 .bat 文件中 - “C:\\ --flags etc...”,然后在第二个参数中将其作为命令行调用,而不是直接使用lp应用程序名称。不知道这是否有所作为!但是当我打印进程的 PID 时,我可以看到它是 cmd.exe 进程的 PID,然后我们的程序有一个子 PID。但是,当我在 Process Monitor 中进行跟踪时,我可以看到父母和孩子都以退出代码 0 退出。

4

1 回答 1

3

找到了!应用程序本身实际上返回了 0 错误代码……它周围的 shell 返回了 1。这是由于第二个参数中的 .bat 文件。该名称是从时间生成的,因此如果多个实例过于紧密地一起运行,它最终会成为完全相同的名称。这就是内部应用程序运行良好的原因……那里总是有一个具有该名称的 bat 文件。但是据我所知,当不同的实例试图生成或清理蝙蝠时,会发生访问冲突。

作为一个概念验证黑客,我只是将当前 PID 添加到文件名的末尾,并且一切正常。现在我只需要决定真正的修复,我认为这可能会完全摆脱整个 bat 文件机制并直接调用应用程序。

哇!谢谢各位的帮助!可悲的是,我包含的那段代码没有违规行,但上面每个人的提示帮助我缩小了问题的范围。:-)

于 2013-06-04T01:22:12.363 回答