Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [архив - Часть 2] AutoIt скрипты

Закрытая тема
Настройки темы
[архив - Часть 2] AutoIt скрипты

(*.*)


Сообщения: 36554
Благодарности: 6693


Конфигурация

Профиль | Сайт | Отправить PM | Цитировать


Изменения
Автор: Vadikan
Дата: 27-01-2008
Внимание!
Тема переведена в архивное состояние







(настоятельно рекомендуется к прочтению/поиску)


Руководство к действию по работе c AutoIt.


Сайт программы
Русская справка
Коллекция AutoIt скриптов от Sanja Alone
Коллекция AutoIt скриптов от MSFN (могут быть устаревшие).
Справочник по командам rundll32 (команды запуска диалоговых окон и не только...)

AutoIt скрипты - введение и FAQ (статья содержит вводную информацию по AutoIt, а также ответы на ЧаВо).



Данная тема предназначена для общих вопросов по AutoIt. Вопросы по установке приложений при помощи AutoIt следует задавать в соответствии с правилами форума "Автоматическая установка приложений". Таким образом, если вы хотите узнать как установить Winamp 5.x при помощи AutoIt, то создайте тему [autoit] Winamp 5.х (если таковой еще нет на форуме). Проверить наличие тем можно при помощи поиска или фильтров.
Цитата Vadikan:
В теме уже свыше 500 сообщений и поиск нужной информации в ней усложняется. Есть предложение собрать все решения (скрипты) и разместить их на Wiki по принципу "один скрипт - одна статья wiki", добавляя статьи в категорию Autoit. Речь, в принципе, идет об общих решениях, а не о скриптах для установки конкретной программы. Название статьи, очевидно, должно отражать назначение скрипта. Затем можно в шапке просто разместить ссылки на статьи Wiki.

-------
Канал Windows 11, etc | Чат @winsiders

Это сообщение посчитали полезным следующие участники:

Отправлено: 00:02, 05-02-2006

 

Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Давняя проблема с кодировками...

Есть два критичных вопроса (один критичнее другого ) :

1) Возможно ли написать функцию, которая будет возвращать тип кодировки указанной строки?
К примеру, функция будет именоваться так: _StringGetEncoding(), и возвращать будет в соответствии с кодировкой: ANSI, Unicode, UTF-8, UTF-8 with signature.
2) Как перекодировать строку в UTF-8 with signature кодировку? это нужно для обработки текста разных кодировок, я так понял это единственная кодировка которая справляется с текстом на многих языках.

Дело в том, что мне нужно писать в лог файл, этот лог будет содержать данные, взяты с сети (названия ссылок, заголовок страниц и т.п), но при этом эти данные должны отображаться в моём GUI, для этого я использую функцию _UTF8ToUnicode (см. в примере далее), но когдя я пишу в файл в режиме UTF-8 with signature (FileOpen("log.txt", 129)), то данные пишутся некорректно, т.е если строка на русском, то либо пишет всё что до русских символов + русские символы (и дальше не пишет ), либо вообще не пишет русские символы, точно как показано в примере ниже:

Код: Выделить весь код
;Запишем сначала в файл, чтобы получить строку в кодировке Unicode (строка может быть и в этой кодировке, но проверить я не могу(?))
$hFile = FileOpen(@ScriptDir & "\temp.txt", 34)
FileWrite($hFile, "Some [Тест.txt] and more test" & @CRLF)
FileClose($hFile)
$Line = FileRead(@ScriptDir & "\temp.txt")
FileDelete(@ScriptDir & "\temp.txt")

;Теперь пишем в лог (с UTF-8 with signature кодировкой), текст с русскими символами вообще не пишется :(
$Log_File = @ScriptDir & "\Log.txt"
WriteLog($Log_File, _Utf8ToUnicode($Line))
ShellExecute($Log_File)

Func WriteLog($sFile, $Line)
    Local $hFile = FileOpen($sFile, 129)
    FileWrite($hFile, $Line)
    FileClose($hFile)
EndFunc

Func _Utf8ToUnicode($Utf8String)
    Local $BufferSize = StringLen($Utf8String) * 2
    Local $Buffer = DllStructCreate("byte[" & $BufferSize & "]")
    Local $Return = DllCall("Kernel32.dll", "int", "MultiByteToWideChar", _
        "int", 65001, _
        "int", 0, _
        "str", $Utf8String, _
        "int", StringLen($Utf8String), _
        "ptr", DllStructGetPtr($Buffer), _
        "int", $BufferSize)
    Local $UnicodeBinary = DllStructGetData($Buffer, 1)
    Local $UnicodeHex1 = StringReplace($UnicodeBinary, "0x", "")
    Local $UnicodeString, $UnicodeHex2, $UnicodeHex3
    For $i = 1 To StringLen($UnicodeHex1) Step 4
        $UnicodeHex2 = StringMid($UnicodeHex1, $i, 4)
        $UnicodeHex3 = StringMid($UnicodeHex2, 3, 2) & StringMid($UnicodeHex2, 1, 2)
        $UnicodeString &= ChrW(Dec($UnicodeHex3))
    Next
    $Buffer = 0
    Return $UnicodeString
EndFunc
Это не идеальный пример моей проблеме, в этом примере можно сделать так чтобы всё записывалось как надо, но бывают и посложнее ситуации, с другими кодировками и на других языках.

P.S
Я верю что если найдётся решение для двух этих вопросов, то все мои (и не только) проблемы связанные с кодировками будут решены.

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 01:44, 22-11-2007 | #741



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


Creat0R
Цитата:
Возможно ли написать функцию, которая будет возвращать тип кодировки указанной строки?
в общем случае нет... хотя WinAPI и содержит функцию для проверки строки на "юникодовость", но даже она не дает абсолютно достоверного результата так как применяет некие статистические алгоритмы и не рекомендуется к использованию... собственно поэтому и придумали сигнатуры, чтобы была возможность надежно определить кодировку файла
Цитата:
Как перекодировать строку в UTF-8 with signature кодировку?
из какой кодировки и куда?.. если из ANSI в файл то штатным FileWrite() с флагом 128... если из UTF-8 в файл, то FileWrite() с флагом 16 и предварительной записью сигнатуры в начало файла при его инициализации... или имелось ввиду что-то другое?

И еще - я так и не понял зачем тебе понадобился юникод если ты работаешь только в UTF-8?

Последний раз редактировалось amel27, 22-11-2007 в 08:43.


Отправлено: 08:33, 22-11-2007 | #742


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


amel27,
Цитата:
из какой кодировки и куда?
Из неизвестной, строку получаю с разных источников, именно поэтому мне и нужна функция для определения кодировки.

А строка будет отображаться в ГУИ, и далее записываться в файл. Кстати, юникодная строка в Status Bar'е отображается некоректно, когда таже строка нормально отображается в других элементах гуи... но это не так уж важно.

Цитата:
зачем тебе понадобился юникод если ты работаешь только в UTF-8?
Мне он вообще не нужен, я вообще не понимаю зачем столько кодировок придумали (знаю вроде зачем, но не понимаю ), это строка которую я получаю (программно) с сети, кодировка там бывает разная

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 09:01, 22-11-2007 | #743


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


Creat0R
Цитата:
строку получаю с разных источников
ИМХО единственный выход - копать в сторону параметров самих источников строк, к примеру для файла - сигнатура, для браузера - параметры отображаемой страницы (в меню же есть, значит можно как-то и программно получить кодировку) ну и т. д.

ADD: да, еще надо учитывать особенности API которым производится чтение строк т.е. по ходу передачи строка может неожиданно сменить свою кодировку

Цитата:
Мне он вообще не нужен
тогда зачем _Utf8ToUnicode()?.. Во-первых, твоя функция переводит не в юникод, а в обычный ANSI... Во-вторых, в качестве параметра ты подаешь вместо UTF-8 обычную (ANSI) строку поэтому часть текста, отличная от ASCII интерпретируется неверно.

З.Ы. строго говоря, UTF-8 и UTF-16 имеют одну кодировку (юникодовую) но разное двоичное представление

Последний раз редактировалось amel27, 22-11-2007 в 11:41.

Это сообщение посчитали полезным следующие участники:

Отправлено: 10:40, 22-11-2007 | #744


Аватара для Maza Faka

Ветеран


Сообщения: 604
Благодарности: 133

Профиль | Отправить PM | Цитировать


Как создать одномерный, 24-ёх элементный массив со случайными числами от 1 до 12, которые должны каждый раз располагаться в случайном порядке, причём у каждого числа должна быть пара.
Сделал так:
Код: Выделить весь код
#include <Array.au3>

Global $ImgArray1[12]
RandomArray($ImgArray1)

Global $ImgArray2[12]
RandomArray($ImgArray2)

Global $MainArray[1]

For $i = 0 To 11
    _ArrayAdd($MainArray, $ImgArray1[$i])
    _ArrayAdd($MainArray, $ImgArray2[$i])
Next

$ImgArray1 = 0
$ImgArray2 = 0

_ArrayDisplay($MainArray)

Func RandomArray(ByRef $retArray)
    For $i = 0 To UBound($retArray) -1
        While 1
            $number = Random(1, 12, 1)
            $search = _ArraySearch($retArray, $number)
            If @error Then ExitLoop
            WEnd
            $retArray[$i] = $number
        Next
    EndFunc
, но получилось громоздко и некрасиво, может, кто-нибудь подкинет идею, как можно сделать покрасивее?

Отправлено: 17:17, 22-11-2007 | #745


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Вложения
Тип файла: zip Get_Name_Test.zip
(1.9 Kb, 7 просмотров)

amel27,
Ок, Прикрепляю реальный пример, вывод в гуи, нормально, запись в файл - не нормально .

Обойти можно если использовать функцию кодировки только для показа в ГУИ, но бывают и другие строки (всё зависит от запроса поиска), которые нормально отображатся в ГУИ и без перекодировки, но в файл попадут неверно... вот и не могу найти идеальное решение... как говорится - Catch 22


P.S
Этот код, это часть моего проэкта YouTube Download Center! (исходники и необходимые ресурсы там прилагаются).


Maza Faka
Цитата:
24-ёх элементный массив со случайными числами от 1 до 12, которые должны каждый раз располагаться в случайном порядке
Кажется ты(?) уже задавал точно такой вопрос
И я даже пример вроде привёл (сорри, найти не удалось).

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 00:52, 23-11-2007 | #746


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


Цитата Creat0R:
Прикрепляю реальный пример, вывод в гуи, нормально »
как я себе представляю вывод в юникоде:
Код: Выделить весь код
#include <A3LConstants.au3>

; ...
; Это кусок скрипта между "Case $Get_Button" и "EndSwitch"
            GUICtrlSetData($StatusLabel, "Please wait...")
            $VNameUTF8 = GetName("fQyYG-1nhMA") ;Это видео ролик с YouTube (имя ролика на иврите)
            $VNameUTF16= _Utf8ToUnicode($VNameUTF8) ; Возвращает тип BINARY
            $struUTF16 = DllStructCreate("byte["&BinaryLen($VNameUTF16)&"];byte[2]") ; Структура для UTF-16
            DllStructSetData($struUTF16, 1, $VNameUTF16) ; Заполняем структуру
            GUICtrlSendMsg($Data_Input, $WM_SETTEXT, 0, DllStructGetPtr($struUTF16)) ; Устанавливаем текст контрола
            WriteToLog("Video Name: [" & $VNameUTF8 & "] and data")
            GUICtrlSetData($StatusLabel, "")
; ...

; Функция возвращает тип BINARY
Func _Utf8ToUnicode($UTF8String)
    Local $ret = DllCall("Kernel32.dll", "int", "MultiByteToWideChar", _
        "int", 65001, _
        "int", 0, _
        "str", $UTF8String, _
        "int", -1, _
        "ptr", 0, _
        "int", 0)
    Local $buf = DllStructCreate("byte[" & $ret[0]*2 & "]")
    $ret = DllCall("Kernel32.dll", "int", "MultiByteToWideChar", _
        "int", 65001, _
        "int", 0, _
        "str", $UTF8String, _
        "int", -1, _
        "ptr", DllStructGetPtr($buf), _
        "int", $ret[0])
    Return DllStructGetData($buf, 1)
EndFunc
Цитата Creat0R:
запись в файл - не нормально »
хм, сигнатура должна быть всего одна в начале файла, а у тебя добавляется перед каждой строкой... поэтому лучше не доверять AutoIT и сделать все самому, типа:
Код: Выделить весь код
Func WriteToLog($Line)
    Local $hLogFile, $Log_File = StringTrimRight(@ScriptFullPath, 3) & "log"
    Local $GetDateTime = @HOUR & ":" & @MIN & ":" & @SEC & ", " & @MDAY & "/" & @MON & "/" & @YEAR

        If Not FileExists($Log_File) Then
        $hLogFile = FileOpen($Log_File, 17)
        FileWrite($Log_File, chr(0xEF) & chr(0xBB) & chr(0xBF) & _
        "========================================================================" & @CRLF & _
        "Log File for <" & @ScriptName & "> started at: " & $GetDateTime & @CRLF & _
        "========================================================================" & @CRLF & @CRLF)
    Else
        $hLogFile = FileOpen($Log_File, 17)
    EndIf

    FileWrite($hLogFile, StringToBinary("[" & $GetDateTime & "]" & @CRLF,4))
    FileWrite($hLogFile, StringToBinary(">> ",4) & Binary($Line) & StringToBinary(@CRLF & @CRLF,4))
    FileClose($hLogFile)
EndFunc

Последний раз редактировалось amel27, 23-11-2007 в 07:07. Причина: исправил WriteToLog()

Это сообщение посчитали полезным следующие участники:

Отправлено: 06:24, 23-11-2007 | #747


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


amel27,
Спасибо большое!
С этим примером всё отлично работает, но на самом деле всё намного сложнее, в лог при некоторых обстоятельствах пишется и путь к файлу вместе с именем с сети (скачивается видео с сети), если путь содержит кириллицу, или теже ивритские символы (или вообще и те и другие), то в файле получается полная каша

А также мне будет немного сложно адаптировать подобный метод, GuiCtrlSendMsg() работает с обычными контролями, а что делать со StatusBar к примеру? (не Label) - возможно SendMessage, но опять таки, это не надёжно, StatusBar не полностью поддерживает юникод. А также обновлять данные нужно по несколько раз, в зависимости от отображаемых элементов (там у меня есть динамичная панель которая скрывается опционально)...

Кстати, есть ещё функция StringToUTF() (без API, чистая перекодировка символов), можно попробовать путь кодировать отдельно, а имя с сети отдельно... но вот если бы была функция для определения кодировки строки, то это упростило бы работу намного.

В общем спасибо ещё раз, попробую найти хоть какой то компромис.

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 08:38, 23-11-2007 | #748


Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


Цитата Creat0R:
на самом деле всё намного сложнее »
в любом случае все нужно конвертить в UTF-16 так как это native-кодировка Windows
Цитата Creat0R:
возможно SendMessage, но опять таки, это не надёжно »
имхо это как раз надежней... ну, можно еще "покапать на мозги" разработчикам, может добавят в GUI-функции поддержку текста не только в ANSI, но и в UTF-16 (тип Binary)
Цитата Creat0R:
StatusBar не полностью поддерживает юникод »
можно пример?
Цитата Creat0R:
можно попробовать путь кодировать отдельно, а имя с сети отдельно... но вот если бы была функция для определения кодировки строки »
Ну не может быть такой функции (кроме частных случаев), так что единственный выход я уже озвучивал - скурпулезный учет всех источников и их раздельная кодировка... примерно так я и делал в функции WriteToLog()
Цитата Creat0R:
есть ещё функция StringToUTF() »
хм, у меня еще нет... может версию обновить?

Отправлено: 09:22, 23-11-2007 | #749


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


amel27,
Цитата:
можно пример?
В том скрипте что я прикрепил, замени создание строки состояния (Label) на настоящий StatusBar, и полученное имя видео отобрази в этом статус баре, всё что отобразиться так это ????????.

Цитата:
хм, у меня еще нет
Это самопальная функция - Вот:

Код: Выделить весь код
Func StringToUTF($String)
    Local $sResult = "", $iCode
    Local $VarUTFArr = StringSplit($String, "")

    For $i = 1 To $VarUTFArr[0]
        $iCode = Asc($VarUTFArr[$i])

        Select
            Case $iCode >= 192 And $iCode <= 239
                $VarUTFArr[$i] = Chr(208) & Chr($iCode - 48)
            Case $iCode >= 240 And $iCode <= 255
                $VarUTFArr[$i] = Chr(209) & Chr($iCode - 112)
            Case $iCode = 168
                $VarUTFArr[$i] = Chr(208) & Chr(129)
            Case $iCode = 184
                $VarUTFArr[$i] = Chr(209) & Chr(145)
            Case Else
                $VarUTFArr[$i] = Chr($iCode)
        EndSelect

        $sResult &= $VarUTFArr[$i]
    Next

    Return $sResult
EndFunc

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 13:25, 23-11-2007 | #750



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [архив - Часть 2] AutoIt скрипты

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Открывая 7z архив пишет не удаётся открыть как архив. Можно ли его восстановить? DreDo Хочу все знать 4 01-12-2009 18:54
[Архив - Часть 3] AutoIt скрипты .:[общие вопросы]:. Vadikan AutoIt 1543 18-01-2009 10:46
[Архив - Часть 1.3] AutoIt скрипты biork AutoIt 503 09-06-2007 11:27
[Архив - Часть 1.2] AutoIt скрипты Dirk Diggler AutoIt 505 02-12-2006 11:00
[Архив - Часть 1.1] AutoIt скрипты EgOrus AutoIt 335 04-02-2006 16:58




 
Переход