Что нового

_AU3_GetErrLineCode - не работает в скомпилированном виде

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Оригинал функции ЗДЕСЬ
Собственно, вопрос к автору функции. В теме по ссылке нет возможности задать вопрос
Использую данную функцию для сбора всех включаемых библиотек в один код. Чтобы его можно было компилировать используя только Aut2Exe
В принципе, ничего не менял, только вместо сравнения делаю запись в файл
мой исходный файл, который обрабатывается этой функцией, имеет произвольное название , но с неизменным дополнением: любые четыре символа после основного имени.
пример: MyFile_def.au3. После обработки: MyFile.au3, в этот файл уже записаны все подключаемые библиотечные функции.
При запуске функции _AU3_GetErrLineCode из редактора или через контекстное меню файлов .au3, все работает как надо. Но если код, который я привел ниже, скомпилировать, то он работает частично. В первом случае я имею на выходе файл размером больше мегабайта. Во втором случае килобайт 200 . Просмотрев получаемый код я заметил, что функция переносит все подключаемые пользовательские библиотеки, а библиотеки из каталога установки AutoIt как будто не находит. С чего вдруг?
Код:
#include <WinAPIFiles.au3>

Global $sAutoItExe = @AutoItExe ;Should be 3.3.12.0 / 3.3.9.4 / 3.3.8.X / 3.3.6.X
;Global $sAutoItExe = 'D:\AutoIt_Versions\AutoIt_3.3.12.0\AutoIt3.exe'

Local $sFile = FileOpenDialog('Select script file (source from your compiled script)...', @ScriptDir, 'AutoIt v3 Script (*.au3)')
If @error Then Exit

SplashTextOn('Generating error code line', 'Please wait...', 200, 50, -1, -1, BitOR(16, 32), '', 12, 800)
$sCodeLine = _AU3_GetErrLineCode($sFile)
SplashOff()


Func _AU3_GetErrLineCode($sScript_File, $iLine = 0)
	Local $sSrc_Raw, $iPos1, $iPos2, $iLen

	$sSrc_Raw = _AU3_StripToRaw($sScript_File)

	If @error Then
		Return SetError(1, 0, '')
	EndIf

	$sSrc_Raw = StringStripWS($sSrc_Raw, 3)
	Local $snf = StringTrimRight($sScript_File, 8)
	FileDelete($snf & '.au3')
	FileWrite($snf & '.au3', $sSrc_Raw)
;~ 	$iPos1 = StringInStr($sSrc_Raw, @LF, 2, $iLine - 1)
;~ 	$iPos2 = StringInStr($sSrc_Raw, @LF, 2, $iLine)               | определение строки ошибки
;~ 	$iLen = ($iPos2 > 0 ? $iPos2 - $iPos1 : -1)

;~ 	Return StringStripWS(StringMid($sSrc_Raw, $iPos1, $iLen), 3)
EndFunc   ;==>_AU3_GetErrLineCode

Func _AU3_StripToRaw($sSrcFile)
	If $sSrcFile = '' Or Not FileExists($sSrcFile) Then
		Return SetError(1, 0, 0)
	EndIf

	Local Static $sSrcRaw = ''
	Local Static $sIncludes = '|'

	Local $sInclude = ''
	Local $sScriptDir = StringRegExpReplace($sSrcFile, '\\[^\\]+$', '')
	Local $sRead = FileRead($sSrcFile)

	;!!! Strip comment block here (before checking #include-once)...
	_AU3_StringStripCommentBlocks($sRead)

	If StringRegExp($sRead, '(?mi)^\h*#include-once') Then
		If StringInStr($sIncludes, '|' & $sSrcFile & '|', 2) Then
			$sRead = StringRegExpReplace($sRead, '(?msi)\R?^\h*#include-once.*', '')
		Else
			$sIncludes &= '|' & $sSrcFile & '|'
		EndIf
	EndIf

	Local $aRead = StringSplit(StringStripCR($sRead), @LF)

	For $i = 1 To $aRead[0]
		If StringStripWS($aRead[$i], 8) = '' Or StringRegExp($aRead[$i], '(?i)^\h*(;|#include-once|#pragma\h+compile\()') Then
			ContinueLoop
		EndIf

		_AU3_StringStripComments($aRead[$i])

		If Not StringRegExp($aRead[$i], '(?i)^\h*#include\h+[<"'']') Then
			If StringRegExp($aRead[$i], '_\h*$') Then
				$sSrcRaw &= StringRegExpReplace($aRead[$i], '[_ ]+$', '')
				$i += 1

				While $i <= $aRead[0]
					_AU3_StringStripComments($aRead[$i])
					$sSrcRaw &= StringRegExpReplace($aRead[$i], '[_ ]+$', '')
					If @extended = 0 Then ExitLoop

					$i += 1
				WEnd

				$sSrcRaw &= @CRLF
			Else
				$sSrcRaw &= $aRead[$i] & @CRLF
			EndIf

			ContinueLoop
		EndIf

		$sInclude = _AU3_IncludeToPath($aRead[$i], $sScriptDir)

		If Not @error Then
			$sSrcRaw = _AU3_StripToRaw($sInclude)
		EndIf
	Next

	Return $sSrcRaw
EndFunc   ;==>_AU3_StripToRaw

Func _AU3_IncludeToPath($sInclude, $sScriptDir = @ScriptDir)
	Local $aRegExp, $aRet, $sSYS, $sAU3, $sWorkDir
	Local $iError = 0, $sRet = ''

	$aRegExp = StringRegExp($sInclude, '(?i)^\h*#include\h+(<|"|'')([^>"'']+)(?:>|"|'')\h*(;.*?)?$', 3)

	If UBound($aRegExp) < 2 Then
		Return SetError(1, 0, '')
	EndIf

	$sInclude = $aRegExp[1]

	;Get AutoIt Include folder
	Local Static $sAutoIt_Incl_Dir = StringRegExpReplace($sAutoItExe, '\\[^\\]+$', '') & '\Include'

	;Get User Include folders
	Local Static $aUDL = StringRegExp(RegRead('HKCU\Software\AutoIt v3\AutoIt', 'Include'), '([^;]+)(?:;|$)', 3)

	While 1
		;Check include type 4 (include with full path)
		If Not _WinAPI_PathIsRelative($sInclude) Then
			If FileExists($sInclude) Then
				$sRet = $sInclude
			Else
				$iError = 2
			EndIf

			ExitLoop
		EndIf

		;Set Current & AutoIt Include file
		$sAU3 = $sScriptDir & '\' & $sInclude
		$sSYS = $sAutoIt_Incl_Dir & '\' & $sInclude

		;Check include type 1 and 2 (before user includes check)
		If $aRegExp[0] == '<' Then
			If FileExists($sSYS) Then
				$sRet = $sSYS
				ExitLoop
			EndIf
		ElseIf $aRegExp[0] == '"' Or $aRegExp[0] == "'" Then
			If FileExists($sAU3) Then
				$sRet = $sAU3
				ExitLoop
			EndIf
		EndIf

		;Check include type 3 (search in user includes)
		For $i = 0 To UBound($aUDL) - 1
			$aUDL[$i] &= '\' & $sInclude

			If FileExists($aUDL[$i]) Then
				$sRet = $aUDL[$i]
				ExitLoop 2
			EndIf
		Next

		;Check include type 1 and 2 (after user includes check)
		If $aRegExp[0] == '<' Then
			If FileExists($sAU3) Then
				$sRet = $sAU3
				ExitLoop
			EndIf
		ElseIf $aRegExp[0] == '"' Or $aRegExp[0] == "'" Then
			If FileExists($sSYS) Then
				$sRet = $sSYS
				ExitLoop
			EndIf
		EndIf

		;Include file not found
		$iError = 3
		ExitLoop
	WEnd

	If Not $iError Then
		$sWorkDir = @WorkingDir

		If $sWorkDir <> $sScriptDir Then
			FileChangeDir($sScriptDir)
		EndIf

		$sRet = _WinAPI_GetFullPathName($sRet)

		If @error Or $sRet = '' Then
			$iError = 4
		EndIf

		If $sWorkDir <> $sScriptDir Then
			FileChangeDir($sWorkDir)
		EndIf
	Else
		$sRet = ''
	EndIf

	Return SetError($iError, 0, $sRet)
EndFunc   ;==>_AU3_IncludeToPath

Func _AU3_StringStripCommentBlocks(ByRef $sString)
	Local $aSplit = StringSplit(StringStripCR($sString), @LF)
	Local $iCmntsStart_Count

	$sString = ''

	For $i = 1 To $aSplit[0]
		If StringRegExp($aSplit[$i], '(?i)^\h*#(cs|comments-start)([\h;].*)?$') Then
			$iCmntsStart_Count = 1

			While 1
				If $i + 1 >= $aSplit[0] Then
					ExitLoop
				EndIf

				$i += 1

				If StringRegExp($aSplit[$i], '(?i)^\h*#(cs|comments-start)([\h;].*)?') Then
					$iCmntsStart_Count += 1
					ContinueLoop
				EndIf

				If StringRegExp($aSplit[$i], '(?i)^\h*#(ce|comments-end)([\h;].*)?') Then
					$iCmntsStart_Count -= 1

					If $iCmntsStart_Count <= 0 Then
						ExitLoop
					EndIf
				EndIf
			WEnd

			ContinueLoop
		EndIf

		$sString &= $aSplit[$i] & @CRLF
	Next
EndFunc   ;==>_AU3_StringStripCommentBlocks

Func _AU3_StringStripComments(ByRef $sString)
	Local $aChars = StringSplit($sString, '')
	Local $sOpenStrChar = ''

	For $iChar = 1 To $aChars[0] - 1
		If $sOpenStrChar And $sOpenStrChar = $aChars[$iChar] Then
			If $aChars[$iChar] = $aChars[$iChar + 1] Then
				$iChar += 1
			Else
				$sOpenStrChar = ''
			EndIf

			ContinueLoop
		EndIf

		If Not $sOpenStrChar And ($aChars[$iChar] = '"' Or $aChars[$iChar] = "'") Then
			$sOpenStrChar = $aChars[$iChar]
			ContinueLoop
		EndIf

		If Not $sOpenStrChar And $aChars[$iChar] = ';' Then
			$sString = StringStripWS(StringLeft($sString, $iChar - 1), 2)
			Return
		EndIf
	Next

	If StringRight($sString, 1) = ';' Then
		$sString = StringTrimRight($sString, 1)
	Else
		SetError(1)
	EndIf
EndFunc   ;==>_AU3_StringStripComments
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
joiner
В начале указан $sAutoItExe, после компиляции это становится запускаемым файлом, проблема тут.
Позже поправлю.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Замени строчку:
Код:
Global $sAutoItExe = @AutoItExe

на:
Код:
Global $sAutoItExe = (@Compiled ? (RegRead('HKCU\Software\AutoIt v3\AutoIt', 'InstallDir') & '\AutoIt3.exe') : @AutoItExe)
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
особо не замарачиваясь сделал так
Код:
#include <WinAPIFiles.au3>

Global $sAutoItExe = FileSelectFolder('AutoIT Include', @ScriptDir);папка с библиотеками AutoIT. Пример D:\Include
If @error Then Exit
Local $sFile = FileOpenDialog('Select script file (source from your compiled script)...', @ScriptDir, 'AutoIt v3 Script (*.au3)'); файл для обработки
If @error Then Exit
Local $sStrip_File = FileSaveDialog('Save', @ScriptDir, '(*.*)', 16, 'Strip.au3');Выбор файла для сохранения, если файла нет, то он будет создан. Существующий файл будет перезаписан
If @error Then Exit

SplashTextOn('', 'Please wait...', 200, 50, -1, -1, BitOR(16, 32), '', 12, 800)
$sCodeLine = _AU3_GetErrLineCode($sFile, $sStrip_File)
SplashOff()


Func _AU3_GetErrLineCode($sScript_File, $sStrip_File)
	Local $sSrc_Raw
	$sSrc_Raw = _AU3_StripToRaw($sScript_File)
	If @error Then
		Return SetError(1, 0, '')
	EndIf
	Local $hOpen_SF = FileOpen($sStrip_File, 2)
	If $hOpen_SF = -1 Then Return SetError(2)
	FileWrite($hOpen_SF, $sSrc_Raw)
	FileClose($hOpen_SF)
EndFunc   ;==>_AU3_GetErrLineCode
Все работает
 

Prog

Продвинутый
Сообщения
537
Репутация
65
В HKEY_LOCAL_MACHINE\SOFTWARE нет раздела AutoIt v3.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
На x64 InstallDir и Version хранятся в HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\AutoIt v3\AutoIt
 

Prog

Продвинутый
Сообщения
537
Репутация
65
По этому пути есть InstallDir.
Спасибо.
 
Верх