Что нового

Au3Stripper - очистка кода от неиспользуемых функций и переменных

asdf8

Скриптер
Сообщения
564
Репутация
152
AutoIt: 3.3.10.0
Версия: 1.4

Au3Stripper является аналогом одноименной утилиты из SciTE4AutoIt3 и имеет следующие отличительные особенности:
  • Добавлена возможность явно указать путь к AutoIt, который будет использоваться при обработке исходного кода.
  • Значительно увеличена скорость обработки. В режиме склейки исходного кода с подключаемыми файлами и очистки от неиспользуемых функций и переменных разница для небольших файлов составляет примерно пять раз, но это не главное - оригинальный Au3Stripper производит обработку за вполне приемлемое время. Для больших файлов разница может составлять более тридцати раз - и это уже очень ощутимо. Правда, режим PreExpand работает гораздо медленнее, но, во-первых, механизм обработки гораздо более скрупулезный, кроме замен констант их значениями идет последовательное упрощение арифметических, логических и текстовых выражений, а во-вторых, суммарный выигрыш во времени все равно остается очень хорошим.

Описание:
Au3Stripper заменяет в исходном коде скрипта подключаемые файлы их содержимым, производит обработку полученного кода в соответствии заданными параметрами и сохраняет результат в новый файл.

Параметры командной строки:
Также параметры обработки могут быть заданы в скрипте с помощью директивы #preproc Props(Au3Stripper, ... , при отсутствии директив #preproc параметры загружаются из директивы #Au3Stripper_Parameters, но командная строка имеет более высокий приоритет. Путь к обрабатываемому файлу должен быть первым параметром командной строки.
  • /GuiMode - Au3Stripper запускается в оконном режиме (параметр поддерживается только в командной строке).
  • /MergeOnly /MO - эмулируется обработка скрипта AUT2EXE для скомпилированного файла, это позволяет, в случае возникновения в скрипте ошибки, найти правильный номер строки с ошибкой, для получения правильного результата необходимо задать удаление директив #pragma, что возможно только при запуске Au3Stripper в оконном режиме. При наличии этого параметра игнорируются параметры /Strip, /PreExpand и /RenameMinimum.
  • /Strip[=0/1] /S[=0/1] - из кода удаляются неиспользуемые функции и глобальные переменные и константы. Опция по умолчанию включена. Из соображений совместимости параметры /StripOnly, /SO, /SF=1 или /SV=1 включают режим /Strip.
    Замечание: для встроенных AutoIt функций, в которых, в качестве входного параметра, используется имя функции или переменной в виде текста (AdlibRegister, Call и т.д., кроме Execute), правильная обработка возможна только если соответствующий параметр явно задан текстом или текстовым выражением, если параметр содержит переменную или функцию, а также для функции Execute и пользовательских функций, для получения корректного результата нужно воспользоваться директивами #Au3Stripper_Ignore_Funcs или #Au3Stripper_Ignore_Variables
  • /PreExpand[=0/1/2] /PE[=0/1/2] - числовые константы заменяются их значениями, также производится упрощение арифметических и текстовых выражений. Опция по умолчанию выключена. Включение этой опции существенно увеличивает время обработки. При /PE=2 также будут обрабатываться текстовые константы, что может увеличить размер выходного файла. Константы, занесенные в исключения директивами Au3Stripper, не переименовываются. См. замечание для /Strip.
  • /RenameMinimum[=0/1] /RM[=0/1] - имена функций и переменных заменяются более короткими (длинной от двух знаков). Опция по умолчанию выключена. Включение этой опции увеличивает время обработки. Функции и переменные, занесенные в исключения директивами Au3Stripper, не переименовываются. См. замечание для /Strip.
  • /rsln[=0/1] - в основном файле исходного кода (не в подключаемых файлах) заменяет макрос @ScriptLineNumber фактическим номером строки (используется для отладки). Опция по умолчанию выключена. Следует учитывать, что использование макроса в качестве значения по умолчанию пользовательской функции приведет к ошибочному определению номера строки.
  • /ShowConsoleInfo=0/9 /SCI=0/9
    • /SCI=0 - минимальный вывод в консоль - только предупреждения и ошибки.
    • /SCI=9 - (по умолчанию) максимальный вывод в консоль.
  • /NoCheck[=0/1] /NCHK[=0/1] - не производить синтаксическую проверку выходного кода. По умолчанию проверка производится. При отсутствии ошибок Au3Stripper завершается с кодом 1000, что позволяет AutoIt3Wrapper не производить повторную проверку.
  • /AutoIt3Dir="Path" - параметр поддерживается только в командной строке и задает папку с установленным AutoIt, который и будет использоваться.
    Если этот параметр не задан AutoIt будет искаться в следующем порядке:
    • в переменной среды AutoItPath
    • в переменной SciTe AutoIt3Dir
    • на два уровня выше, чем Au3Stripper
  • /CMD - Au3Stripper загружает основные параметры обработки исключительно из командной строки.

Директивы, используемые в скрипте для управления Au3Stripper:
  • #preproc Props(Au3Stripper, ... или #Au3Stripper_Parameters= - задает параметры обработки кода
  • #Au3Stripper_Off - остановить процесс обработки ниже этой линии
  • #Au3Stripper_On - возобновить процесс обработки ниже этой линии
  • #Au3Stripper_Ignore_Funcs= - не удалять и не переименовывать перечисленные функции
  • #Au3Stripper_Ignore_Variables= - не удалять и не переименовывать перечисленные переменные

Пример подключения к SciTE (файл "au3.properties")
Код:
command.12.*.au3="$(autoit3dir)\autoit3.exe" ""$(SciteDefaultHome)\AutoItTools\Au3Stripper.a3x" "$(FilePath)" /GuiMode
command.name.12.*.au3=Au3Stripper Gui
command.subsystem.12.*.au3=0
command.save.before.12.*.au3=1

PS: изначально утилита делалась для моей сборки SciTe, но она должна бы без переделок работать и с другими редакторами.

Файл: Скачать (26.03.2016)

Источник: autoit-script.ru
Автор(ы): asdf8
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Первые тесты оставляют хорошее впечатление. :ok: :beer:
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
что делаю не так? после обработки в скрипте масса ошибок типа
Код:
_ArrayDelete(): undefined function.
_ArrayDelete($90, 0)
~~~~~~~~~~~~~~~~~~~^
 
Автор
A

asdf8

Скриптер
Сообщения
564
Репутация
152
joiner [?]
кончено об абстрактном, другими не занимаюсь.
Скачал файл по ссылке, запустил обработку файла JMPack.au3 - выдало одно предупреждение:
Код:
- Не поддерживаемые параметры функции :: Call($TRAYNOTIFYIDS[$nID][5], $nID, $lParam)
Никаких синтаксических ошибок в коде, после обработки, нет.
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
asdf8
вот поэтому я и спросил, что делаю не так. ты с какими ключами запускал обработку?
AutoIT 3.3.12.0
 
Автор
A

asdf8

Скриптер
Сообщения
564
Репутация
152
joiner [?]
какими ключами запускал обработку?
Перепробовал все режимы.

вот поэтому я и спросил, что делаю не так.
Хотелось бы узнать - что же было сделано? Думаю, так ускорим разбор полетов.


Добавлено:
Сообщение автоматически объединено:

Скорее всего дело в этом:

asdf8 [?]
/AutoIt3Dir="Path" - параметр поддерживается только в командной строке и задает папку с установленным AutoIt, который и будет использоваться.
Если этот параметр не задан AutoIt будет искаться в следующем порядке:
в переменной среды AutoItPath
в переменной SciTe AutoIt3Dir
на два уровня выше, чем Au3Stripper
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
я компилировал твою утилиту и запустил с параметром окна. там указал путь к папке AutoIT
на выходе получил обработанный скрипт. проверка на синтаксис выдала ошибки. ну и, естественно, после компиляции мой код не запустился
 

Вложения

  • Безымянный.jpg
    Безымянный.jpg
    145 КБ · Просмотры: 67
Автор
A

asdf8

Скриптер
Сообщения
564
Репутация
152
Обновил утилиту:
  • Исправлена установка папки AutoIt в оконном режиме
  • В случае отсутствия подключаемых файлов в консоль выводится сообщение и обработка завершается ошибкой.
 
A

Alofa

Гость
asdf8 прошу прощения, но у меня утилита отказывалась работать потому, что так совпало, что ни один из нижеперечисленных критериев поиска не дал результата.
asdf8 сказал(а):
... Если этот параметр не задан AutoIt будет искаться в следующем порядке:
  • в переменной среды AutoItPath
  • в переменной SciTe AutoIt3Dir
  • на два уровня выше, чем Au3Stripper
...
Только после того как сделал так:
Код:
; ...
$sAutoitDir = EnvGet('AutoItPath')
If Not FileExists($sAutoitDir & '\AutoIt3.exe') Then
	$sAutoitDir = RegRead('HKLM\SOFTWARE\AutoIt v3\AutoIt', 'InstallDir')
	If Not FileExists($sAutoitDir & '\AutoIt3.exe') Then
		$sAutoitDir = SciTE_GetProperty('autoit3dir')
		If Not FileExists($sAutoitDir & '\AutoIt3.exe') Then
			$sAutoitDir = StringRegExpReplace(@ScriptDir, '(\\[^\\]+){2}$', '')
			If Not FileExists($sAutoitDir & '\AutoIt3.exe') Then
				ConsoleWrite('!> ' & $lng__2 & ' :: ' & $lng__17 & ' "AutoItPath"' & @CRLF)
				Exit -2
			EndIf
		EndIf
	EndIf
EndIf
; ...
... все получилось.
 
Автор
A

asdf8

Скриптер
Сообщения
564
Репутация
152
Alofa [?]
у меня утилита отказывалась работать потому, что так совпало, что ни один из нижеперечисленных критериев поиска не дал результата
В реестре тоже может не быть нужного параметра или он может не совпадать с нужной версией AutoIt, поэтому и не стал использовать этот вариант. Еще можно передать этот параметр через командную строку.
Главное - чтобы документированные возможности правильно работали.
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
скачал последнюю версию утилиты.
запустил с параметром /GuiMode
Появилось окошко, отметил что надо. На выходе получил работоспособный код.
Запускал из батника.
Далее, в батнике меняю только имя скрипта, ну, чтобы другой код обработать. Окно стриппера не появляется.
И так и сяк - результат нулевой.
asdf8, в чем может быть косяк?Может где-то процесс заклинило?
 
A

Alofa

Гость
joiner сказал(а):
... в чем может быть косяк?
Может быть в пробелах пути к файлу? $CmdLine этого не любит без кавычек.


Добавлено:
Сообщение автоматически объединено:

asdf8 Поздравляю с Гуруизацией Вас :beer:
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
A

Alofa

Гость
OffTopic:
joiner ничуть не сомневаюсь в вашей квалификации. Но мало ли - запарился, не учел чего-нибудь... Всякое бывает.
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
перезагрузил систему - все заработало. где глюк так и не понял. пусть будет у меня в системе.
я обработал исполняемые коды(ссылка в четвертом сообщении темы).
после компиляции размер полученного файла на два МБ меньше получился. это плюс. запуск, как мне показалось, стал быстрее.
проверил работоспособность проги - в основном все ок.
только пропали отображаемые прогрессы упаковки\распаковки.
при упаковке\распаковке запускаются отдельные модули и передают в основной скрипт процент выполнения.
пример модуля до обработки стриппером
Код:
#NoTrayIcon
#include <WinAPIFiles.au3>
#include <UDF\7ZipM.au3>
#include <WindowsConstants.au3>
Opt("GUICloseOnESC", 0)
Opt("MustDeclareVars", 1)
Global $WoT = GUICreate('')
GUISetState(@SW_HIDE, $WoT)
Local $MapFile = _WinAPI_OpenFileMapping('DataExchangeFile')
If $MapFile = 0 Then Exit
Local $PosFile = _WinAPI_MapViewOfFile($MapFile)
If $PosFile = 0 Then Exit
Global $t_Data = DllStructCreate('int rto;int total[12];int perc;int exit;int err', $PosFile)
Local $tmpdir = @TempDir & '\tmp'
Local $arc = $tmpdir & '\tmp.bin'
Local $rto = DllStructGetData($t_Data, 'rto')
Local $ftmp = $tmpdir & '\res_mods'
Global $Total = DllStructGetData($t_Data, 'total')
Global $fls, $PC, $iWS, $perc, $flag
_7ZipStartup()
_7ZipSetOwnerWindowEx($WoT, "_ARCHIVERPROC")
$flag = 1
_7ZipAdd($WoT, _ANSIToOEM($arc), _ANSIToOEM($ftmp), 1, $rto, 2, 0, 0, '*****')
If @error Then
	DllStructSetData($t_Data, 'err', 1)
	Exit
EndIf
_7ZipAdd($WoT, _ANSIToOEM($arc), _ANSIToOEM($tmpdir & '\'), 1, $rto, 0, '*.jmp;*.jpg;*.mp3;*.png', 0, '*****')
If @error Then
	DllStructSetData($t_Data, 'err', 1)
	Exit
EndIf
_7ZipAdd($WoT, _ANSIToOEM($arc), _ANSIToOEM($tmpdir & '\TTF\'), 1, $rto, 0, '*.ttf', 0, '*****')
If @error Then
	DllStructSetData($t_Data, 'err', 1)
	Exit
EndIf
_7ZipKillOwnerWindowEx($WoT)
_7ZipShutdown()
DllStructSetData($t_Data, 'exit', 1)

Func _ARCHIVERPROC($hWnd, $Msg, $nState, $ExInfo)
	If DllStructGetData($t_Data, 'exit') = 1 Then Exit
	If $nState = 1 Then
		$PC = DllStructCreate($tagINDIVIDUALINFO, $ExInfo)
		$iWS = DllStructGetData($PC, "dwCompressedSize")
		If $flag Then $fls = $iWS
		$perc = Int($fls / $Total * 100)
		DllStructSetData($t_Data, 'perc', $perc)
		Return 1
	EndIf
	If $nState = 2 Then
		If $flag Then
			$flag = 0
			Return 1
		EndIf
		$fls += $iWS
		If $fls = $Total Then DllStructSetData($t_Data, 'perc', 100)
	EndIf
	Return 1
EndFunc   ;==>_ARCHIVERPROC

и после

Код:
#NoTrayIcon
Func _0($0)
	Local $1 = DllStructCreate('int64')
	Local $2 = DllStructCreate('dword;dword', DllStructGetPtr($1))
	DllStructSetData($1, 1, $0)
	Return DllStructGetData($2, 2)
EndFunc   ;==>_0
Func _1($0)
	Local $1 = DllStructCreate('int64')
	Local $2 = DllStructCreate('dword;dword', DllStructGetPtr($1))
	DllStructSetData($1, 1, $0)
	Return DllStructGetData($2, 1)
EndFunc   ;==>_1
Func _2($3, $4 = 0, $5 = 0, $6 = 0x0006)
	Local $7 = DllCall('kernel32.dll', 'ptr', 'MapViewOfFile', 'handle', $3, 'dword', $6, 'dword', _0($4), 'dword', _1($4), 'ulong_ptr', $5)
	If @error Then Return SetError(@error, @extended, 0)
	Return $7[0]
EndFunc   ;==>_2
Func _3($8, $6 = 0x0006, $9 = False)
	Local $7 = DllCall('kernel32.dll', 'handle', 'OpenFileMappingW', 'dword', $6, 'bool', $9, 'wstr', $8)
	If @error Then Return SetError(@error, @extended, 0)
	Return $7[0]
EndFunc   ;==>_3
Global $a = "7-zip32.dll"
Global $b = @ScriptDir & "\"
Global $c = @TempDir & "\"
Global $d
Global $e = 0
Func _4()
	If Not @Compiled Then
		If Not FileExists($b & $a) Then Return SetError(2, 0, 0)
		$e = DllOpen($b & $a)
	Else
		If Not FileInstall("7-zip32.dll", $c & $a, 1) Then Return SetError(3, 0, 0)
		$e = DllOpen($c & $a)
	EndIf
	If $e = -1 Then Return SetError(1, 0, 0)
	Return 1
EndFunc   ;==>_4
Func _5()
	DllClose($e)
	If $d Then DllCallbackFree($d)
	$e = 0
	$d = ""
	If @Compiled Then
		If Not FileDelete($c & $a) Then Return SetError(1, 0, 0)
	EndIf
	Return 1
EndFunc   ;==>_5
Func _6($f, $g, $h, $i = 0, $j = 5, $k = 1, $l = 0, $m = 0, $n = 0, $o = 0, $p = 0, $q = 0)
	Local $r = _d()
	If $r = 0 Then Return SetError(2, 0, 0)
	$g = '"' & $g & '"'
	$h = '"' & $h & '"'
	Local $s = ""
	If $i Then $s &= " -hide"
	$s &= " -mx" & $j
	$s &= _a($k)
	If $l Then $s &= _7($l)
	If $m Then $s &= _b($m)
	If $n Then $s &= " -p" & $n & ' -mhe'
	If FileExists($o) Then $s &= " -sfx" & $o
	If $p Then $s &= " -v" & $p
	If $q Then $s &= " -w" & $q
	Local $t = DllStructCreate("char[32768]")
	Local $7 = DllCall($e, "int", "SevenZip", "hwnd", $f, "str", "a " & $g & " " & $h & " " & $s, "ptr", DllStructGetPtr($t), "int", DllStructGetSize($t))
	If $r = 2 Then _5()
	If Not $7[0] Then Return SetError(0, 0, DllStructGetData($t, 1))
	Return SetError(1, 0, 0)
EndFunc   ;==>_6
Func _7($u)
	If StringInStr($u, ";") Then
		Local $v = StringSplit($u, ";")
		$u = ""
		For $w = 1 To UBound($v) - 1
			If StringInStr($v[$w], "*") Then
				$u &= ' -ir!"' & $v[$w] & '"'
			Else
				$u &= ' -i!"' & $v[$w] & '"'
			EndIf
		Next
		Return $u
	ElseIf StringInStr($u, "*") Then
		Return ' -ir!"' & $u & '"'
	ElseIf StringLeft($u, 1) = "@" Then
		Return ' -i"' & $u & '"'
	Else
		Return ' -i!"' & $u & '"'
	EndIf
EndFunc   ;==>_7
Func _8($f, $x)
	If $e <= 0 Then Return SetError(2, 0, 0)
	If $d Then DllCallbackFree($d)
	$d = DllCallbackRegister($x, "int", "hwnd;uint;uint;ptr")
	If $d = 0 Then Return SetError(1, 0, 0)
	Local $7 = DllCall($e, "int", "SevenZipSetOwnerWindowEx", "hwnd", $f, "ptr", DllCallbackGetPtr($d))
	Return $7[0]
EndFunc   ;==>_8
Func _9($f)
	If $e <= 0 Then Return SetError(2, 0, 0)
	Local $7 = DllCall($e, "int", "SevenZipKillOwnerWindowEx", "hwnd", $f)
	Return $7[0]
EndFunc   ;==>_9
Func _a($u)
	Switch $u
		Case 1
			Return " -r"
		Case 2
			Return " -r0"
		Case Else
			Return " -r-"
	EndSwitch
EndFunc   ;==>_a
Func _b($u)
	If StringInStr($u, "*") Then
		Return ' -x!"' & $u & '"'
	ElseIf StringLeft($u, 1) = "@" Then
		Return ' -x"' & $u & '"'
	Else
		Return ' -x!"' & $u & '"'
	EndIf
EndFunc   ;==>_b
Func _c($y)
	Local $z = DllStructCreate("char[" & StringLen($y) + 1 & "]")
	Local $7 = DllCall("User32.dll", "int", "CharToOem", "str", $y, "ptr", DllStructGetPtr($z))
	If Not IsArray($7) Then Return SetError(1, 0, '')
	If $7[0] = 0 Then Return SetError(2, $7[0], '')
	Return DllStructGetData($z, 1)
EndFunc   ;==>_c
Func _d()
	If $e <= 0 Then
		If _4() Then
			Return 2
		Else
			Return 0
		EndIf
	EndIf
	Return 1
EndFunc   ;==>_d
Opt("GUICloseOnESC", 0)
Opt("MustDeclareVars", 1)
Global $10 = GUICreate('')
GUISetState(@SW_HIDE, $10)
Local $11 = _3('DataExchangeFile')
If $11 = 0 Then Exit
Local $12 = _2($11)
If $12 = 0 Then Exit
Global $13 = DllStructCreate('int rto;int total[12];int perc;int exit;int err', $12)
Local $14 = @TempDir & '\tmp'
Local $15 = $14 & '\tmp.bin'
Local $16 = DllStructGetData($13, 'rto')
Local $17 = $14 & '\res_mods'
Global $18 = DllStructGetData($13, 'total')
_4()
_8($10, "_ARCHIVERPROC")
_6($10, _c($15), _c($17), 1, $16, 2, 0, 0, '*****')
If @error Then
	DllStructSetData($13, 'err', 1)
	Exit
EndIf
_6($10, _c($15), _c($14 & '\'), 1, $16, 0, '*.jmp;*.jpg;*.mp3;*.png', 0, '*****')
If @error Then
	DllStructSetData($13, 'err', 1)
	Exit
EndIf
_6($10, _c($15), _c($14 & '\TTF\'), 1, $16, 0, '*.ttf', 0, '*****')
If @error Then
	DllStructSetData($13, 'err', 1)
	Exit
EndIf
_9($10)
_5()
DllStructSetData($13, 'exit', 1)

и первый и второй код отрабатывают нормально. но второй не дает процент
 
Автор
A

asdf8

Скриптер
Сообщения
564
Репутация
152
joiner [?]
проверил работоспособность проги - в основном все ок.
только пропали отображаемые прогрессы упаковки\распаковки.
При обработке, желательно читать консольный вывод:
Код:
!> Au3Stripper 1 warning(s) :
- Не поддерживаемые параметры функции :: DllCallbackRegister($sProcFunc, "int", "hwnd;uint;uint;ptr")
В общем случае не возможно узнать, что скрывается за $sProcFunc, нужно вручную найти используемые функции и указать в параметре:
Код:
#Au3Stripper_Ignore_Funcs=
 
Верх