DOSCommand (TurboPack) в консольном приложении

Можно ли использовать компонент TurboPack/DOSCommand в приложении C++Builder Console?

Мотивация. Я пытаюсь создать консольный конверт для старой 32-битной консольной программы MS-DOS, которая правильно работает в Windows 10. пытаюсь перезвонить( OnNewLineсобытие) после звонка Execute()процедура, когда выполняемая команда представляет собой приложение, требующее взаимодействия с пользователем (выбор таких параметров, как " (1) for Save", " (2) for Calc", так далее.).

Я пытаюсь что-то вроде этого, но DOSCommandничего не возвращает:

      //-----------------------------------------------------------------
void __fastcall 
DoNewLine(void *This, System::TObject* ASender, 
const System::UnicodeString ANewLine, TOutputType AOutputType)
{
  if (AOutputType == otEntireLine)
    std::cout << AnsiString(ANewLine).c_str() << std::endl;
}
//-----------------------------------------------------------------
int
_tmain(int argc, _TCHAR* argv[])
{
  try
  {
    TDosCommand* DosCmd = NULL;
    try
    {
      DosCmd = new TDosCommand(NULL);
      DosCmd->CommandLine = "cmd /c \"dir\"";
      DosCmd->CurrentDir  = "C:\\Windows";

      //Set a new line event.
      TMethod m;
      m.Code = &DoNewLine;
      m.Data = NULL; 
      DosCmd->OnNewLine = reinterpret_cast<TNewLineEvent&>(m);

      DosCmd->Execute();

      //Wait? No response.
      Sleep(10000);

    __finally
    {
      if (DosCmd) delete (DosCmd);
    }
  }
  catch (Exception& E)
  {
    std::cout << "Program terminated due to an exception: ";
    std::cout << E.Message.c_str() << std::endl;
  }
  return (0);
}
//-----------------------------------------------------------------

При отладке кода после DosCmd->Execute(), TDosThread.Executeне был выполнен.

Примечание. Если я создаю приложение VCL с основной формой и помещаю эквивалентный код в событие OnClick TButton, DOSCommand работает правильно.

Я использую C++Builder Tokyo и Windows 10 (64-разрядная версия).

Спасибо за любую помощь.

1 ответ

Решено с комментарием Реми Лебо о CheckSynchronize();

      
    //-----------------------------------------------------------------
    void __fastcall
    DoNewLine(void *This, System::TObject* ASender,
    const System::UnicodeString ANewLine, TOutputType AOutputType)
    {
      if (AOutputType == otEntireLine)
        std::cout << AnsiString(ANewLine).c_str() << std::endl;
    }
    //-----------------------------------------------------------------
    int
    _tmain(int argc, _TCHAR* argv[])
    {
      try
      {
        TDosCommand* DosCmd = NULL;
        try
        {
          DosCmd = new TDosCommand(NULL);
          DosCmd->CommandLine = "cmd /c \"dir\"";
          DosCmd->CurrentDir  = "C:\\Windows";
    
          //Set a new line event.
          TMethod m;
          m.Code = &DoNewLine;
          m.Data = NULL;
          DosCmd->OnNewLine = reinterpret_cast<TNewLineEvent&>(m);
    
          DosCmd->Execute();
    
          //Remy's help here.
          while ( DosCmd->IsRunning )
          {
            CheckSynchronize(1000);
          }
    
        __finally
        {
          if (DosCmd) delete (DosCmd);
        }
      }
      catch (Exception& E)
      {
        std::cout << "Program terminated due to an exception: ";
        std::cout << E.Message.c_str() << std::endl;
      }
      return (0);
    }
    //-----------------------------------------------------------------

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