Что нового

IncludeSrc - Вложение исходного кода в скомпилированный скрипт

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 444
Репутация
2 394
Позволяет в будущем извлекать из вашего скомпилированного скрипта исходный код (пока только главный скрипт), используя заданный пароль.
По сути это вкладывается как библиотека в ваш основной скрипт, больше ничего делать не нужно (в смысле никаких обращений к библиотеке).

Некоторые правила (выполнять по порядку):
* Пароль менять у переменной $sPass (чувствителен к регистру).
* Запустить скрипт хотя бы один раз до компиляции (и после каждого изменения в иерархии Includ'ов). Все последующие запуски ничего не поменяют, только если поменялся список #includ'ов.

IncludeSrc.au3:
Код:
#include-once
#OnAutoItStartRegister '__IncludeSrc'

Func __IncludeSrc()
	Local $sPass = 'MyMasterPass'
	
	Local $sOld_WD = @WorkingDir
	FileChangeDir(@ScriptDir)
	
	If Not @Compiled Then
		Local $aIncludes = __IncludeSrc_GetIncludes(@ScriptFullPath)
		Local $sInclude, $sInclude_Rel, $sUDF, $sDirC, $sDirCreate, $sFileI, $sFileInstall
		
		For $i = 0 To UBound($aIncludes) - 1
			;Check if it's an include from AutoIt registry includes dir
			If $aIncludes[$i][2] Then
				ContinueLoop
			EndIf
			
			$sInclude = $aIncludes[$i][0]
			$sInclude_Rel = $aIncludes[$i][1]
			
			If Not $sUDF And StringInStr(FileRead($sInclude), '__FILE_INSTALL_INCLUDE_SRC') Then
				$sUDF = $sInclude
			EndIf
			
			$sDirC = StringRegExpReplace($sInclude, '\\[^\\]+$', '')
			
			;We will not create dir for @ScriptDir :)
			If $sDirC <> @ScriptDir Then
				$sDirC = StringReplace($sDirC, @ScriptDir, "@ScriptDir & '")
				$sDirC = 'DirCreate(' & (@extended ? '' : "'") & $sDirC & "')"
				
				If Not StringInStr($sDirCreate, $sDirC) Then
					$sDirCreate &= $sDirC & @CRLF & @TAB & @TAB & @TAB
				EndIf
			EndIf
			
			$sFileI = "FileInstall('" & StringReplace($sInclude, @ScriptDir & '\', '') & "', " & StringReplace("'" & $sInclude, "'" & @ScriptDir, "@ScriptDir & '") & "', 1)"
			
			If Not StringInStr($sFileInstall, $sFileI) Then
				$sFileInstall &= $sFileI & @CRLF & @TAB & @TAB & @TAB
			EndIf
		Next
		
		If $sUDF Then
			Local $sSrcs = StringStripWS($sDirCreate & "FileInstall(@ScriptFullPath, StringTrimRight(@ScriptFullPath, 3) & 'au3', 1)" & @CRLF & @TAB & @TAB & @TAB & $sFileInstall, 3)
			Local $sRead = FileRead($sUDF)
			Local $aFI_Old = StringRegExp($sRead, _
				'(?sim)^\h*#Region __FILE_INSTALL_INCLUDE_SRC\s+(.*?)\s+^\h*#EndRegion __FILE_INSTALL_INCLUDE_SRC', 3)
			
			If @error Or $aFI_Old[0] <> $sSrcs Then
				$sSrcs = @CRLF & @TAB & @TAB & @TAB & $sSrcs
				
				$sRead = StringRegExpReplace($sRead, _
					'(?sim)(^\h*#Region __FILE_INSTALL_INCLUDE_SRC).*?(^\h*#EndRegion __FILE_INSTALL_INCLUDE_SRC)', _
					'\1' & StringReplace($sSrcs, '\', '\\') & @CRLF & '\2')
				
				Local $hFile = FileOpen($sUDF, 2)
				FileWrite($hFile, StringStripWS($sRead, 3))
				FileClose($hFile)
				
				MsgBox(48, @ScriptName & ' - __IncludeSrc', 'FileInstall for sources was generated, ready for compilation.')
			EndIf
		EndIf
	Else
		If $CmdLine[0] >= 1 And StringRegExp($CmdLine[1], '((?i)/Source):\Q' & $sPass & '\E') Then
			#Region __FILE_INSTALL_INCLUDE_SRC
			#EndRegion __FILE_INSTALL_INCLUDE_SRC
			
			MsgBox(64, @ScriptName, 'Source extracted (to your program''s dir).')
			
			Exit
		EndIf
	EndIf
	
	FileChangeDir($sOld_WD)
EndFunc

Func __IncludeSrc_GetIncludes($sMainSrcFile)
	Local $sMainPath = StringRegExpReplace($sMainSrcFile, '\\[^\\]+$', '')
	Local Static $sInitMainPath = $sMainPath
	
	Local $sRegIncludes = RegRead('HKCU\Software\AutoIt v3\AutoIt', 'Include')
	Local $aRegPaths = StringSplit(($sRegIncludes ? $sRegIncludes : '|'), ';')
	Local $aIncludes = StringRegExp(FileRead($sMainSrcFile), '(?mi)^\h*#include \h*[<"'']([^<>"'']+)[>"'']', 3)
	
	If @error Then
		Return SetError(1, 0, 0)
	EndIf
	
	Local Static $oDict = 0
	Local Static $fRecurseFlag = False
	
	If Not IsObj($oDict) Or Not $fRecurseFlag Then
		$oDict = ObjCreate('Scripting.Dictionary')
		
		If Not IsObj($oDict) Then
			Return SetError(2, 0, 0)
		EndIf
		
		$oDict.CompareMode = 1 ;Text
	EndIf
	
	Local $sPath, $sIncl
	
	For $sIncl In $aIncludes
		$sPath = $sMainPath
		
		;If not exists in Main script's dir, search in includes from AutoIt registry
		If Not FileExists($sPath & '\' & $sIncl) Then
			For $i = 1 To $aRegPaths[0]
				If FileExists($aRegPaths[$i] & '\' & $sIncl) Then
					$sPath = $aRegPaths[$i]
					ExitLoop
				EndIf
			Next
		EndIf
		
		If $oDict.Exists($sPath & '\' & $sIncl) Or Not FileExists($sPath & '\' & $sIncl) Then
			ContinueLoop
		EndIf
		
		$oDict.Add($sPath & '\' & $sIncl, $sIncl)
		
		$fRecurseFlag = True
		__IncludeSrc_GetIncludes($sPath & '\' & $sIncl)
		$fRecurseFlag = False
	Next
	
	Local $aRet[$oDict.Count][3]
	Local $aKeys = $oDict.Keys
	
	For $i = 0 To UBound($aKeys) - 1
		 $aRet[$i][0] = $aKeys[$i]
		 $aRet[$i][1] = $oDict.Item($aKeys[$i])
		 $aRet[$i][2] = Int(StringLeft($aRet[$i][0], StringLen($sInitMainPath)) <> $sInitMainPath)
	Next
	
	Return $aRet
EndFunc


Код:
#include-once
#OnAutoItStartRegister '__IncludeSrc'

Func __IncludeSrc()
	Local $sPass = 'MyMasterPass'
	Local $sUDF = 'Includes\IncludeSrc.au3' ;Relative to @ScriptDir
	
	If Not @Compiled Then
		If Not FileExists(@ScriptDir & '\' & $sUDF) Then
			Return
		EndIf
		
		Local $sRead = FileRead(@ScriptDir & '\' & $sUDF)
		
		If Not StringInStr($sRead, "FileInstall('" & @ScriptName & "'") Then
			Local $hFile = FileOpen(@ScriptDir & '\' & $sUDF, 2)
			FileWrite($hFile, StringRegExpReplace($sRead, "FileInstall\('[^'""]+'", "FileInstall('" & @ScriptName & "'"))
			FileClose($hFile)
		EndIf
		
		Return
	EndIf
	
	If $CmdLine[0] >= 1 And $CmdLine[1] = '/Source:' & $sPass Then
		FileInstall('ScriptName.au3', @ScriptDir & '\Src.au3', 1)
		Exit
	EndIf
EndFunc

Использование:
Код:
#include 'IncludeSrc.au3' ;Достаточно просто вложить библиотеку в основной скрипт
MsgBox(64, @ScriptName, 'Main script.', 0, Default)


После компиляции запускать с командной строкой: /Source:MyMasterPass
Естественно MyMasterPass должен быть ваш, и желательно уникальный для вас (для ваших приложений).

Залил архив IncludeSrc.zip, в нём есть папка Test, запустите Test.bat и увидите результат работы.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 444
Репутация
2 394
Обновил.
Добавил поддержку вложенных #Includ'ов.
Также теперь нужно менять только $sPass, остальное автоматический заменяется.
 
Автор темы Похожие темы Форум Ответы Дата
C Стол заказов 0
Верх