Ich verwende in meinem SciTE ja ein Lua-Skript um den TimeStamp automatisch beim Speichern einzutragen.
Der TimeStamp hat eine durch Property festgelegte Zeile, in der er eingefügt wird.
Wenn ich jedoch ein Skript kompiliere, grätscht der Au3Wrapper ungefragt dazwischen, indem er
a) seine Direktiven im Skript hinterlegt (was ich nicht will und erst nach dem Kompilieren passiert und somit nicht erforderlich ist)
b) Diese Einträge werden einfach an den Skriptanfang gesetzt. Der User hat da andere Vorstellungen? - Ja leck mich, als Wrapper bin ich Chef!
Dadurch wandert natürlich der TimeStamp im Skript unter die Zeilen mit den Wrappereinträgen. Ich kann natürlich nach dem Kompilieren einfach nochmal Speichern und dann wird das mit meinem Lua-Skript korrigiert - viel schöner wäre es doch, wenn man das mittels AutoIt automatisiert. Der Wrapper kann per INI gesteuert werden und enthält einen Schlüssel zum Ausführen danach:
Nun habe ich ein Skript geschrieben, das mittels SciTE-Interface den Pfad der zum Kompilieren in SciTE geöffneten Datei holt, diese Datei in ein Array einliest und im Array die Zeilen an die gewollte Position verschiebt. Das funktioniert auch soweit, wie gewollt.
Jedoch das Rückschreiben in die Datei ist wirkungslos. Ich hatte eigentlich erwartet, dass "Run_After" auch tatsächlich erst nach Beendigung des Wrappers läuft. Aber dem scheint nicht so zu sein. Die letzte Aktion des Wrappers ist, wenn ich dessen Code jetzt richtig verstanden habe, dass die Änderungen, die er intern an einer Tmp-Datei durchführt, im Skript landen und der Inhalt anschließend in den Editor eingefügt wird. Somit sind meine zwischenzeitlichen Änderungen am Skript wieder futsch.
Die Bezeichnung "Run_After" ist somit m.M.n. irreführend und sollte heißen: "Run_After_Compile", ich hatte es nämlich als "Run_After_Wrapper" interpretiert.
Falls ihr aber eine Idee habt, wie man NACH Beendigung des Wrappers automatisch ein Skript startet - lasst hören.
Hier übrigens das Skript:
;-- TIME_STAMP 2021-10-19 09:51:42
#cs
• Au3Wrapper manipulates the file with AutoIt. The SciTE events doesn't work there. TimeStamp doesn't run and is moved by inserting the wrapper region.
• This script runs after the Au3Wrapper, searches the start of the Wrapper region (#pragmas too) and moves all wrapper lines downwards, starting at line behind the TimeStamp
The TimeStamp will moved to its right line from property: "TimeStamp.Type.Line"
• Required:
"\AutoIt3Wrapper\AutoIt3Wrapper.ini"
[Other]
Run_After="C:\CODE\AutoIt\Au3WrapperRunAfter_MoveRegion.exe"
From "Help - SciTE4AutoIt3":
Default AutoIt3Wrapper options can be set in AutoIt3Wrapper.ini which is stored in the %LOCALAPPDATA%\AutoIt v3\SciTE\AutoIt3Wrapper folder
for the Installer version and ...\AutoIt3\SciTE\AutoIt3Wrapper folder for the portable version.
There is an example ini file in the folder to serve as a template:
' This INI sets the Defaults for AutoIt3Wrapper which can be overridden by the Compiler Directives
' Use 1/y for Yes and 0/n for No on options like Run_AU3Check
' See documentation for an explanation on purpose of the fields and their values
' AutoIt section for Aut2Exe and AutoIt3
[Autoit]
Aut2Exe=
Icon=
OutfileType=
Compression=
UseUpx=
' Resource update section
[Res]
Language=
Comment=
Description=
Fileversion=
LegalCopyright=
Field1Name=
Field1Value=
Field2Name=
Field2Value=
[Other]
Run_AU3Check=
AU3Check_Stop_OnWarning=
AU3Check_Parameter=
Run_Before=
Run_After=
TempDir=
ShowProgress=
SciTE_STOPEXECUTE=^{END}
SciTE_RESTART=^!{END}
#ce
#include <File.au3>
#include <WinAPIConv.au3>
#include <WinAPIConstants.au3>
Global $g_SciTECmd
GUIRegisterMsg(74, "MY_WM_COPYDATA") ; $WM_COPYDATA = 74
; die vom Au3Wrapper geänderte Datei muss gelesen werden
; im Editor ist zu diesem Zeitpunkt noch der Inhalt vor der Wrapper-Ausführung
; Pfad der aktuell zum Kompilieren in SciTE geöffneten Datei
Global $sFileCurr = _GetCurrentFile()
; ################ Direkter TEST des Skriptes mit <F5> und einer beliebigen au3-Datei mit Wrappereinträgen & verschobenem TimeStamp
;~ Global $sFileCurr = 'C:\CODE\AutoIt\Test\TestWrapper.au3'
; ################
; in welcher Zeile muss der TimeStamp stehen (ohne Property Eintrag: 1)
Global $propTimeStampLine = _GetProperty('TimeStamp.Type.Line')
If $propTimeStampLine = '' Then $propTimeStampLine = 'au3=1'
Global $iLineTimeStamp = StringRegExp($propTimeStampLine, '(?i)au3=(\d)', 1)[0]
If $iLineTimeStamp < 1 Then $iLineTimeStamp = 1
; die Wrapper-Region soll in die Zeile nach dem TimeStamp verschoben werden
Global $iLineWrapper = $iLineTimeStamp +1
; aktuelle Zeilennummern nach Ausführung des Wrappers
Global $iCurrTimeStamp = Null, $iCurrPragmaStart = Null, $iCurrPragmaEnd = Null, $iCurrWrapperStart = Null
Global $iCurrWrapperEnd = Null, $iCurrInclStart = Null, $iCurrInclEnd = Null
; Einlesen der Datei
Global $aRead
_FileReadToArray($sFileCurr, $aRead, 0)
; Zeilen mit Wrapper Start/End und TimeStamp suchen (Wrapper-Start od. pragma od. "Start added" ist immer in erster Zeile, wenn eingefügt)
For $i = 0 To UBound($aRead) -1
If $iCurrInclStart = Null Then
If StringRegExp($aRead[$i], '^; \*\*\* Start added by AutoIt3Wrapper \*\*\*') Then $iCurrInclStart = $i
EndIf
If $iCurrInclEnd = Null Then
If StringRegExp($aRead[$i], '^; \*\*\* End added by AutoIt3Wrapper \*\*\*') Then $iCurrInclEnd = $i
EndIf
If $iCurrPragmaStart = Null Then
If StringRegExp($aRead[$i], '^#pragma') Then $iCurrPragmaStart = $i
Else
If StringRegExp($aRead[$i], '^#pragma') Then $iCurrPragmaEnd = $i
EndIf
If $iCurrWrapperStart = Null Then
If StringRegExp($aRead[$i], '^#Region ;\*\*\*\* Directives created by AutoIt3Wrapper_GUI \*\*\*\*') Then
$iCurrWrapperStart = $i
EndIf
EndIf
If $iCurrWrapperEnd = Null Then
If StringRegExp($aRead[$i], '^#EndRegion ;\*\*\*\* Directives created by AutoIt3Wrapper_GUI \*\*\*\*') Then
$iCurrWrapperEnd = $i
EndIf
EndIf
If $iCurrTimeStamp = Null Then
If StringRegExp($aRead[$i], '^;-- TIME_STAMP') Then
$iCurrTimeStamp = $i
$sTimeStamp = $aRead[$i]
EndIf
EndIf
; Bedingungen zum schnellstmöglichen Beenden der Suche (Skript wird nicht bis zum Ende durchsucht)
If ($iCurrTimeStamp <> Null And $iCurrWrapperStart <> Null And $iCurrWrapperEnd <> Null) Or _ ; Wrapper-Region und TimeStamp vorhanden
($iCurrPragmaStart <> Null And $iCurrTimeStamp <> Null) Or _ ; Pragma und TimeStamp
($iCurrInclStart <> Null And $iCurrTimeStamp <> Null) Or _ ; Include und TimeStamp
($iCurrTimeStamp <> Null And $iCurrWrapperStart = Null) Or _ ; keine Wrapper-Region eingefügt aber TimeStamp
($iCurrTimeStamp = Null And $iCurrWrapperEnd <> Null And $i > ($iCurrWrapperEnd + $iLineTimeStamp)) Or _ ; Wrapper-Region aber kein TimeStamp
(($iCurrWrapperStart = Null And $iCurrPragmaStart = Null And $iCurrInclStart = Null) And _ ; keine Wrapper/Pragma/Include-Region, kein TimeStamp
$i > $iLineTimeStamp And $iCurrTimeStamp = Null) Then
ExitLoop
EndIf
Next
; der tatsächlich belegte Wrapperbereich
Global $iWrapperStart = $iCurrInclStart <> Null ? $iCurrInclStart : ($iCurrPragmaStart <> Null ? $iCurrPragmaStart : $iCurrWrapperStart)
$iCurrPragmaEnd = $iCurrPragmaEnd <> Null ? $iCurrPragmaEnd : $iCurrPragmaStart
Global $iWrapperEnd = $iCurrWrapperEnd <> Null ? $iCurrWrapperEnd : ($iCurrPragmaEnd <> Null ? $iCurrPragmaEnd : $iCurrInclEnd)
Global $nWrapperLines = $iWrapperStart <> Null ? $iWrapperEnd - $iWrapperStart : 0
If $iWrapperStart = Null Then ; es wurde keine Wrapper-Region eingefügt
Exit
Else
; im Array den Wrapperbereich verschieben
Global $iLineLast = $nWrapperLines + ($iLineWrapper -1)
If $iLineLast < $iCurrTimeStamp Then $iLineLast = $iCurrTimeStamp
Global $aLinesToMove[$iLineLast - $iWrapperEnd]
Global $n = 0
; zu verschiebene Zeile(n) unterhalb Wrapper-Region sammeln
For $i = $iWrapperEnd +1 To $iLineLast
$aLinesToMove[$n] = $aRead[$i]
$n += 1
Next
; Wrapper-Region zeilenweise nach unten verschieben, beim letzten Eintrag beginnen
For $i = $iLineLast To UBound($aLinesToMove) Step -1
$aRead[$i] = $aRead[$i - UBound($aLinesToMove)]
Next
; evtl. Zeile des TimeStamp korrigieren
Switch UBound($aLinesToMove)
Case 1
; alles OK - nur ein Eintrag, das ist der TimeStamp
Case Else
Global $iTmp, $sTmp
$iTmp = $iCurrTimeStamp -$iWrapperEnd -1 ; Index TimeStamp in Array
If $iTmp = $iLineTimeStamp -1 Then ; TimeStamp an richtigem Index
; do nothing
Else
If $iTmp = 0 Then
$sTmp = $aLinesToMove[1]
$aLinesToMove[1] = $aLinesToMove[0]
$aLinesToMove[0] = $sTmp
Else
$sTmp = $aLinesToMove[$iTmp-1]
$aLinesToMove[$iTmp-1] = $aLinesToMove[$iTmp]
$aLinesToMove[$iTmp] = $sTmp
EndIf
EndIf
EndSwitch
; Zeilen bis zum TimeStamp an richtiger Position eintragen
For $i = 0 To UBound($aLinesToMove) -1
$aRead[$i] = $aLinesToMove[$i]
Next
; ############################################################## TEST - nur Anzeige Array-Inhalt
;~ ConsoleWrite('+ =================================================================' & @CRLF)
;~ ConsoleWrite('+ Neuer Array-Inhalt bis incl. der Zeile, in der der TimeStamp war:' & @CRLF)
;~ ConsoleWrite('+ =================================================================' & @CRLF)
;~ For $i = 0 To $iLineLast
;~ ConsoleWrite($aRead[$i] & @CRLF)
;~ Next
; ##############################################################################################
; Datei mit den Änderungen der Reihenfolge aus Array überschreiben
Global $hFileCurr = FileOpen($sFileCurr, 2+128) ; $FO_OVERWRITE (2), $FO_UTF8 (128)
_FileWriteFromArray($hFileCurr, $aRead)
FileClose($hFileCurr)
EndIf
;===============================================================================
; Function Name....: _GetCurrentFile
; Description......: Gibt den Pfad der aktuell im Editor geöffneten Datei zurück
; Parameter(s).....: keine
; Return Value(s)..: Dateipfad
; Author(s)........: BugFix
;===============================================================================
Func _GetCurrentFile()
SendSciTE_Command("askfilename:", 1)
Return StringReplace(StringTrimLeft($g_SciTECmd,StringInStr($g_SciTECmd, ':', 1, 3)), '\\', '\')
EndFunc
;===============================================================================
; Function Name....: _GetProperty
; Description......: Gibt den Wert für eine Property zurück
; Parameter(s).....: Property
; Return Value(s)..: Wert der Property
; Docu.............: http://www.scintilla.org/SciTEDoc.html od. "SciTE-Hilfe" --> "SciTE Documentation"
; Author(s)........: BugFix
;===============================================================================
Func _GetProperty($_sProperty)
SendSciTE_Command("askproperty:" & $_sProperty, 1)
Return StringTrimLeft($g_SciTECmd,StringInStr($g_SciTECmd, ':', 1, 4))
EndFunc
#cs --> Diese Versionen sind für die Verwendung mit Umlauten gedacht. In meinem SciTE liefern sie jedoch immer nur '0' zurück.
;===============================================================================
; Function Name....: _GetCurrentFile
; Description......: Gibt den Pfad der aktuell im Editor geöffneten Datei zurück
; Parameter(s).....: keine
; Return Value(s)..: Dateipfad
; Author(s)........: BugFix, Modified: Bitnugger
;===============================================================================
Func _GetCurrentFile()
SendSciTE_Command("askfilename:", 1)
Return StringReplace(StringTrimLeft(_WinAPI_MultiByteToWideChar(String($g_SciTECmd), 65001, $MB_PRECOMPOSED, True), StringInStr($g_SciTECmd, ':', 1, 1)), '\\', '\')
EndFunc ;==>_GetCurrentFile
;===============================================================================
; Function Name....: _GetProperty
; Description......: Gibt den Wert für eine Property zurück
; Parameter(s).....: Property
; Return Value(s)..: Wert der Property
; Docu.............: http://www.scintilla.org/SciTEDoc.html od. "SciTE-Hilfe" --> "SciTE Documentation"
; Author(s)........: BugFix, Modified: Bitnugger
;===============================================================================
Func _GetProperty($_sProperty)
SendSciTE_Command("askproperty:" & $_sProperty, 1)
ConsoleWrite('StringTrimLeft($g_SciTECmd, StringInStr($g_SciTECmd... ' & StringTrimLeft($g_SciTECmd, StringInStr($g_SciTECmd, ':', 1, 4)) & @CRLF)
;~ Return StringTrimLeft($g_SciTECmd, StringInStr($g_SciTECmd, ':', 1, 4))
Return _WinAPI_MultiByteToWideChar(StringTrimLeft($g_SciTECmd, StringInStr($g_SciTECmd, ':', 1, 4)), 65001, $MB_PRECOMPOSED, True)
EndFunc ;==>_GetProperty
#ce
; by BugFix
Func _GetHwndDirectorExtension()
Local $hActive = WinGetHandle('[ACTIVE]')
Local $PIDActive = WinGetProcess($hActive)
Local $aExtension = WinList("DirectorExtension")
Local $PIDExt
For $i = 1 To $aExtension[0][0]
$PIDExt = WinGetProcess($aExtension[$i][1])
If $PIDExt = $PIDActive Then Return $aExtension[$i][1]
Next
EndFunc ;==>_GetHwndDirectorExtension
; by Jos
Func SendSciTE_Command($_sCmd, $Wait_For_Return_Info = 0)
Local Static $My_Hwnd = GUICreate("AutoIt3-SciTE interface") ; Create GUI to receive SciTE info
Local Static $My_Dec_Hwnd = Dec(StringTrimLeft($My_Hwnd, 2)) ; Convert my Gui Handle to decimal
Local Const $SCI_GETLINE = 0x0869 ; 2153
Local Const $WM_COPYDATA = 0x004A ; 74
Local Const $WM_GETTEXT = 0x000D ; 13
Local Const $WM_GETTEXTLENGTH = 0xE224 ; 57892
Local $Scite_hwnd = _GetHwndDirectorExtension() ; Get SciTE DIrector Handle
$_sCmd = ":" & $My_Dec_Hwnd & ":" & $_sCmd ; Add dec my gui handle to commandline to tell SciTE where to send the return info
Local $CmdStruct = DllStructCreate('CHAR[' & StringLen($_sCmd) + 1 & ']')
DllStructSetData($CmdStruct, 1, $_sCmd)
Local $COPYDATA = DllStructCreate('ULONG_PTR;DWORD;PTR')
DllStructSetData($COPYDATA, 1, 1)
DllStructSetData($COPYDATA, 2, StringLen($_sCmd) + 1)
DllStructSetData($COPYDATA, 3, DllStructGetPtr($CmdStruct))
$g_SciTECmd = ""
DllCall('User32.dll', 'None', 'SendMessage', _
'HWnd', $Scite_hwnd, _
'Int', $WM_COPYDATA, _
'HWnd', $My_Hwnd, _
'Ptr', DllStructGetPtr($COPYDATA))
;~ GUIDelete($My_Hwnd)
If $Wait_For_Return_Info Then
For $x = 1 To 10
If $g_SciTECmd <> "" Then ExitLoop
Sleep(20)
Next
$g_SciTECmd = StringTrimLeft($g_SciTECmd, StringLen(":" & $My_Dec_Hwnd & ":"))
$g_SciTECmd = StringReplace($g_SciTECmd, "macro:stringinfo:", "")
Return $g_SciTECmd
EndIf
EndFunc ;==>SendSciTE_Command
;~ https://docs.microsoft.com/en-us/windows/desktop/api/Winuser/ns-winuser-tagcopydatastruct
;~ typedef struct tagCOPYDATASTRUCT {
;~ ULONG_PTR dwData; --> ULONG_PTR
;~ DWORD cbData; --> DWORD
;~ PVOID lpData; --> PTR
;~ } COPYDATASTRUCT, *PCOPYDATASTRUCT;
Func MY_WM_COPYDATA($hWnd, $msg, $wParam, $lParam)
Local $COPYDATA = DllStructCreate('ULONG_PTR;DWORD;PTR', $lParam)
Local $SciTECmdLen = DllStructGetData($COPYDATA, 2)
Local $CmdStruct = DllStructCreate('CHAR[255]', DllStructGetData($COPYDATA, 3))
$g_SciTECmd = StringLeft(DllStructGetData($CmdStruct, 1), $SciTECmdLen)
EndFunc ;==>MY_WM_COPYDATA
Alles anzeigen