1

Тема: AHK: CMD StdOut проблемы с кодировкой параметров

Общий привет.
Нужно как-то создавать папку (и другие операции), сейчас это не работает, русская кодировка теряется. В общем нужно как-то передавать параметры в правильной кодировке. Вот тестовый код:


s := "__тест_test"

MsgBox, % StdOut("cmd.exe /u /q /c mkdir ""C:\temp\" . s . """ ", "cp866") ; not work
MsgBox, % StdOut("cmd.exe /a /q /c mkdir ""C:\temp\" . s . """ ", "cp866") ; not work


StdOut(sCmd, encoding)
{
   static STARTF_USESTDHANDLES := 0x100, CREATE_NO_WINDOW := 0x08000000

   DllCall("CreatePipe", PtrP, hStdInRd, PtrP, hStdInWr, UInt, 0, UInt, 0)
   DllCall("CreatePipe", PtrP, hStdOutRd, PtrP, hStdOutWr, UInt, 0, UInt, 0)
   DllCall("SetHandleInformation", Ptr, hStdInRd, UInt, 1, UInt, 1)
   DllCall("SetHandleInformation", Ptr, hStdOutWr, UInt, 1, UInt, 1)

   VarSetCapacity(pi, A_PtrSize*2 + 8, 0)
   NumPut( VarSetCapacity(      si, A_PtrSize*4 + 4*8 + A_PtrSize*5, 0), si )
   NumPut(STARTF_USESTDHANDLES, si, A_PtrSize*4 + 4*7)
   NumPut(hStdInRd            , si, A_PtrSize*4 + 4*8 + A_PtrSize*2)
   NumPut(hStdOutWr           , si, A_PtrSize*4 + 4*8 + A_PtrSize*3)
   NumPut(hStdOutWr           , si, A_PtrSize*4 + 4*8 + A_PtrSize*4)

   DllCall("CreateProcess", UInt, 0, Ptr, &sCmd, UInt, 0, UInt, 0, Int, True, UInt, CREATE_NO_WINDOW, UInt, 0, UInt, 0, Ptr, &si, Ptr, &pi)

   for k, v in [NumGet(pi, 0), NumGet(pi, A_PtrSize), hStdOutWr, hStdInRd, hStdInWr]
      DllCall("CloseHandle", Ptr, v)

   VarSetCapacity(sTemp, 4095)
   while DllCall("ReadFile", UInt, hStdOutRd, Ptr, &sTemp, UInt, 4095, UIntP, nSize, UInt, 0)
      sOutput .= StrGet(&sTemp, nSize, encoding)
   DllCall("CloseHandle", Ptr, hStdOutRd)
   Return sOutput
}

Дополнительно сообщаю, что использую системы windows 7-10 x64, autohotkey x64 unicode 1.1.30.00, сами файлы скриптов в кодировке utf-8. Скритов таких много и все работало хорошо, пока не стали использовать русские буквы в названиях файлов\каталогов, поэтому, жеталательно, простое, ясное и однозначное решение вопроса, чтобы там все не переделывать.

2

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Нужно получать вывод команд в гуи и распарсить. Так что, спасибо, но мне это не совсем подходит, вы лучше подумайте как в моем способе сделать.

3

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Поставьте русскую системную локаль.

4

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Спасибо, но можно это сделать средствами ahk?

5

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Смотрел на зарубежных форумах, там, вроде, использут функции StrPut()/StrGet(), но что-то я не понимаю как это использовать, в документации написано не совсем понятно и примеры на форумах какие-то неясные, запутанные.

6

Re: AHK: CMD StdOut проблемы с кодировкой параметров

У меня ваш код работает и на 7, и на 10, оба варианта.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Кстати да, проверил и обнаружил, что не работает на системах, где изначально была английская версия windows, куда позднее был установлен русский пакет. CHCP сообщает: codepage 866. Такие дела.
teadrinker круто, а у меня не работает, может вы сможете помочь, как разбирающийся товарищ.
stealzy если нет других вариантов.

8

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Нет

9

Re: AHK: CMD StdOut проблемы с кодировкой параметров

upsi_daezium пишет:

CHCP сообщает: codepage 866

Это у всех так по умолчанию. Вряд ли смогу помочь, нет такого опыта.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

10

Re: AHK: CMD StdOut проблемы с кодировкой параметров

teadrinker sad. Вы говорили, что у вас все сразу работает, создается папка с правильным именем?

11

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Да, и на 7, и на 10, в любом варианте:

s := "__тест_test"

MsgBox, % StdOut("cmd.exe /u /q /c mkdir ""C:\temp\" . s . """ ", "cp866") ; not work
MsgBox, % StdOut("cmd.exe /a /q /c mkdir ""C:\temp\" . s . """ ", "cp866") ; not work
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12

Re: AHK: CMD StdOut проблемы с кодировкой параметров

upsi_daezium пишет:

Спасибо, но можно это сделать средствами ahk?

Конечно можно.
Посмотрите, что меняется в реестре при изменении локали и повторите тоже самое.

13

Re: AHK: CMD StdOut проблемы с кодировкой параметров

teadrinker так, а у вас какая система\версия\локаль??
Malcev насчет реестра не уверен, что надо туда лезть.

Путем копания забугорных форумов, нашел один участок кода, применил методом тыка и вот что получилось:


s := "__тест_test" ; __тест_test

vText := s ; вот, собственно, этот код
vSize := StrPut(vText, "CP1251") ; с указанием этой кодировки все работает
VarSetCapacity(vTemp, vSize)
StrPut(vText, &vTemp, "CP1251") ; и тут
s := StrGet(&vTemp, "UTF-8") ; а здесь уже ЮТФ-8 нужно указать
MsgBox, % s ; ok

MsgBox, % StdOut("cmd.exe /u /q /c mkdir ""C:\temp\" . s . s . """ ", "") ; now ok
MsgBox, % StdOut("cmd.exe /a /q /c mkdir ""C:\temp\" . s . """ ", "cp866") ; now ok
MsgBox, % StdOut("cmd.exe /a /q /c dir ""C:\temp\"" ", "cp866") ; cool


StdOut(sCmd, encoding)
{
   static STARTF_USESTDHANDLES := 0x100, CREATE_NO_WINDOW := 0x08000000

   DllCall("CreatePipe", PtrP, hStdInRd, PtrP, hStdInWr, UInt, 0, UInt, 0)
   DllCall("CreatePipe", PtrP, hStdOutRd, PtrP, hStdOutWr, UInt, 0, UInt, 0)
   DllCall("SetHandleInformation", Ptr, hStdInRd, UInt, 1, UInt, 1)
   DllCall("SetHandleInformation", Ptr, hStdOutWr, UInt, 1, UInt, 1)

   VarSetCapacity(pi, A_PtrSize*2 + 8, 0)
   NumPut( VarSetCapacity(      si, A_PtrSize*4 + 4*8 + A_PtrSize*5, 0), si )
   NumPut(STARTF_USESTDHANDLES, si, A_PtrSize*4 + 4*7)
   NumPut(hStdInRd            , si, A_PtrSize*4 + 4*8 + A_PtrSize*2)
   NumPut(hStdOutWr           , si, A_PtrSize*4 + 4*8 + A_PtrSize*3)
   NumPut(hStdOutWr           , si, A_PtrSize*4 + 4*8 + A_PtrSize*4)

   DllCall("CreateProcess", UInt, 0, Ptr, &sCmd, UInt, 0, UInt, 0, Int, True, UInt, CREATE_NO_WINDOW, UInt, 0, UInt, 0, Ptr, &si, Ptr, &pi)

   for k, v in [NumGet(pi, 0), NumGet(pi, A_PtrSize), hStdOutWr, hStdInRd, hStdInWr]
      DllCall("CloseHandle", Ptr, v)

   VarSetCapacity(sTemp, 4095)
   while DllCall("ReadFile", UInt, hStdOutRd, Ptr, &sTemp, UInt, 4095, UIntP, nSize, UInt, 0)
      sOutput .= StrGet(&sTemp, nSize, encoding)
   DllCall("CloseHandle", Ptr, hStdOutRd)
   Return sOutput
}

Просьба проверить как у вас работает и, если кто разберется, написать как это конкретно работает.

14

Re: AHK: CMD StdOut проблемы с кодировкой параметров

upsi_daezium пишет:

Malcev насчет реестра не уверен, что надо туда лезть.

А что по вашему делает смена локали, да и любые другие настройки виндовс?
Я на всех машинах всегда ставлю русскую локаль - никогда проблем не было.
ИМХО сейчас вы здесь будете использовать костыли, а потом знаки вопроса/кракозябры появятся в другой программе не поддерживающей юникод.

15

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Хорошо, Malcev, давайте посмотрим в эту сторону. Я тут поискал немного и вот что нашел:


Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage

Это ветвь реестра, где, видимо, и хранятся эти параметры. Если я правильно понял, это это ACP, OEMCP (у меня соотвтсвенно значения 1251 и 866).
У вас, вероятно, есть какие-то наработки по этому поводу.

16

Re: AHK: CMD StdOut проблемы с кодировкой параметров

stealzy пишет:

Run %comspec% /c mkdir C:\вышобобо,, Hide

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

17

Re: AHK: CMD StdOut проблемы с кодировкой параметров

upsi_daezium пишет:

У вас, вероятно, есть какие-то наработки по этому поводу.

У меня нету.
Если бы мне захотелось сделать такое через реестр, то я бы сделал снимок реестра, потом поменял бы локаль, отрестартился бы и сделал еще раз снимок реестра и сравнил бы их.
Уверен, что там еще добавляются/меняются шрифты.
А вообще можно менять через запуская нужный xml через intl.cpl.

18

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Оказалось, дело было совсем в другом. Напишу здесь, чтобы другие не попали впросак.
Все работало, потом вдруг файлы и папки стали появляться с "кракозяблами", так совпало, что стали писать русские буквы. А у меня редактор для скриптов sublime text 3, я туда пакет поставил editorconfig. И перезаписались настройки сохранения с кодировкой, стало utf-8. А надо то было utf-8 with bom! А обнаружил я это чисто случайно, когда сохранил файл в блокноте и он вдруг сработал как надо.
Короче, пацаны, смотрите внимательно и не расслабляйтесь. Всем спасибо. Тред закрыть.

19

Re: AHK: CMD StdOut проблемы с кодировкой параметров

У меня utf-8 with bom не влияет на StdOut.
Как были в msgbox знаки вопроса при английской локали, так и остаются.

20

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Malcev странно, у меня все заработало. Напишите подробности, я постараюсь проверить.

21

Re: AHK: CMD StdOut проблемы с кодировкой параметров

А какие подробности вас интересуют?
Win7 64 бит Pro английская.
Оригинальная сборка.
Локаль английская.
Файл создаётся с кириллицей, но msgbox от cmd со знаками вопроса.
Если сохранять без bom, то создается файл и показывается сообщение с кракозябрами.
Если поменять локаль на русскую, то кириллица показывается нормально.

22

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Как меняете локаль? Каким скриптом? И что в реестре?

23

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Руками.
http://www.fujitsu.com/global/Images/win7_administrative_tab_tcm100-922542.gif

24

Re: AHK: CMD StdOut проблемы с кодировкой параметров

Пробовал менять руками. Результаты такие, папки все создаются с правильными именами (без кракозябл), а сообщения StdOut тоже правильные.