Заметки / Выполнение программ в DOSBox

C++, Утилита
 При попытке выполнить DOS-приложение в современной версии Windows появляется такое сообщение:


Было бы удобно, если бы система перенаправляла обращения к DOS-файлам в программу, которая их понимает, например DOSBox. Это невозможно, но ничто не мешает переименовать тип файла и проассоциировать его с программой, отдающей файл в DOSBox. Вот как выглядит эта программа:
 FILE *file;
 int i, dir_l=0, size;
 bool bat=false;
 char FilePath [_MAX_PATH], AppDir [_MAX_PATH], cfgPath [_MAX_PATH],
      DOSBoxPath [_MAX_PATH], DOSAppPath [_MAX_PATH], DOSAppDir [_MAX_PATH],
      DOSAppFake [_MAX_PATH], DOSAppExe [_MAX_PATH], RunPath [_MAX_PATH];
 char mess [256], err [32]={"Ошибка"};

 // Находим директорию этой программы
 memset (FilePath, 0, _MAX_PATH);
 GetModuleFileName (NULL, FilePath, _MAX_PATH);
 for (i=_MAX_PATH-1; i>=0 && dir_l==0; i--)
 {
  if (FilePath [i]=='\\')
   dir_l=i+1;
 }
 for (i=0; i<dir_l; i++)
  AppDir [i]=FilePath [i];

 // ...и "config.txt"
 memset (cfgPath, 0, _MAX_PATH);
 memcpy (cfgPath, AppDir, dir_l);
 strcat (cfgPath, "data\\config.txt");

 // Считываем путь к "DOSBox.exe"
 file=fopen (cfgPath, "rb");
 if (file!=NULL)
 {
  fgets (DOSBoxPath, _MAX_PATH, file);
  fclose (file);
 }

 // Проверяем существование файла
 file=fopen (DOSBoxPath, "rb");
 if (file!=NULL)
 {
  fclose (file);

  if (lpszArgument [0]==0)// если передан аргумент
  {
   char mess_ar [5] [64]={"Нужен аргумент - файл DOS-программы (.exe, .com, .bat),",
                          "с расширением переименованным в .dos"
                         };
   sprintf (mess, "%s\n%s", mess_ar [0], mess_ar [1]);
   MessageBox (NULL, mess, err, MB_OK);
  }
  else
  {
   // Определяем тип файла DOS-программы
   if (lpszArgument [0]=='...')// аргумент в кавычках
   {
    memset (DOSAppPath, 0, _MAX_PATH);
    for (i=1; i<strlen (lpszArgument)-1; i++)
     DOSAppPath [i-1]=lpszArgument [i];
   }
   else
    sprintf (DOSAppPath, "%s", lpszArgument);
   file=fopen (DOSAppPath, "rb");
   if (file!=NULL)
   {
    fseek (file, 0, SEEK_END);
    size=ftell (file);
    fclose (file);

    // Если длина файла меньше половины килобайта,
    // предположительно это пакетный файл
    if (size<512)
     bat=true;
   }

   // Получаем директорию и имя .dos-файла
   dir_l=0;
   for (i=_MAX_PATH-1; i>=0 && dir_l==0; i--)
   {
    if (DOSAppPath [i]=='\\')
     dir_l=i+1;
   }
   memset (DOSAppDir, 0, _MAX_PATH);
   for (i=0; i<dir_l; i++)
    DOSAppDir [i]=DOSAppPath [i];
   memset (DOSAppFake, 0, _MAX_PATH);
   for (i=dir_l; i<strlen (DOSAppPath); i++)
    DOSAppFake [i-dir_l]=DOSAppPath [i];

   // ...имя .exe-файла
   sprintf (DOSAppExe, "%s", DOSAppFake);
   if (bat)
   {
    DOSAppExe [strlen (DOSAppExe)-3]='b';
    DOSAppExe [strlen (DOSAppExe)-2]='a';
    DOSAppExe [strlen (DOSAppExe)-1]='t';
   }
   else
   {
    DOSAppExe [strlen (DOSAppExe)-3]='e';
    DOSAppExe [strlen (DOSAppExe)-2]='x';
    DOSAppExe [strlen (DOSAppExe)-1]='e';
   }

   // Устанавливаем директорию
   SetCurrentDirectory (DOSAppDir);

   // Копируем .dos-файл в .exe-файл
   CopyFile (DOSAppFake, DOSAppExe, false);

   // Проверяем существование файла
   file=fopen (DOSAppExe, "rb");
   if (file!=NULL)
   {
    fclose (file);

    // Загружаем программу в DOSBox
    sprintf (RunPath, "\"%s\" %s -exit", DOSBoxPath, DOSAppExe);
    system (RunPath);

    // Удаляем временный файл
    DeleteFile (DOSAppExe);
   }
   else
   {
    sprintf (mess, "Не получилось создать исполняемый файл: \"%s\"\n\n", DOSAppExe);
    MessageBox (NULL, mess, err, MB_OK);
   }
  }
 }
 else
 {
  sprintf (mess, "DOSBox не найден. Укажите путь к нему в \"%s\"\n\n", cfgPath);
  MessageBox (NULL, mess, err, MB_OK);
 }


 // Выход
 PostQuitMessage (0);       /* send a WM_QUIT to the message queue */


Для использования утилиты необходимо переименовать расширение DOS-программы в "DOS" и кликнуть по файлу:


Далее нажать на "Ещё приложения", прокрутить список до конца и перейти по ссылке "Найти другое приложение на этом компьютере", после чего выбрать описанную здесь программу для открытия нового типа файлов. Теперь для выполнения любой DOS-программы будет достаточно единожды переименовать её.

Более простой, но менее удобный способ выполнения программ в DOSBox - перетаскивать файл программы на ярлык DOSBox.

Скачать утилиту.