четверг, 6 сентября 2012 г.

Лечим "кракозябры" в консоли сборки Qt Creator под Windows

Добрый день, друзья!

Не понятно? Вот и с Qt Creator'ом так - о чем он там пишет на "русском" в консоли сборки - черт его знает... :-). Хотя здесь только "половина" его вины, а именно нежелание разработчиков "пофиксить" ситуацию, когда вывод вызываемого в консоли mingw32 идет в кодировке ibm866, а сам Qt Creator работает в кодировке cp1251. Конечно, проблемы нет для англоязычных разработчиков (ну и для тех, у кого "локаль" на ПК установлена в одной из вариации "английской"), но что же делать нам, истинным патриотам своего языка? :-) 

На форумах, посвященных Qt, есть несколько тем с означенной проблемой и парочкой возможных путей решения, основная идея которых это замена конфигурационных файлов самого Qt Creator'а перед его компиляцией либо уже пропатчивание готового исполняемого файла. Больше всего решений связано с заменой файла jom.exe, ранее пропатченным одним умельцем b-s-a (например, тут можете ознакомиться более подробно). Хотя это, по сути, справедливо для компилятора от Visual Studio, а у нас тут все же mingw32 :-). 

Поэтому, если Вам не помогли способы описанные на ресурсах указанных выше, предлагаю ознакомиться и с моим решением данной проблемы... "костыльным" решением ... но имеющим право на существование ;-).

Итак, основная идея - заставить командную строку Windows возвращать текст в кодировке cp1251 вместо ibm866. Для этих целей в арсенале самой операционной системы есть такая утилита как chcp.com.  Ее использование весьма тривиальное:
chcp номер_кодировки
Т.е. чтобы сменить кодировку командной строки (cmd.exe) на нужную нам cp1251, достаточно набрать команду:
chcp 1251
Одно плохо - изменения затрагивают только тот "экземпляр" шелла, в котором была набрана команда. Каждый новый "экземпляр" будет иметь кодировку "по-умолчанию" т.е. ibm866. И тут на помощь приходит Чип & Дейл одна замечательная особенность командной строки Windows - возможность задавать команды "автозапуска" (команды которые будут выполнятся при старте каждого "экземпляра" cmd.exe). Собственно это и решает нашу проблему - командная строка возвращает весь поток в нужной нам кодировке. Где же задать эту команду? А все там же - в реестре Windows. 
Ваша задача - найти ветку реестра "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" и создать в ней новый   Расширяемый строковый параметр (тип "reg_expand_sz") "AutoRun", которому присвойте значение "chcp 1251 1>nul". Все. Теперь каждый запуск командной строки Windows будет приводить к выполнению указанной команды "chcp 1251 1>nul" - и нам гарантировано обеспечена нужная кодировка. Правда "кракозябры" уже будут у всех остальных консольных приложений Windows, например, тот же ipconfig - их то вывод так и остался в кодировке ibm866. Можно, конечно, принудительно теперь уже возвращать нужную нам кодировку командой:
chcp 866
но это же "не наш метод" :-). Поэтому предлагаю Вашему вниманию вариант с BAT файлом, где сначала задается нужный нам параметр реестра, затем запускается Qt Creator, а по окончании его работы созданное нами значение реестра "AutoRun" удаляется:
@echo off
reg add "HKCU\Software\Microsoft\Command Processor" /v AutoRun /t reg_expand_sz /d "chcp 1251 1>nul" /f
C:\Qt\qtcreator-2.5.0\bin\qtcreator.exe
reg delete "HKCU\Software\Microsoft\Command Processor" /v AutoRun /f
только строчку с запуском Qt Creator не забудьте заменить на свою.

Можно было бы на этом остановится, но, для любителей эстетики, я хотел бы еще предложить "усовершенствовать" вариант такого запуска Qt Creator'а без навязчивого "черного окна" консоли, "висящего" до окончания работы. И здесь нашим помощником снова становится сама ОС Windows, а точнее Visual Basic Script. Для этого нам будет необходимо создать обычный текстовый файл, при сохранении которого указать расширение "VBS" (и это ОЧЕНЬ важно). Например, у меня это файл - "runme.vbs". А в качестве содержимого указать вот такой код:
set WShell = CreateObject("WScript.shell")
ACode = WShell.Run("cp1251.bat", 0, false)
где, cp1251.bat - имя нашего ранее созданного BAT файла (у Вас оно может быть, конечно же, другим). Ну и самое главное - оба этих файла (BAT и VBS) должны находится в одной директории :-).

Теперь уже точно все, осталось только поменять ярлык для запуска Qt Creator'а с "qtcreator.exe" на созданный нами "runme.vbs" и наслаждаться русскими сообщениями от MinGW :-).

И на последок пару замечаний:
1) учтите, что пока работает Qt Creator запущенный таким образом, каждая новая консоль будет иметь кодировку cp1251;
2) будьте внимательны - Ваши средства защиты могут блокировать запуск файла VBS.

Ну, вроде бы, ничего не забыл - до новых встреч! ;-)

p/s знаете более красивый способ решения проблемы? Обязательно напишите в комментарии :-).

24 комментария:

  1. Спасибо большое, кракозябры исчезли, а консоль после выхода из криэйтора запускается в норм кодировке.

    ОтветитьУдалить
  2. Есть решение проблемы.
    1) Скачиваете исходники jom c http://qt.gitorious.org/qt-labs/jom/ или с помощью git://gitorious.org/qt-labs/jom.git
    2) Находите в них файл \src\app\main.cpp
    3) Заменяете в нём строки
    4) int main(int argc, char* argv[])
    {
    int result = 0;

    на

    int main(int argc, char* argv[])
    {
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    int result = 0;

    5) Далее запускаете командную строку разработчика vs2012(или аналогичное), переходите в корневую папку jom и выполняете команды qmake и nmake. Далее просто копируете файлы из папки %jom%\bin\ в папку %qt-creator%\bin

    Глупо, но работает. И никаких батников не надо(который к тому же мне не помог =( )

    ОтветитьУдалить
    Ответы
    1. Константин, предложенное Вами решение по сути относится к работе с компилятором VS. В заметке же идет речь про MinGW ;-).

      Удалить
  3. Creator запускается, но консоль всё равно заполнен кракозябрами :(

    ОтветитьУдалить
    Ответы
    1. Версия Windows? И в содержании файла ошибка не закралась? :-)

      Удалить
  4. Добрых суток. Сделал все по вашей инструкции, но QtCreator по-прежнему выводит ошибки нераспознаваемой кириллицей. Например:

    C:\Users\mvlab_000\Documents\QtProjects\test\main.cpp:9: ошибка: C2061: бЁ­в ЄбЁзҐбЄ п ®иЁЎЄ : Ё¤Ґ­вЁдЁЄ в®а "QLabel"

    Версия Qt - 5.3.0. Использую Windows 8.1
    По вашей инструкции точно сделал все правильно, т.к. во время работы QtCreator обычные консольные приложения тоже выводят некорректную кодировку.

    ОтветитьУдалить
    Ответы
    1. Доброго времени суток!

      К сожалению у меня нет доступа к Windows 8,чтобы проверить работоспособность решения на ней. Хотя, я не думаю, что в архитектуре 8-ке в этом плане что-то поменялось.

      Т.е. после запуска созданного файла runme.vbs Creator запускается, но кодировка такая же "кривая"?

      Удалить
    2. Та же проблема, только у меня Windows 7. Запускаю runme.vds -> Qt Creator запускается, но с кодировкой так же беда....

      Менял jom.exe на старые и на новые версии, но все равно не помогает (http://download.qt-project.org/)

      Удалить
  5. Замечательное решение сделано неким мастером Gres, см. проект sourceforge.net/projects/qtc-paneencode/ или qtc-paneencode.sourceforge.net/.
    После загрузки бинов и закидывания их в соответствующие поддиректории Tools\QtCreator\ надо пере-войти в Creator и (внимательно посмотрите на скриншоты) в параметрах проекта -> настройках среды -> кодировке панелей -> выбрать кодировку консоли сборки 886.

    Славься Gres!

    Ofigus.

    ОтветитьУдалить
  6. Замечание.
    Gres велик, но этот плагин классно работает применительно к ошибкам компилятора, но ошибки линкера так и остаются в кракозябрах. (И еще в других окнах есть нехорошо.) Например, если приложение запущено, его пытаешься пересобрать, линкер не может записать результат (exe), выдает русскоязычную диагностику, которая "Догадайся мол сам" -- кривая как сволочь.

    Но! Есть исходники плагина. Можно доковывать и перековывать!

    Мне симпатично, что подход правилен -- через плагин.

    Ofigus.

    ОтветитьУдалить
  7. Идеально сработал предложенный выше вариант собрать jom.exe из исходников http://qt.gitorious.org/qt-labs/jom/ , добавив две строчки в main.cpp

    int main(int argc, char* argv[])
    {
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    int result = 0;

    Cборку можно произвести в самом Qt Creator, а не ковыряться в командной строке разработчика vs2012. Проверено на Qt Creator 3.3.0 (MSVC 2013, 64 бита).

    ОтветитьУдалить
  8. jom.exe скомпилированный в кодировке cp1251
    https://yadi.sk/d/95W-59e3s5GLT

    Кидать в папку Tools\QtCreator\bin с заменой старого, мне помогло (компилятор MSVC2015):
    http://image.prntscr.com/image/687648eba52148ed8369b35f5f674932.png

    ОтветитьУдалить
  9. Написал подробную статью как исправить jom файл http://blog.harrix.org/article/5888

    ОтветитьУдалить
  10. Антон
    Ссылка https://git.gitorious.org/qt-labs/jom.git больше не работает
    Исходники jom можно забрать отсюда: http://wiki.qt.io/Jom

    git clone git://code.qt.io/qt-labs/jom.git
    Поправьте в статье.
    Спасибо за Вашу статью.

    ОтветитьУдалить
  11. Можно обойтись только qmake, т.е. правкой .pro файла. По крайней мере с VC++ я эти кракозябры поборол.

    http://blog.mgsxx.com/?p=2979

    ОтветитьУдалить
  12. Под виндой лучше Студии ничего нет! Креатор - недоразумение написанное удолбанным школяром на коленке. вечно с ним проблемы.

    ОтветитьУдалить
  13. А не проще взять и вместо "chcp 1251 >nul" прописать в AutoRun "chcp 437 > null". Тем самым переключив язык вывода на английский тем самым решив проблему сразу во всех компиляторах.

    ОтветитьУдалить
  14. Всем успехов, на момент 07.11.2018 СУМЕЛ ИСПРАВИТЬ крякозябры, поставив в комплекте проекта галочку "Заставлять компилятор MSVC выводить сообщения в UTF-8".
    Версия QtCreator4.7.2(MSVS2015 32бит) на Qt5.11.2 под VS2015 64bit компилятором.

    ОтветитьУдалить
  15. У меня сработал вариант, описанный в http://blog.mgsxx.com/?p=2979
    Надо в pro-файл вставить следующие строки:

    QMAKE_EXTRA_TARGETS += before_build makefilehook

    makefilehook.target = $(MAKEFILE)
    makefilehook.depends = .beforebuild

    PRE_TARGETDEPS += .beforebuild

    before_build.target = .beforebuild
    before_build.depends = FORCE
    before_build.commands = chcp 1251

    ОтветитьУдалить
  16. Если кто то до сих пор мучается с этой проблемой, нашел следующее решение: Control Panel -> Часы и регион -> Региональные стандарты -> Дополнительно -> Там будет опция "Язык программ, не поддерживающих Юникод" -> Изменить язык системы -> там должна быть опция "Бета-версия: Использовать Юникод для поддержки языка во всем мире".

    ОтветитьУдалить