Форум : WarCraft IIНазвание : Кракозябры вместо русских букв в меню, nls-фикс bat-файл
© 2005 www.runcms.org https://www.war2.ru
URL этой темы
https://www.war2.ru/modules/newbb_plus/viewtopic.php?topic_id=2370&forum=1
|
il : |
28.1.19 13:46 |
Захожу русской версией комбата на сервер, а там в некоторых диалогах bnet - вместо слов "победы", "поражения" и т.п. - кракозябры. Например, в профилях пользователей или прямо при входе.
Проблема старая, распространена много где, в том числе во всяких 1с v7 и прочем. В общем, в старых до-UTF-ных приложениях. Одно из популярных решений - залезть в реестр и выставить c_1251.nls для всех кодировок. Это решение больше не работает, как минимум с windows 7. Зато работает подмена nls-файла в c:\windows\system32\c_1252.nls на c_1251.nls. Конечно, после такой подмены надо перезагрузиться.
Возникла идея встроить эту подмену в русский комбат, чтобы инсталлятор делал это автоматически. Соответственно, нужен скрипт.
Решение конечно спорное: как минимум, это испортит такие же старые до-UTF-ные приложения на других языках, которые не русский и не английский, которые используют этот самый c_1252.nls. Но русскоязычные пользователи, думаю, в большинстве своем, такую порчу переживут. Наоборот, спасибо может быть скажут: многие другие старые русские приложения могут заработать.
В общем, выкладываю скрипт на всеобщее обозрение. Получилось неожиданно много кода, но аккуратно иначе не сделать. На windows 7 и 10 работают, на windows xp не проверял! Заодно, может быть, кто-нибудь подскажет, может, можно как-то починить русские буквы в вар2 не подменяя nls глобально по всей системе?
Цитата: @echo off
set SRC_SHORT_FILENAME=C_1251.NLS set SRC_FILE="%windir%\System32\%SRC_SHORT_FILENAME%" set DST_SHORT_FILENAME=C_1252.NLS set DST_DIR=%windir%\System32 set DST_FILE="%DST_DIR%\%DST_SHORT_FILENAME%" set DST_BACKUP_SHORT_FILENAME="%DST_SHORT_FILENAME%_backup" set ACL_TMPFILE="%tmp%\%DST_SHORT_FILENAME%_acl_%random%"
if not exist %DST_FILE% goto NOTEXIST_ERR
"%windir%\System32\fc.exe" /b %SRC_FILE% %DST_FILE% >nul if ERRORLEVEL 1 goto PERM echo files already similar, nothing to do goto END_NOTHING
:PERM "%windir%\System32\icacls.exe" "%DST_FILE%" /save %ACL_TMPFILE% if ERRORLEVEL 1 goto ACLSAVE_ERR "%windir%\System32\takeown.exe" /F "%DST_FILE%" if ERRORLEVEL 1 goto SETOWNER_ERR "%windir%\System32\icacls.exe" "%DST_FILE%" /grant "%username%":(D) if ERRORLEVEL 1 goto SETPERM_ERR ren "%DST_FILE%" "%DST_BACKUP_SHORT_FILENAME%" if ERRORLEVEL 1 goto REN_ERR copy %SRC_FILE% %DST_FILE% if ERRORLEVEL 1 goto COPY_ERR "%windir%\System32\icacls.exe" "%DST_DIR%" /restore %ACL_TMPFILE% if ERRORLEVEL 1 goto ACLRESTORE_ERR
echo done if exist %ACL_TMPFILE% del %ACL_TMPFILE% goto END_OK
:NOTEXIST_ERR echo file not exist: %DST_FILE% goto END_NOTHING :ACLSAVE_ERR echo error saving permissions: %DST_FILE% to file: %ACL_TMPFILE% goto END_NOTHING :SETOWNER_ERR echo error changing owner to "%username%": %DST_FILE% goto END_DELTMP :SETPERM_ERR echo error setting permissions: %DST_FILE% goto END_DELTMP :REN_ERR echo error renaming file: %DST_FILE% to %DST_SHORT_FILENAME% goto END_DELTMP :COPY_ERR echo error copying file: %SRC_FILE% to %DST_FILE% rem if not exist %DST_FILE% ren "%DST_DIR%\DST_BACKUP_SHORT_FILENAME" "%DST_SHORT_FILENAME%" goto END_NOTHING :ACLRESTORE_ERR echo error restoring permissions: %DST_FILE% from file: %ACL_TMPFILE% goto END_OK
:END_DELTMP if exist %ACL_TMPFILE% del %ACL_TMPFILE% :END_NOTHING exit /b 0 :END_OK echo if you appeared here, that means you should reboot your computer to take effect exit /b 1
Это все надо запускать как bat-файл, в режиме администратора, после успешной замены файла надо перезагрузиться.
Что делает скрипт: просто заменить файл нельзя - нет прав, он системный. Сначала меняем владельца на себя, потом, будучи владельцем, разрешаем себе его удалять-переименовывать. Переименовываем, вместо него копируем c_1251.nls на новый получившийся файл - восстанавливаем права "как было", запрещая себе его удалять, чтобы не ослаблять безопасность системы своими действиями. Единственное, что не возвращаем как было - владельца файла, т.к. это невозможно штатными средствами, к сожалению.
При любом сбое - пишет ошибку и завершается, в этом смысле безопасен. Единственный опасный момент: если файл удалось переименовать, но новый не удалось скопировать. При этом система после перезагрузки почувствует себя очень плохо, хотя не очень представляю, как такое может получиться хотя бы теоретически.
Слеши форматирование грызет если его оформить как код, сделал код в виде цитаты. Ну и выложил файл сюда: ftp://war2.ru/war2/utils/c_1252.nls.bat
[ Редактировано il в 28.1.19 12:54 ]
[ Редактировано il в 28.1.19 13:02 ]
[ Редактировано il в 28.1.19 13:04 ]
[ Редактировано il в 28.1.19 13:09 ] | |
|
il : |
30.1.19 03:47 |
Доделал скрипт: 1. сделал отмену изменений (нам же надо не только уметь подменять файл, но и возвращать "как было"). С параметром do - заменить файл, undo - вернуть обратно, без параметров - проверить необходимость изменений. Результат определяется кроме текстовых сообщений по коду возврата. 2. если мы отменяем изменения - логично удалить старые файлы бекапов. Так вот - нюанс в том, что при переименовании какой-то из файлов блокируется. Причем, после переименования файла до перезагрузки заблокирован на удаление файл бекапа, а после перезагрузки - подозреваю, что основной файл c_1252.nls. Значит, надо корректно обрабатывать ошибку удаления файла. Чтобы и в этом случае адекватно работало и переименование файла, и отмена. Или хотя бы возвращало ошибку, ничего не переименовывая. В итоге работает так: при переменовании туда-обратно без перезагрузок - следующее переименование закончится прогнозируемой ошибкой удаления бекап-файла. 3. при отмене изменений, бепакы удалять можно, но очень аккуратно, только при условии, что они действительно бекапы, а не случайно подвернувшиеся файлики с теми же именами. Сравниваем содержимое перед удалением. 4. подумал, что копирование теоретически может быть не выполнено если диск на 100% переполнен. В этом случае, если переименование туда сработало, значит по идее переименование обратно тоже должно сработать. Добавил. 5. весь скрипт сделан в едином стиле, довольно гибко и расширяемо, во всяком случае, самому мне за него не стыдно, хотя и с учетом специфики bat-файла в олдскульном стиле через set и goto.
Цитата: @echo off
set ORIG_SHORT_FILENAME=C_1251.NLS set SYS_DIR=%windir%\System32 set BACKUP_SUFFIX=backup set BACKUP_UNDO_SUFFIX=backup_undo
set DST_SHORT_FILENAME=C_1252.NLS set DST_FILE="%SYS_DIR%\%DST_SHORT_FILENAME%" set ACL_TMPFILE="%tmp%\%DST_SHORT_FILENAME%_acl_%random%"
if "_%1" == "_undo" goto UNDO if "_%1" == "_do" goto DO "%windir%\System32\fc.exe" /b "%SYS_DIR%\%ORIG_SHORT_FILENAME%" %DST_FILE% >nul if ERRORLEVEL 1 exit /b 1 echo files are similar, nothing to do goto END_NOTHING :DO set DST_BACKUP_SHORT_FILENAME=%DST_SHORT_FILENAME%_%BACKUP_SUFFIX% set SRC_SHORT_FILENAME=%ORIG_SHORT_FILENAME% set SRC_FILE="%SYS_DIR%\%SRC_SHORT_FILENAME%" goto START_DEL_OLD :UNDO set DST_BACKUP_SHORT_FILENAME=%DST_SHORT_FILENAME%_%BACKUP_UNDO_SUFFIX% set SRC_SHORT_FILENAME=%DST_SHORT_FILENAME%_backup set SRC_FILE="%SYS_DIR%\%SRC_SHORT_FILENAME%" goto START_DEL_OLD :START_DEL_OLD if not exist "%SYS_DIR%\%DST_BACKUP_SHORT_FILENAME%" goto START echo file "%SYS_DIR%\%DST_BACKUP_SHORT_FILENAME%" exist, comparing "%windir%\System32\fc.exe" /b "%SYS_DIR%\%DST_BACKUP_SHORT_FILENAME%" %DST_FILE% >nul if ERRORLEVEL 1 goto START echo file "%SYS_DIR%\%DST_BACKUP_SHORT_FILENAME%" is similar to %DST_FILE%, deleting del "%SYS_DIR%\%DST_BACKUP_SHORT_FILENAME%"
if exist "%SYS_DIR%\%DST_BACKUP_SHORT_FILENAME%" goto EXIST_AFTER_DEL :START if not exist %SRC_FILE% goto NOTEXIST_SRC_ERR if not exist %DST_FILE% goto NOTEXIST_DST_ERR "%windir%\System32\fc.exe" /b %SRC_FILE% %DST_FILE% >nul if ERRORLEVEL 1 goto PERM echo files already similar, nothing to do set RESULT=nothing goto END_NOTHING :PERM "%windir%\System32\icacls.exe" %DST_FILE% /save %ACL_TMPFILE% if ERRORLEVEL 1 goto ACLSAVE_ERR "%windir%\System32\takeown.exe" /F %DST_FILE% if ERRORLEVEL 1 goto SETOWNER_ERR "%windir%\System32\icacls.exe" %DST_FILE% /grant "%username%":(D) if ERRORLEVEL 1 goto SETPERM_ERR
:REN ren %DST_FILE% "%DST_BACKUP_SHORT_FILENAME%" if ERRORLEVEL 1 goto REN_ERR copy %SRC_FILE% %DST_FILE% if ERRORLEVEL 1 goto COPY_ERR :RESTORE_PERMS "%windir%\System32\icacls.exe" "%SYS_DIR%" /restore %ACL_TMPFILE% if ERRORLEVEL 1 goto ACLRESTORE_ERR :ACLSAVE_DELETE if exist %ACL_TMPFILE% del %ACL_TMPFILE% set RESULT=ok if "_%RESULT%" == "_nothing" goto END_NOTHING if "_%RESULT%" == "_ok" goto END_NOTHING echo Error! result is unknown exit /b 2 goto END_OK :NOTEXIST_DST_ERR echo file not exist: %DST_FILE% goto END_NOTHING :NOTEXIST_SRC_ERR echo file not exist: %SRC_FILE% goto END_NOTHING :EXIST_AFTER_DEL echo file delete failed: "%SYS_DIR%\%DST_BACKUP_SHORT_FILENAME%" goto END_NOTHING :ACLSAVE_ERR echo error saving permissions: %DST_FILE% to file: %ACL_TMPFILE% set RESULT=nothing goto ACLSAVE_DELETE :SETOWNER_ERR echo error changing owner to "%username%": %DST_FILE% set RESULT=nothing goto ACLSAVE_DELETE :SETPERM_ERR echo error setting permissions: %DST_FILE% set RESULT=nothing goto ACLSAVE_DELETE :REN_ERR echo error renaming file: %DST_FILE% to %DST_SHORT_FILENAME%, restoring permissions set RESULT=nothing goto RESTORE_PERMS :COPY_ERR echo error copying file: %SRC_FILE% to %DST_FILE%, renaming back: ren "%SYS_DIR%\%DST_BACKUP_SHORT_FILENAME%" "%DST_SHORT_FILENAME%" ren "%SYS_DIR%\%DST_BACKUP_SHORT_FILENAME%" "%DST_SHORT_FILENAME%" set RESULT=nothing goto RESTORE_PERMS :ACLRESTORE_ERR echo error restoring permissions: %DST_FILE% from file: %ACL_TMPFILE% set RESULT=ok goto ACLSAVE_DELETE
:END_NOTHING exit /b 0 :END_OK echo if you appeared here, that means you should reboot your computer to take effect exit /b 1
| |
|
Dar : |
30.1.19 10:16 |
Ил нам простым смертным нужно что то переустанавливать на своих ПК? Может надо новую версию игры к примеру инсталировать? | |
|
il : |
30.1.19 12:02 |
Переустанавливать ничего не надо, в принципе, можно просто запустить первую версию скрипта (ее достаточно чтобы подменить файл), только это можно делать на виндовс 7-8-10. На XP не тестировал, поэтому не советую.
А лучше пока подождать - это в принципе задел на будущее, которое, надеюсь, скоро настанет. | |
|
Dar : |
30.1.19 12:53 |
Ясно, ну тогда ждемс | |
|
© 2005 www.runcms.org https://www.war2.ru
URL этой темы
https://www.war2.ru/modules/newbb_plus/viewtopic.php?topic_id=2370&forum=1
|