Creating Installer with 7zip SFX exe - without using Temp

Helpful script writing tricks and HowTo's
User avatar
Taurus
Posts: 94
Joined: 20 Jan 2015, 10:31

Creating Installer with 7zip SFX exe - without using Temp

23 Feb 2015, 09:30

Hey guys,

Edit 17.06.2015:
This is the best solution, ready to use for everybody:

Thx to all posters below and big Thx to HotKeyIt!
How to use: Just download it and copy the first part to your script

Code: Select all

; Big Thx to HotKeyIt
; Source: http://www.autohotkey.com/board/topic/87068-binrun-run-binary-executable-from-memory-eg-resource/page-2


; ************************ Howto use ************************
; copy this to your script and modify exe-name and parameters

;~ #Include ExeRun.ahk 

;~ If 0
   ;~ FileInstall,MyExe.exe,-
   

;~ Parameters = -o"Path" -y -p"Password" ; Example for 7zip-Installer
;~ cmdLineScript = ; AHK Script-Code if used to create & execute code while running
;~ Hide = 0 ; Show/Hide the executed Window
;~ ExeToUse = ; if not specified, self is used

;~ Process_ID := BinRun("MyExe.exe", Parameters, cmdLineScript, Hide, ExeToUse)

;~ Process, Wait, %Process_ID%, 5 ; wait for process to start
;~ Process, WaitClose, %Process_ID%, 300 ; same as RunWait




; ************************ Source-Code ************************


; -- sizeof.ahk --


;: Title: sizeof function by HotKeyIt
;

; Function: sizeof
; Description:
;      sizeof() is based on AHK_L Objects and supports both, ANSI and UNICODE version, so to use it you will require <a href=http://www.autohotkey.com/forum/viewtopic.php?t=43049>Lexikos AutoHotkey_L.exe</a> or other versions based on it that supports objects.<br><br>nsizeof is used to calculate the size of structures or data types. <br>Visit <a href=http://www.autohotkey.com/forum/viewtopic.php?t=43049>sizeof at AutoHotkey</a> forum, any feedback is welcome.
; Syntax: size:= sizeof(Structure_Definition or Structure_Object)
; Parameters:
;	   Field types - All AutoHotkey and Windows Data Types are supported<br>AutoHotkey Data Types<br> Int, Uint, Int64, UInt64, Char, UChar, Short, UShort, Fload and Double.<br>Windows Data Types<br> - note, TCHAR UCHAR and CHAR return actual character rather than the value, use Asc() function to find out the value/code<br>Windows Data types: Asc(char)<br>ATOM,BOOL,BOOLEAN,BYTE,CHAR,COLORREF,DWORD,DWORDLONG,DWORD_PTR,<br>DWORD32,DWORD64,FLOAT,HACCEL,HALF_PTR,HANDLE,HBITMAP,HBRUSH,HCOLORSPACE,HCONV,HCONVLIST,HCURSOR,HDC,<br>HDDEDATA,HDESK,HDROP,HDWP,HENHMETAFILE,HFILE,HFONT,HGDIOBJ,HGLOBAL,HHOOK,HICON,HINSTANCE,HKEY,HKL,<br>HLOCAL,HMENU,HMETAFILE,HMODULE,HMONITOR,HPALETTE,HPEN,HRESULT,HRGN,HRSRC,HSZ,HWINSTA,HWND,INT,<br>INT_PTR,INT32,INT64,LANGID,LCID,LCTYPE,LGRPID,LONG,LONGLONG,LONG_PTR,LONG32,LONG64,LPARAM,LPBOOL,<br>LPBYTE,LPCOLORREF,LPCSTR,LPCTSTR,LPCVOID,LPCWSTR,LPDWORD,LPHANDLE,LPINT,LPLONG,LPSTR,LPTSTR,LPVOID,<br>LPWORD,LPWSTR,LRESULT,PBOOL,PBOOLEAN,PBYTE,PCHAR,PCSTR,PCTSTR,PCWSTR,PDWORD,PDWORDLONG,PDWORD_PTR,<br>PDWORD32,PDWORD64,PFLOAT,PHALF_PTR,PHANDLE,PHKEY,PINT,PINT_PTR,PINT32,PINT64,PLCID,PLONG,PLONGLONG,<br>PLONG_PTR,PLONG32,PLONG64,POINTER_32,POINTER_64,POINTER_SIGNED,POINTER_UNSIGNED,PSHORT,PSIZE_T,<br>PSSIZE_T,PSTR,PTBYTE,PTCHAR,PTSTR,PUCHAR,PUHALF_PTR,PUINT,PUINT_PTR,PUINT32,PUINT64,PULONG,PULONGLONG,<br>PULONG_PTR,PULONG32,PULONG64,PUSHORT,PVOID,PWCHAR,PWORD,PWSTR,SC_HANDLE,SC_LOCK,SERVICE_STATUS_HANDLE,<br>SHORT,SIZE_T,SSIZE_T,TBYTE,TCHAR,UCHAR,UHALF_PTR,UINT,UINT_PTR,UINT32,UINT64,ULONG,ULONGLONG,<br>ULONG_PTR,ULONG32,ULONG64,USHORT,USN,WCHAR,WORD,WPARAM
;	   <b>Parameters</b> - <b>Description</b>
;	   size - The size of structure or data type
;	   Structure_Definition - C/C++ syntax or usual definition (must not be multiline) e.g. "Int x,Int y", C/C++ definitions must be multiline.
; Return Value:
;     sizeof returns size of structures or data types
; Remarks:
;		None.
; Related:
; Example:
;		file:

sizeof(_TYPE_,parent_offset=0,ByRef _align_total_=0){
  ;Windows and AHK Data Types, used to find out the corresponding size
  static _types__:="
  (LTrim Join
    ,ATOM:2,LANGID:2,WCHAR:2,WORD:2,PTR:" A_PtrSize ",UPTR:" A_PtrSize ",SHORT:2,USHORT:2,INT:4,UINT:4,INT64:8,UINT64:8,DOUBLE:8,FLOAT:4,CHAR:1,UCHAR:1,__int64:8
    ,TBYTE:" (A_IsUnicode?2:1) ",TCHAR:" (A_IsUnicode?2:1) ",HALF_PTR:" (A_PtrSize=8?4:2) ",UHALF_PTR:" (A_PtrSize=8?4:2) ",INT32:4,LONG:4,LONG32:4,LONGLONG:8
    ,LONG64:8,USN:8,HFILE:4,HRESULT:4,INT_PTR:" A_PtrSize ",LONG_PTR:" A_PtrSize ",POINTER_64:" A_PtrSize ",POINTER_SIGNED:" A_PtrSize "
    ,BOOL:4,SSIZE_T:" A_PtrSize ",WPARAM:" A_PtrSize ",BOOLEAN:1,BYTE:1,COLORREF:4,DWORD:4,DWORD32:4,LCID:4,LCTYPE:4,LGRPID:4,LRESULT:4,PBOOL:" A_PtrSize "
    ,PBOOLEAN:" A_PtrSize ",PBYTE:" A_PtrSize ",PCHAR:" A_PtrSize ",PCSTR:" A_PtrSize ",PCTSTR:" A_PtrSize ",PCWSTR:" A_PtrSize ",PDWORD:" A_PtrSize "
    ,PDWORDLONG:" A_PtrSize ",PDWORD_PTR:" A_PtrSize ",PDWORD32:" A_PtrSize ",PDWORD64:" A_PtrSize ",PFLOAT:" A_PtrSize ",PHALF_PTR:" A_PtrSize "
    ,UINT32:4,ULONG:4,ULONG32:4,DWORDLONG:8,DWORD64:8,ULONGLONG:8,ULONG64:8,DWORD_PTR:" A_PtrSize ",HACCEL:" A_PtrSize ",HANDLE:" A_PtrSize "
     ,HBITMAP:" A_PtrSize ",HBRUSH:" A_PtrSize ",HCOLORSPACE:" A_PtrSize ",HCONV:" A_PtrSize ",HCONVLIST:" A_PtrSize ",HCURSOR:" A_PtrSize ",HDC:" A_PtrSize "
     ,HDDEDATA:" A_PtrSize ",HDESK:" A_PtrSize ",HDROP:" A_PtrSize ",HDWP:" A_PtrSize ",HENHMETAFILE:" A_PtrSize ",HFONT:" A_PtrSize ",USAGE:" 2 "
   )"
  static _types_:=_types__ "
  (LTrim Join
     ,HGDIOBJ:" A_PtrSize ",HGLOBAL:" A_PtrSize ",HHOOK:" A_PtrSize ",HICON:" A_PtrSize ",HINSTANCE:" A_PtrSize ",HKEY:" A_PtrSize ",HKL:" A_PtrSize "
     ,HLOCAL:" A_PtrSize ",HMENU:" A_PtrSize ",HMETAFILE:" A_PtrSize ",HMODULE:" A_PtrSize ",HMONITOR:" A_PtrSize ",HPALETTE:" A_PtrSize ",HPEN:" A_PtrSize "
     ,HRGN:" A_PtrSize ",HRSRC:" A_PtrSize ",HSZ:" A_PtrSize ",HWINSTA:" A_PtrSize ",HWND:" A_PtrSize ",LPARAM:" A_PtrSize ",LPBOOL:" A_PtrSize ",LPBYTE:" A_PtrSize "
     ,LPCOLORREF:" A_PtrSize ",LPCSTR:" A_PtrSize ",LPCTSTR:" A_PtrSize ",LPCVOID:" A_PtrSize ",LPCWSTR:" A_PtrSize ",LPDWORD:" A_PtrSize ",LPHANDLE:" A_PtrSize "
     ,LPINT:" A_PtrSize ",LPLONG:" A_PtrSize ",LPSTR:" A_PtrSize ",LPTSTR:" A_PtrSize ",LPVOID:" A_PtrSize ",LPWORD:" A_PtrSize ",LPWSTR:" A_PtrSize "
     ,PHANDLE:" A_PtrSize ",PHKEY:" A_PtrSize ",PINT:" A_PtrSize ",PINT_PTR:" A_PtrSize ",PINT32:" A_PtrSize ",PINT64:" A_PtrSize ",PLCID:" A_PtrSize "
     ,PLONG:" A_PtrSize ",PLONGLONG:" A_PtrSize ",PLONG_PTR:" A_PtrSize ",PLONG32:" A_PtrSize ",PLONG64:" A_PtrSize ",POINTER_32:" A_PtrSize "
     ,POINTER_UNSIGNED:" A_PtrSize ",PSHORT:" A_PtrSize ",PSIZE_T:" A_PtrSize ",PSSIZE_T:" A_PtrSize ",PSTR:" A_PtrSize ",PTBYTE:" A_PtrSize "
     ,PTCHAR:" A_PtrSize ",PTSTR:" A_PtrSize ",PUCHAR:" A_PtrSize ",PUHALF_PTR:" A_PtrSize ",PUINT:" A_PtrSize ",PUINT_PTR:" A_PtrSize "
     ,PUINT32:" A_PtrSize ",PUINT64:" A_PtrSize ",PULONG:" A_PtrSize ",PULONGLONG:" A_PtrSize ",PULONG_PTR:" A_PtrSize ",PULONG32:" A_PtrSize "
     ,PULONG64:" A_PtrSize ",PUSHORT:" A_PtrSize ",PVOID:" A_PtrSize ",PWCHAR:" A_PtrSize ",PWORD:" A_PtrSize ",PWSTR:" A_PtrSize ",SC_HANDLE:" A_PtrSize "
     ,SC_LOCK:" A_PtrSize ",SERVICE_STATUS_HANDLE:" A_PtrSize ",SIZE_T:" A_PtrSize ",UINT_PTR:" A_PtrSize ",ULONG_PTR:" A_PtrSize ",VOID:" A_PtrSize "
     )"
  local _,_ArrName_:="",_ArrType_,_ArrSize_,_defobj_,_idx_,_LF_,_LF_BKP_,_match_,_offset_,_padding_,_struct_
				,_total_union_size_,_uix_,_union_,_union_size_,_in_struct_,_mod_,_max_size_,_struct_align_
	_offset_:=parent_offset           ; Init size/offset to 0 or parent_offset

  If IsObject(_TYPE_){    ; If structure object - check for offset in structure and return pointer + last offset + its data size
    return _TYPE_["`a`a"]
  }
  
  If RegExMatch(_TYPE_,"^[\w\d\._]+$"){ ; structures name was supplied, resolve to global var and run again
      If InStr(_types_,"," _TYPE_ ":")
        Return SubStr(_types_,InStr(_types_,"," _TYPE_ ":") + 2 + StrLen(_TYPE_),1)
      else If InStr(_TYPE_,"."){ ;check for object that holds structure definition
        Loop,Parse,_TYPE_,.
          If A_Index=1
            _defobj_:=%A_LoopField%
          else _defobj_:=_defobj_[A_LoopField]
        Return sizeof(_defobj_,parent_offset)
      } else Return sizeof(%_TYPE_%,parent_offset)
  } else _defobj_:=""    
  If InStr(_TYPE_,"`n") {   ; C/C++ style definition, convert
    _offset_:=""            ; This will hold new structure
    ,_struct_:=[]            ; This will keep track if union is structure
    ,_union_:=0              ; This will keep track of union depth
    Loop,Parse,_TYPE_,`n,`r`t%A_Space%%A_Tab%
    {
      _LF_:=""
      Loop,Parse,A_LoopField,`,`;,`t%A_Space%%A_Tab%
      {
        If RegExMatch(A_LoopField,"^\s*//") ;break on comments and continue main loop
            break
        If (A_LoopField){ ; skip empty lines
            If (!_LF_ && _ArrType_:=RegExMatch(A_LoopField,"[\w\d_#@]\s+[\w\d_#@]")) ; new line, find out data type and save key in _LF_ Data type will be added later
              _LF_:=RegExReplace(A_LoopField,"[\w\d_#@]\K\s+.*$")
            If Instr(A_LoopField,"{"){ ; Union, also check if it is a structure
              _union_++,_struct_.Insert(_union_,RegExMatch(A_LoopField,"i)^\s*struct\s*\{"))
            } else If InStr(A_LoopField,"}") ; end of union/struct
              _offset_.="}"
            else { ; not starting or ending struct or union so add definitions and apply Data Type.
              If _union_ ; add { or struct{
                  Loop % _union_
                    _ArrName_.=(_struct_[A_Index]?"struct":"") "{"
              _offset_.=(_offset_ ? "," : "") _ArrName_ ((_ArrType_ && A_Index!=1)?(_LF_ " "):"") RegExReplace(A_LoopField,"\s+"," ")
              ,_ArrName_:="",_union_:=0
            }
        }
      }
    }
    _TYPE_:=_offset_
    ,_offset_:=parent_offset           ; Init size/offset to 0 or parent_offset
  }
  
  ; Following keep track of union size/offset
  _union_:=[]               ; keep track of union level, required to reset offset after union is parsed
  ,_struct_:=[]              ; for each union level keep track if it is a structure (because here offset needs to increase
  ,_union_size_:=[]          ; keep track of highest member within the union or structure, used to calculate new offset after union
  ,_struct_align_:=[]        ; keep track of alignment before structure
  ,_total_union_size_:=0     ; used in combination with above, each loop the total offset is updated if current data size is higher
  ;,_align_total_:=0          ; used to calculate alignment for total size of structure
  ,_in_struct_:=1
  ; Parse given structure definition and calculate size
  ; Structures will be resolved by recrusive calls (a structure must be global)
  Loop,Parse,_TYPE_,`,`; ;,%A_Space%%A_Tab%`n`r
  {
    _in_struct_+=StrLen(A_LoopField)+1
    If ("" = _LF_ := trim(A_LoopField,A_Space A_Tab "`n`r"))
      continue
    _LF_BKP_:=_LF_ ;to check for ending brackets = union,struct
    ; Check for STARTING union and set union helpers
    While (_match_:=RegExMatch(_LF_,"i)^(struct|union)?\s*\{\K"))
      ; correct offset for union/structure, sizeof_maxsize returns max size of union or structure
        _max_size_:=sizeof_maxsize(SubStr(_TYPE_,_in_struct_-StrLen(A_LoopField)-1+(StrLen(_LF_BKP_)-StrLen(_LF_))))
        ,_union_.Insert(_offset_+=(_mod_:=Mod(_offset_,_max_size_))?Mod(_max_size_-_mod_,_max_size_):0)
        ,_union_size_.Insert(0)
        ,_struct_align_.Insert(_align_total_>_max_size_?_align_total_:_max_size_)
        ,_struct_.Insert(RegExMatch(_LF_,"i)^struct\s*\{")?(1,_align_total_:=0):0)
        ,_LF_:=SubStr(_LF_,_match_)
    StringReplace,_LF_,_LF_,},,A
    
    If InStr(_LF_,"*"){ ; It's a pointer, size will be always A_PtrSize
      _offset_ += (_mod_:=Mod(_offset_ + A_PtrSize,A_PtrSize)?A_PtrSize-_mod_:0) + A_PtrSize
      ,_align_total_:=_align_total_<A_PtrSize?A_PtrSize:_align_total_
    } else {
      ; Split array type and optionally the size of array, e.g. "TCHAR chr[5]"
      RegExMatch(_LF_,"^(?<ArrType_>[\w\d\._#@]+)?\s*(?<ArrName_>[\w\d\._#@]+)?\s*\[?(?<ArrSize_>\d+)?\]?\s*$",_)
      If (!_ArrName_ && !_ArrSize_ && !InStr( _types_  ,"," _ArrType_ ":"))
        _ArrName_:=_ArrType_,_ArrType_:="UInt"
      If InStr(_ArrType_,"."){ ;check for object that holds structure definition
        Loop,Parse,_ArrType_,.
          If A_Index=1
            _defobj_:=%A_LoopField%
          else _defobj_:=_defobj_[A_LoopField]
        ; _ArrType_:=_defobj_                                                                     ;                   ??????????????????????????????????????
      }
      If (_idx_:=InStr( _types_  ,"," _ArrType_ ":")) ; AHK or Windows data type
        _padding_:=SubStr( _types_  , _idx_+StrLen(_ArrType_)+2 , 1 ),_align_total_:=_align_total_<_padding_?_padding_:_align_total_
      else _padding_:= sizeof(_defobj_?_defobj_:%_ArrType_%,0,_align_total_),_max_size_:=sizeof_maxsize(_defobj_?_defobj_:%_ArrType_%)
      if (_max_size_){
        if (_mod_:=Mod(_offset_,_max_size_))
          _offset_ += Mod(_max_size_-_mod_,_max_size_)
      } else if _mod_:=Mod(_offset_,_padding_)
        _offset_ += Mod(_padding_-_mod_,_padding_)
      _offset_ += (_padding_ * (_ArrSize_?_ArrSize_:1))
      _max_size_:=0
    }
    ; It's a union or struct, check if new member is higher then previous members
    If (_uix_:=_union_.MaxIndex()) && (_max_size_:=_offset_ - _union_[_uix_])>_union_size_[_uix_]
      _union_size_[_uix_]:=_max_size_
    _max_size_:=0
    ; It's a union and not struct
    If (_uix_ && !_struct_[_uix_])
      _offset_:=_union_[_uix_]

    ; Check for ENDING union and reset offset and union helpers
    While (SubStr(_LF_BKP_,0)="}"){
      If !(_uix_:=_union_.MaxIndex()){
        MsgBox,0, Incorrect structure, missing opening braket {`nProgram will exit now `n%_TYPE_%
        ExitApp
      }
      ; reset offset and align because we left a union or structure
      if (_uix_>1 && _struct_[_uix_-1]){
        If (_mod_:=Mod(_offset_,_struct_align_[_uix_]))
          _offset_+=Mod(_struct_align_[_uix_]-_mod_,_struct_align_[_uix_])
      } else _offset_:=_union_[_uix_]
      ; a member of union/struct is smaller than previous align, restore
      if (_struct_[_uix_] &&_struct_align_[_uix_]>_align_total_)
        _align_total_ := _struct_align_[_uix_]
      ; Increase total size of union/structure if necessary
      _total_union_size_ := _union_size_[_uix_]>_total_union_size_?_union_size_[_uix_]:_total_union_size_
      ,_union_.Remove() ,_struct_.Remove() ,_union_size_.Remove(),_struct_align_.Remove() ; remove latest items
      ,_LF_BKP_:=SubStr(_LF_BKP_,1,StrLen(_LF_BKP_)-1)
      If (_uix_=1){ ; leaving top union, add offset
        if (_mod_:=Mod(_total_union_size_,_align_total_))
          _total_union_size_ += Mod(_align_total_-_mod_,_align_total_)
        _offset_+=_total_union_size_,_total_union_size_:=0
      }
    }
  }
  _offset_+= Mod(_align_total_ - Mod(_offset_,_align_total_),_align_total_)
  Return _offset_
}
sizeof_maxsize(s){
  static _types__:="
  (LTrim Join
    ,ATOM:2,LANGID:2,WCHAR:2,WORD:2,PTR:" A_PtrSize ",UPTR:" A_PtrSize ",SHORT:2,USHORT:2,INT:4,UINT:4,INT64:8,UINT64:8,DOUBLE:8,FLOAT:4,CHAR:1,UCHAR:1,__int64:8
    ,TBYTE:" (A_IsUnicode?2:1) ",TCHAR:" (A_IsUnicode?2:1) ",HALF_PTR:" (A_PtrSize=8?4:2) ",UHALF_PTR:" (A_PtrSize=8?4:2) ",INT32:4,LONG:4,LONG32:4,LONGLONG:8
    ,LONG64:8,USN:8,HFILE:4,HRESULT:4,INT_PTR:" A_PtrSize ",LONG_PTR:" A_PtrSize ",POINTER_64:" A_PtrSize ",POINTER_SIGNED:" A_PtrSize "
    ,BOOL:4,SSIZE_T:" A_PtrSize ",WPARAM:" A_PtrSize ",BOOLEAN:1,BYTE:1,COLORREF:4,DWORD:4,DWORD32:4,LCID:4,LCTYPE:4,LGRPID:4,LRESULT:4,PBOOL:" A_PtrSize "
    ,PBOOLEAN:" A_PtrSize ",PBYTE:" A_PtrSize ",PCHAR:" A_PtrSize ",PCSTR:" A_PtrSize ",PCTSTR:" A_PtrSize ",PCWSTR:" A_PtrSize ",PDWORD:" A_PtrSize "
    ,PDWORDLONG:" A_PtrSize ",PDWORD_PTR:" A_PtrSize ",PDWORD32:" A_PtrSize ",PDWORD64:" A_PtrSize ",PFLOAT:" A_PtrSize ",PHALF_PTR:" A_PtrSize "
    ,UINT32:4,ULONG:4,ULONG32:4,DWORDLONG:8,DWORD64:8,ULONGLONG:8,ULONG64:8,DWORD_PTR:" A_PtrSize ",HACCEL:" A_PtrSize ",HANDLE:" A_PtrSize "
     ,HBITMAP:" A_PtrSize ",HBRUSH:" A_PtrSize ",HCOLORSPACE:" A_PtrSize ",HCONV:" A_PtrSize ",HCONVLIST:" A_PtrSize ",HCURSOR:" A_PtrSize ",HDC:" A_PtrSize "
     ,HDDEDATA:" A_PtrSize ",HDESK:" A_PtrSize ",HDROP:" A_PtrSize ",HDWP:" A_PtrSize ",HENHMETAFILE:" A_PtrSize ",HFONT:" A_PtrSize ",USAGE:" 2 "
   )"
  static _types_:=_types__ "
  (LTrim Join
     ,HGDIOBJ:" A_PtrSize ",HGLOBAL:" A_PtrSize ",HHOOK:" A_PtrSize ",HICON:" A_PtrSize ",HINSTANCE:" A_PtrSize ",HKEY:" A_PtrSize ",HKL:" A_PtrSize "
     ,HLOCAL:" A_PtrSize ",HMENU:" A_PtrSize ",HMETAFILE:" A_PtrSize ",HMODULE:" A_PtrSize ",HMONITOR:" A_PtrSize ",HPALETTE:" A_PtrSize ",HPEN:" A_PtrSize "
     ,HRGN:" A_PtrSize ",HRSRC:" A_PtrSize ",HSZ:" A_PtrSize ",HWINSTA:" A_PtrSize ",HWND:" A_PtrSize ",LPARAM:" A_PtrSize ",LPBOOL:" A_PtrSize ",LPBYTE:" A_PtrSize "
     ,LPCOLORREF:" A_PtrSize ",LPCSTR:" A_PtrSize ",LPCTSTR:" A_PtrSize ",LPCVOID:" A_PtrSize ",LPCWSTR:" A_PtrSize ",LPDWORD:" A_PtrSize ",LPHANDLE:" A_PtrSize "
     ,LPINT:" A_PtrSize ",LPLONG:" A_PtrSize ",LPSTR:" A_PtrSize ",LPTSTR:" A_PtrSize ",LPVOID:" A_PtrSize ",LPWORD:" A_PtrSize ",LPWSTR:" A_PtrSize "
     ,PHANDLE:" A_PtrSize ",PHKEY:" A_PtrSize ",PINT:" A_PtrSize ",PINT_PTR:" A_PtrSize ",PINT32:" A_PtrSize ",PINT64:" A_PtrSize ",PLCID:" A_PtrSize "
     ,PLONG:" A_PtrSize ",PLONGLONG:" A_PtrSize ",PLONG_PTR:" A_PtrSize ",PLONG32:" A_PtrSize ",PLONG64:" A_PtrSize ",POINTER_32:" A_PtrSize "
     ,POINTER_UNSIGNED:" A_PtrSize ",PSHORT:" A_PtrSize ",PSIZE_T:" A_PtrSize ",PSSIZE_T:" A_PtrSize ",PSTR:" A_PtrSize ",PTBYTE:" A_PtrSize "
     ,PTCHAR:" A_PtrSize ",PTSTR:" A_PtrSize ",PUCHAR:" A_PtrSize ",PUHALF_PTR:" A_PtrSize ",PUINT:" A_PtrSize ",PUINT_PTR:" A_PtrSize "
     ,PUINT32:" A_PtrSize ",PUINT64:" A_PtrSize ",PULONG:" A_PtrSize ",PULONGLONG:" A_PtrSize ",PULONG_PTR:" A_PtrSize ",PULONG32:" A_PtrSize "
     ,PULONG64:" A_PtrSize ",PUSHORT:" A_PtrSize ",PVOID:" A_PtrSize ",PWCHAR:" A_PtrSize ",PWORD:" A_PtrSize ",PWSTR:" A_PtrSize ",SC_HANDLE:" A_PtrSize "
     ,SC_LOCK:" A_PtrSize ",SERVICE_STATUS_HANDLE:" A_PtrSize ",SIZE_T:" A_PtrSize ",UINT_PTR:" A_PtrSize ",ULONG_PTR:" A_PtrSize ",VOID:" A_PtrSize "
     )"
  max:=0,i:=0
  s:=trim(s,"`n`r`t ")
  If InStr(s,"}"){
    Loop,Parse,s
      if (A_LoopField="{")
        i++
      else if (A_LoopField="}"){
        if --i<1{
          end:=A_Index
          break
        }
      }
    if end
      s:=SubStr(s,1,end)
  }
  Loop,Parse,s,`n,`r
  {
    _struct_:=(i:=InStr(A_LoopField," //"))?SubStr(A_LoopField,1,i):A_LoopField
    Loop,Parse,_struct_,`;`,{},%A_Space%%A_Tab%
      if A_LoopField&&!InStr(".union.struct.","." A_LoopField ".")
        if (!InStr(A_LoopField,A_Tab)&&!InStr(A_LoopField," "))
          max:=max<4?4:max
        else if (sizeof(A_LoopField,0,size:=0) && max<size)
          max:=size
  }
  return max
}



; -- _Struct.ahk --



;: Title: _Struct by HotKeyIt
;

; Function: _Struct
; Description:
;      _Struct is based on AHK_L objects and supports both, ANSI and UNICODE version. To use it you will require <a href=http://www.autohotkey.com/forum/viewtopic.php?t=43049>Lexikos AutoHotkey_L.exe</a> or other versions based on it.<br><br>new _Struct is used to create new structure. A structure must be defined as a global variable or an item of global class (e.g. "MyClass.Struct").<br>_Struct can handle structure in structure as well as Arrays of structures and Vectors.<br>Visit <a href=http://www.autohotkey.com/forum/viewtopic.php?t=43049>_Struct on AutoHotkey</a> forum, any feedback is welcome.
; Syntax: MyStruct:= new _Struct(Structure_Definition,Address,initialization)
; Parameters:
;	   General Design - Class _Struct will create Object(s) that will manage fields of structure(s), for example<br>left,top,right,bottom<br>RC := new _Struct("RECT")<br>will create a RECT structure with fields left,top,right,bottom of type UInt. To pass the structure its pointer to a function, DllCall or SendMessage use RC[""].<br><br>To access fields you can use usual Object syntax: RC.left, RC.right ...<br>To set a field of the structure use RC.top := 100.
;	   Field types - Following AutoHotkey and Windows Data Types are supported:<br><br>AutoHotkey Data Types:<br>Int, Uint, Int64, UInt64, Char, UChar, Short, UShort, Fload and Double.<br><br>Windows Data Types:<br>ATOM,BOOL,BOOLEAN,BYTE,CHAR,COLORREF,DWORD,DWORDLONG,DWORD_PTR,<br>DWORD32,DWORD64,FLOAT,HACCEL,HALF_PTR,HANDLE,HBITMAP,HBRUSH,HCOLORSPACE,HCONV,HCONVLIST,HCURSOR,HDC,<br>HDDEDATA,HDESK,HDROP,HDWP,HENHMETAFILE,HFILE,HFONT,HGDIOBJ,HGLOBAL,HHOOK,HICON,HINSTANCE,HKEY,HKL,<br>HLOCAL,HMENU,HMETAFILE,HMODULE,HMONITOR,HPALETTE,HPEN,HRESULT,HRGN,HRSRC,HSZ,HWINSTA,HWND,INT,<br>INT_PTR,INT32,INT64,LANGID,LCID,LCTYPE,LGRPID,LONG,LONGLONG,LONG_PTR,LONG32,LONG64,LPARAM,LPBOOL,<br>LPBYTE,LPCOLORREF,LPCSTR,LPCTSTR,LPCVOID,LPCWSTR,LPDWORD,LPHANDLE,LPINT,LPLONG,LPSTR,LPTSTR,LPVOID,<br>LPWORD,LPWSTR,LRESULT,PBOOL,PBOOLEAN,PBYTE,PCHAR,PCSTR,PCTSTR,PCWSTR,PDWORD,PDWORDLONG,PDWORD_PTR,<br>PDWORD32,PDWORD64,PFLOAT,PHALF_PTR,PHANDLE,PHKEY,PINT,PINT_PTR,PINT32,PINT64,PLCID,PLONG,PLONGLONG,<br>PLONG_PTR,PLONG32,PLONG64,POINTER_32,POINTER_64,POINTER_SIGNED,POINTER_UNSIGNED,PSHORT,PSIZE_T,<br>PSSIZE_T,PSTR,PTBYTE,PTCHAR,PTSTR,PUCHAR,PUHALF_PTR,PUINT,PUINT_PTR,PUINT32,PUINT64,PULONG,PULONGLONG,<br>PULONG_PTR,PULONG32,PULONG64,PUSHORT,PVOID,PWCHAR,PWORD,PWSTR,SC_HANDLE,SC_LOCK,SERVICE_STATUS_HANDLE,<br>SHORT,SIZE_T,SSIZE_T,TBYTE,TCHAR,UCHAR,UHALF_PTR,UINT,UINT_PTR,UINT32,UINT64,ULONG,ULONGLONG,<br>ULONG_PTR,ULONG32,ULONG64,USHORT,USN,WCHAR,WORD,WPARAM
;	   <b>Structure Definition</b> - <b>Description</b>
;	   User defined - To create a user defined structure you will need to pass a string of predefined types and field names.<br>Default type is UInt, so for example for a RECT structure type can be omited: <b>"left,top,right,left"</b>, which is the same as <b>"Uint left,Uint top,Uint right,Uint bottom"</b><br><br>You can also use structures very similar to C#/C++ syntax, see example.
;	   Global - Global variables can be used to save structures, easily pass name of that variable as first parameter, e.g. new _Struct("MyStruct") where MyStruct must be a global variable with structure definition. Also new _Struct(MyStruct) can be used if variable is accessible.
;	   Array - To create an array of structures include a digit in the end of your string enclosed in squared brackets.<br>For example "RECT[2]" would create an array of 2 structures.<br>This feature can also be used for user defined arrays, for example "Int age,TCHAR name[10]".
;	   Union - Using {} you can create union, for example: <br>_AHKVar:="{Int64 ContentsInt64,Double ContentsDouble,object},...
;	   Struct - Using struct{} you can create structures in union or in structures.
;	   Pointer - To create a pointer you can use *, for example: CHR:="char *str" will hold a pointer to a character. Same way you can have a structure in structure so you can call it recursive, for example Label.NextLabel.NextLabel.NextLabel.JumpToLine
;	   <b>Parameters</b> - <b>Description</b>
;	   MyStruct - This is a variable that will hold the object representing the strucuture which is returned by new _Struct(...).
;	   Structure_Definition - C/C++ syntax or one-line definition e.g. "Int x,Int y".
;	   pointer - Pass a pointer as second parameter to occupy existing strucure.
;	   Initialization - Pass an object to initialize structure, e.g. {left:100,top:20}. If pointer is not used initialization can be specified in second parameter.
;	   <b>Methods</b> - <b>Description</b>
;	   Strct.Type(itm) - Returns type of item or structure
;	   Strct.AhkType(itm) - Returns AHK type of item or structure to be used with NumGet and NumPut as well as DllCall
;	   Strct.Size() - Returns size of structure, same as sizeof(MyStruct)
;	   Strct.SizeT(itm) - Returns size of an item
;	   Strct.Offset(itm) - Returns offset for items
;	   Strct.Encoding(itm) - Returns encoding for items, to be used with StrGet and StrPut
;	   Strct.Alloc(itm,size[,ptrsize]) - Allocates memory in bytes, ptrsize is used to create pointers
;	   Strct.Capacity(itm) - Returns memory capacity for items.
;	   Strct.IsPointer(itm) - Returns whether the item is a pointer (defined using *).
; Return Value:
;     A class object representing your structure
; Remarks:
;		<b>NOTE!!! accessing a field that does not exist will cause recrusive calls and will crash your script, these errors are not catched for performance reasons.<br>TCHAR, UCHAR and CHAR return actual character rather than the value, use Asc() function to find out the value/code.
; Related:
; Example:
;		file:Struct_Example.ahk
;

Class _Struct {
	; Data Sizes
  static PTR:=A_PtrSize,UPTR:=A_PtrSize,SHORT:=2,USHORT:=2,INT:=4,UINT:=4,__int64:=8,INT64:=8,UINT64:=8,DOUBLE:=8,FLOAT:=4,CHAR:=1,UCHAR:=1,VOID:=A_PtrSize
    ,TBYTE:=A_IsUnicode?2:1,TCHAR:=A_IsUnicode?2:1,HALF_PTR:=A_PtrSize=8?4:2,UHALF_PTR:=A_PtrSize=8?4:2,INT32:=4,LONG:=4,LONG32:=4,LONGLONG:=8
    ,LONG64:=8,USN:=8,HFILE:=4,HRESULT:=4,INT_PTR:=A_PtrSize,LONG_PTR:=A_PtrSize,POINTER_64:=A_PtrSize,POINTER_SIGNED:=A_PtrSize
    ,BOOL:=4,SSIZE_T:=A_PtrSize,WPARAM:=A_PtrSize,BOOLEAN:=1,BYTE:=1,COLORREF:=4,DWORD:=4,DWORD32:=4,LCID:=4,LCTYPE:=4,LGRPID:=4,LRESULT:=4,PBOOL:=4
    ,PBOOLEAN:=A_PtrSize,PBYTE:=A_PtrSize,PCHAR:=A_PtrSize,PCSTR:=A_PtrSize,PCTSTR:=A_PtrSize,PCWSTR:=A_PtrSize,PDWORD:=A_PtrSize,PDWORDLONG:=A_PtrSize
    ,PDWORD_PTR:=A_PtrSize,PDWORD32:=A_PtrSize,PDWORD64:=A_PtrSize,PFLOAT:=A_PtrSize,PHALF_PTR:=A_PtrSize
    ,UINT32:=4,ULONG:=4,ULONG32:=4,DWORDLONG:=8,DWORD64:=8,ULONGLONG:=8,ULONG64:=8,DWORD_PTR:=A_PtrSize,HACCEL:=A_PtrSize,HANDLE:=A_PtrSize
    ,HBITMAP:=A_PtrSize,HBRUSH:=A_PtrSize,HCOLORSPACE:=A_PtrSize,HCONV:=A_PtrSize,HCONVLIST:=A_PtrSize,HCURSOR:=A_PtrSize,HDC:=A_PtrSize
    ,HDDEDATA:=A_PtrSize,HDESK:=A_PtrSize,HDROP:=A_PtrSize,HDWP:=A_PtrSize,HENHMETAFILE:=A_PtrSize,HFONT:=A_PtrSize
  static HGDIOBJ:=A_PtrSize,HGLOBAL:=A_PtrSize,HHOOK:=A_PtrSize,HICON:=A_PtrSize,HINSTANCE:=A_PtrSize,HKEY:=A_PtrSize,HKL:=A_PtrSize
    ,HLOCAL:=A_PtrSize,HMENU:=A_PtrSize,HMETAFILE:=A_PtrSize,HMODULE:=A_PtrSize,HMONITOR:=A_PtrSize,HPALETTE:=A_PtrSize,HPEN:=A_PtrSize
    ,HRGN:=A_PtrSize,HRSRC:=A_PtrSize,HSZ:=A_PtrSize,HWINSTA:=A_PtrSize,HWND:=A_PtrSize,LPARAM:=A_PtrSize,LPBOOL:=A_PtrSize,LPBYTE:=A_PtrSize
    ,LPCOLORREF:=A_PtrSize,LPCSTR:=A_PtrSize,LPCTSTR:=A_PtrSize,LPCVOID:=A_PtrSize,LPCWSTR:=A_PtrSize,LPDWORD:=A_PtrSize,LPHANDLE:=A_PtrSize
    ,LPINT:=A_PtrSize,LPLONG:=A_PtrSize,LPSTR:=A_PtrSize,LPTSTR:=A_PtrSize,LPVOID:=A_PtrSize,LPWORD:=A_PtrSize,LPWSTR:=A_PtrSize,PHANDLE:=A_PtrSize
    ,PHKEY:=A_PtrSize,PINT:=A_PtrSize,PINT_PTR:=A_PtrSize,PINT32:=A_PtrSize,PINT64:=A_PtrSize,PLCID:=A_PtrSize,PLONG:=A_PtrSize,PLONGLONG:=A_PtrSize
    ,PLONG_PTR:=A_PtrSize,PLONG32:=A_PtrSize,PLONG64:=A_PtrSize,POINTER_32:=A_PtrSize,POINTER_UNSIGNED:=A_PtrSize,PSHORT:=A_PtrSize,PSIZE_T:=A_PtrSize
    ,PSSIZE_T:=A_PtrSize,PSTR:=A_PtrSize,PTBYTE:=A_PtrSize,PTCHAR:=A_PtrSize,PTSTR:=A_PtrSize,PUCHAR:=A_PtrSize,PUHALF_PTR:=A_PtrSize,PUINT:=A_PtrSize
    ,PUINT_PTR:=A_PtrSize,PUINT32:=A_PtrSize,PUINT64:=A_PtrSize,PULONG:=A_PtrSize,PULONGLONG:=A_PtrSize,PULONG_PTR:=A_PtrSize,PULONG32:=A_PtrSize
    ,PULONG64:=A_PtrSize,PUSHORT:=A_PtrSize,PVOID:=A_PtrSize,PWCHAR:=A_PtrSize,PWORD:=A_PtrSize,PWSTR:=A_PtrSize,SC_HANDLE:=A_PtrSize
    ,SC_LOCK:=A_PtrSize,SERVICE_STATUS_HANDLE:=A_PtrSize,SIZE_T:=A_PtrSize,UINT_PTR:=A_PtrSize,ULONG_PTR:=A_PtrSize,ATOM:=2,LANGID:=2,WCHAR:=2,WORD:=2,USAGE:=2
	; Data Types
  static _PTR:="PTR",_UPTR:="UPTR",_SHORT:="Short",_USHORT:="UShort",_INT:="Int",_UINT:="UInt"
    ,_INT64:="Int64",_UINT64:="UInt64",_DOUBLE:="Double",_FLOAT:="Float",_CHAR:="Char",_UCHAR:="UChar"
    ,_VOID:="PTR",_TBYTE:=A_IsUnicode?"USHORT":"UCHAR",_TCHAR:=A_IsUnicode?"USHORT":"UCHAR",_HALF_PTR:=A_PtrSize=8?"INT":"SHORT"
    ,_UHALF_PTR:=A_PtrSize=8?"UINT":"USHORT",_BOOL:="Int",_INT32:="Int",_LONG:="Int",_LONG32:="Int",_LONGLONG:="Int64",_LONG64:="Int64"
    ,_USN:="Int64",_HFILE:="UInt",_HRESULT:="UInt",_INT_PTR:="PTR",_LONG_PTR:="PTR",_POINTER_64:="PTR",_POINTER_SIGNED:="PTR",_SSIZE_T:="PTR"
    ,_WPARAM:="PTR",_BOOLEAN:="UCHAR",_BYTE:="UCHAR",_COLORREF:="UInt",_DWORD:="UInt",_DWORD32:="UInt",_LCID:="UInt",_LCTYPE:="UInt"
    ,_LGRPID:="UInt",_LRESULT:="UInt",_PBOOL:="UPTR",_PBOOLEAN:="UPTR",_PBYTE:="UPTR",_PCHAR:="UPTR",_PCSTR:="UPTR",_PCTSTR:="UPTR"
    ,_PCWSTR:="UPTR",_PDWORD:="UPTR",_PDWORDLONG:="UPTR",_PDWORD_PTR:="UPTR",_PDWORD32:="UPTR",_PDWORD64:="UPTR",_PFLOAT:="UPTR",___int64:="Int64"
    ,_PHALF_PTR:="UPTR",_UINT32:="UInt",_ULONG:="UInt",_ULONG32:="UInt",_DWORDLONG:="UInt64",_DWORD64:="UInt64",_ULONGLONG:="UInt64"
    ,_ULONG64:="UInt64",_DWORD_PTR:="UPTR",_HACCEL:="UPTR",_HANDLE:="UPTR",_HBITMAP:="UPTR",_HBRUSH:="UPTR",_HCOLORSPACE:="UPTR"
    ,_HCONV:="UPTR",_HCONVLIST:="UPTR",_HCURSOR:="UPTR",_HDC:="UPTR",_HDDEDATA:="UPTR",_HDESK:="UPTR",_HDROP:="UPTR",_HDWP:="UPTR"
  static _HENHMETAFILE:="UPTR",_HFONT:="UPTR",_HGDIOBJ:="UPTR",_HGLOBAL:="UPTR",_HHOOK:="UPTR",_HICON:="UPTR",_HINSTANCE:="UPTR",_HKEY:="UPTR"
    ,_HKL:="UPTR",_HLOCAL:="UPTR",_HMENU:="UPTR",_HMETAFILE:="UPTR",_HMODULE:="UPTR",_HMONITOR:="UPTR",_HPALETTE:="UPTR",_HPEN:="UPTR"
    ,_HRGN:="UPTR",_HRSRC:="UPTR",_HSZ:="UPTR",_HWINSTA:="UPTR",_HWND:="UPTR",_LPARAM:="UPTR",_LPBOOL:="UPTR",_LPBYTE:="UPTR",_LPCOLORREF:="UPTR"
    ,_LPCSTR:="UPTR",_LPCTSTR:="UPTR",_LPCVOID:="UPTR",_LPCWSTR:="UPTR",_LPDWORD:="UPTR",_LPHANDLE:="UPTR",_LPINT:="UPTR",_LPLONG:="UPTR"
    ,_LPSTR:="UPTR",_LPTSTR:="UPTR",_LPVOID:="UPTR",_LPWORD:="UPTR",_LPWSTR:="UPTR",_PHANDLE:="UPTR",_PHKEY:="UPTR",_PINT:="UPTR"
    ,_PINT_PTR:="UPTR",_PINT32:="UPTR",_PINT64:="UPTR",_PLCID:="UPTR",_PLONG:="UPTR",_PLONGLONG:="UPTR",_PLONG_PTR:="UPTR",_PLONG32:="UPTR"
    ,_PLONG64:="UPTR",_POINTER_32:="UPTR",_POINTER_UNSIGNED:="UPTR",_PSHORT:="UPTR",_PSIZE_T:="UPTR",_PSSIZE_T:="UPTR",_PSTR:="UPTR"
    ,_PTBYTE:="UPTR",_PTCHAR:="UPTR",_PTSTR:="UPTR",_PUCHAR:="UPTR",_PUHALF_PTR:="UPTR",_PUINT:="UPTR",_PUINT_PTR:="UPTR",_PUINT32:="UPTR"
    ,_PUINT64:="UPTR",_PULONG:="UPTR",_PULONGLONG:="UPTR",_PULONG_PTR:="UPTR",_PULONG32:="UPTR",_PULONG64:="UPTR",_PUSHORT:="UPTR"
    ,_PVOID:="UPTR",_PWCHAR:="UPTR",_PWORD:="UPTR",_PWSTR:="UPTR",_SC_HANDLE:="UPTR",_SC_LOCK:="UPTR",_SERVICE_STATUS_HANDLE:="UPTR"
  static _SIZE_T:="UPTR",_UINT_PTR:="UPTR",_ULONG_PTR:="UPTR",_ATOM:="Ushort",_LANGID:="Ushort",_WCHAR:="Ushort",_WORD:="UShort",_USAGE:="UShort"
    
  ; Following is used internally only to simplify setting field helpers
  ; the corresponding key can be set to invalid type (for string integer and vice versa) to set default if necessary, e.g. ___InitField(N,"")
  ___InitField(_this,N,offset=" ",encoding=0,AHKType=0,isptr=" ",type=0,arrsize=0,memory=0){ ; N = Name of field
    static _prefixes_:={offset:"`b",isptr:"`r",AHKType:"`n",type:"`t",encoding:"`f",memory:"`v",arrsize:" "}
          ,_testtype_:={offset:"integer",isptr:"integer",AHKType:"string",type:"string",encoding:"string",arrsize:"integer"}
          ,_default_:={offset:0,isptr:0,AHKType:"UInt",type:"UINT",encoding:"CP0",memory:"",arrsize:1}
    for _key_,_value_ in _prefixes_
    {
      _typevalid_:=0
      If (_testtype_[_key_]="Integer"){
        If %_key_% is integer
          useDefault:=1,_typevalid_:=1
        else if !_this.HasKey(_value_ N)
          useDefault:=1
      } else {
        If %_key_% is not integer
          useDefault:=1,_typevalid_:=1
        else if !_this.HasKey(_value_ N)
          useDefault:=1
      }
      If (useDefault) ; item does not exist or user supplied a valid type
        If (_key_="encoding")
          _this[_value_ N]:=_typevalid_?(InStr(",LPTSTR,LPCTSTR,TCHAR,","," %_key_% ",")?(A_IsUnicode?"UTF-16":"CP0")
                                        :InStr(",LPWSTR,LPCWSTR,WCHAR,","," %_key_% ",")?"UTF-16":"CP0")
                                      :_default_[_key_]
        else {
          _this[_value_ N]:=_typevalid_?%_key_%:_default_[_key_]
         }
    }
  }
  
  ; Struct Contstructor
  ; Memory, offset and definitions are saved in following character + given key/name
  ;   `a = Allocated Memory
  ;   `b = Byte Offset (related to struct address)
  ;   `f = Format (encoding for string data types)
  ;   `n = New data type (AHK data type)
  ;   `r = Is Pointer (requred for __GET and __SET)
  ;   `t = Type (data type, also when it is name of a Structure it is used to resolve structure pointers dynamically
  ;   `v = Memory used to save string and pointer memory
  __NEW(_TYPE_,_pointer_=0,_init_=0){
    static _base_:={__GET:_Struct.___GET,__SET:_Struct.___SET,__SETPTR:_Struct.___SETPTR,__Clone:_Struct.___Clone,__NEW:_Struct.___NEW
          ,IsPointer:_Struct.IsPointer,Offset:_Struct.Offset,Type:_Struct.Type,AHKType:_Struct.AHKType,Encoding:_Struct.Encoding
          ,Capacity:_Struct.Capacity,Alloc:_Struct.Alloc,Size:_Struct.Size,SizeT:_Struct.SizeT,Print:_Struct.Print,ToObj:_Struct.ToObj}
		local _,_ArrType_,_ArrName_:="",_ArrSize_,_align_total_,_defobj_,_IsPtr_,_key_,_LF_,_LF_BKP_,_match_,_offset_:=""
			,_struct_,_StructSize_,_total_union_size_,_union_,_union_size_,_value_,_mod_,_max_size_,_in_struct_,_struct_align_
		
		If (RegExMatch(_TYPE_,"^[\w\d\._]+$") && !_Struct.HasKey(_TYPE_)){ ; structures name was supplied, resolve to global var and run again
      If InStr(_TYPE_,"."){ ;check for object that holds structure definition
        Loop,Parse,_TYPE_,.
          If A_Index=1
            _defobj_:=%A_LoopField%
          else _defobj_:=_defobj_[A_LoopField]
        _TYPE_:=_defobj_
      } else _TYPE_:=%_TYPE_%,_defobj_:=""
    } else _defobj_:=""
    ; If a pointer is supplied, save it in key [""] else reserve and zero-fill memory + set pointer in key [""]
    If (_pointer_ && !IsObject(_pointer_))
      this[""] := _pointer_,this["`a"]:=0,this["`a`a"]:=sizeof(_TYPE_)
    else
      this._SetCapacity("`a",_StructSize_:=sizeof(_TYPE_)) ; Set Capacity in key ["`a"]
      ,this[""]:=this._GetAddress("`a") ; Save pointer in key [""]
      ,DllCall("RtlZeroMemory","UPTR",this[""],"UInt",this["`a`a"]:=_StructSize_) ; zero-fill memory
    ; C/C++ style structure definition, convert it
    If InStr(_TYPE_,"`n") {
      _struct_:=[] ; keep track of structures (union is just removed because {} = union, struct{} = struct
      _union_:=0   ; init to 0, used to keep track of union depth
      Loop,Parse,_TYPE_,`n,`r`t%A_Space%%A_Tab% ; Parse each line
      {
        _LF_:=""
        Loop,Parse,A_LoopField,`,`;,`t%A_Space%%A_Tab% ; Parse each item
        {
          If RegExMatch(A_LoopField,"^\s*//") ;break on comments and continue main loop
              break
          If (A_LoopField){ ; skip empty lines
              If (!_LF_ && _ArrType_:=RegExMatch(A_LoopField,"[\w\d_#@]\s+[\w\d_#@]")) ; new line, find out data type and save key in _LF_ Data type will be added later
                _LF_:=RegExReplace(A_LoopField,"[\w\d_#@]\K\s+.*$")
              If Instr(A_LoopField,"{"){ ; Union, also check if it is a structure
                _union_++,_struct_.Insert(_union_,RegExMatch(A_LoopField,"i)^\s*struct\s*\{"))
              } else If InStr(A_LoopField,"}") ; end of union/struct
                _offset_.="}"
              else { ; not starting or ending struct or union so add definitions and apply Data Type.
                If _union_ ; add { or struct{
                    Loop % _union_
                      _ArrName_.=(_struct_[A_Index]?"struct":"") "{"
                _offset_.=(_offset_ ? "," : "") _ArrName_ ((_ArrType_ && A_Index!=1)?(_LF_ " "):"") RegExReplace(A_LoopField,"\s+"," ")
                ,_ArrName_:="",_union_:=0
              }
          }
        }
      }
      _TYPE_:=_offset_
    }

    _offset_:=0                 
    ,_union_:=[]                 ; keep track of union level, required to reset offset after union is parsed
    ,_struct_:=[]                ; for each union level keep track if it is a structure (because here offset needs to increase
    ,_union_size_:=[]            ; keep track of highest member within the union or structure, used to calculate new offset after union
    ,_struct_align_:=[]          ; keep track of alignment before structure
    ,_total_union_size_:=0       ; used in combination with above, each loop the total offset is updated if current data size is higher
    ,_align_total_:=0			; used to calculate alignment for total size of structure
	,_in_struct_:=1
    
    ,this["`t"]:=0,this["`r"]:=0 ; will identify a Structure Pointer without members

    ; Parse given structure definition and create struct members
    ; User structures will be resolved by recrusive calls (!!! a structure must be a global variable)
    Loop,Parse,_TYPE_,`,`; ;,%A_Space%%A_Tab%`n`r
    {
      _in_struct_+=StrLen(A_LoopField)+1
      If ("" = _LF_ := trim(A_LoopField,A_Space A_Tab "`n`r"))
        continue
      _LF_BKP_:=_LF_ ;to check for ending brackets = union,struct
      _IsPtr_:=0
      ; Check for STARTING union and set union helpers
       While (_match_:=RegExMatch(_LF_,"i)^(struct|union)?\s*\{\K"))
      ; correct offset for union/structure, sizeof_maxsize returns max size of union or structure
        _max_size_:=sizeof_maxsize(SubStr(_TYPE_,_in_struct_-StrLen(A_LoopField)-1+(StrLen(_LF_BKP_)-StrLen(_LF_))))
        ,_union_.Insert(_offset_+=(_mod_:=Mod(_offset_,_max_size_))?Mod(_max_size_-_mod_,_max_size_):0)
        ,_union_size_.Insert(0)
        ,_struct_align_.Insert(_align_total_>_max_size_?_align_total_:_max_size_)
        ,_struct_.Insert(RegExMatch(_LF_,"i)^struct\s*\{")?(1,_align_total_:=0):0)
        ,_LF_:=SubStr(_LF_,_match_)

      StringReplace,_LF_,_LF_,},,A ;remove all closing brackets (these will be checked later)
      
      ; Check if item is a pointer and remove * for further processing, separate key will store that information
      While % (InStr(_LF_,"*")){
        StringReplace,_LF_,_LF_,*
        _IsPtr_:=A_Index
      }
      ; Split off data type, name and size (only data type is mandatory)
      RegExMatch(_LF_,"^(?<ArrType_>[\w\d\._]+)?\s*(?<ArrName_>[\w\d_]+)?\s*\[?(?<ArrSize_>\d+)?\]?\s*\}*\s*$",_)
      If (!_ArrName_ && !_ArrSize_){
        If RegExMatch(_TYPE_,"^\**" _ArrType_ "\**$"){
          _Struct.___InitField(this,"",0,_ArrType_,_IsPtr_?"PTR":_Struct.HasKey("_" _ArrType_)?_Struct["_" _ArrType_]:"PTR",_IsPtr_,_ArrType_)
          this.base:=_base_
          If (IsObject(_init_)||IsObject(_pointer_)){ ; Initialization of structures members, e.g. _Struct(_RECT,{left:10,right:20})
            for _key_,_value_ in IsObject(_init_)?_init_:_pointer_
            {
              If !this["`r"]{ ; It is not a pointer, assign value
                If InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ",")
                  this.Alloc(_key_,StrLen(_value_)*(InStr(".LPWSTR,LPCWSTR,","," this["`t"] ",")||(InStr(",LPTSTR,LPCTSTR,","," this["`t" _key_] ",")&&A_IsUnicode)?2:1))
                if InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,CHAR,TCHAR,WCHAR,","," this["`t" _key_] ",")
                  this[_key_]:=_value_
                else 
                  this[_key_] := _value_
              }else if (_value_<>"") ; It is not empty
                If _value_ is integer ; It is a new pointer
                  this[_key_][""]:=_value_
            }
          }
          Return this ;:= new _Struct(%_ArrType_%,_pointer_)   ;only Data type was supplied, object/structure has got no members/keys
        } else
          _ArrName_:=_ArrType_,_ArrType_:="UInt"
      }
      If InStr(_ArrType_,"."){ ;check for object that holds structure definition
        Loop,Parse,_ArrType_,.
          If A_Index=1
            _defobj_:=%A_LoopField%
          else _defobj_:=_defobj_[A_LoopField]
      }
      if (!_IsPtr_ && !_Struct.HasKey(_ArrType_)){  ; _ArrType_ not found resolve to global variable (must contain struct definition)
        _offset_+=sizeof(_defobj_?_defobj_:%_ArrType_%,_offset_,_align_total_)-_offset_-sizeof(_defobj_?_defobj_:%_ArrType_%)
        ,_Struct.___InitField(this,_ArrName_,_offset_,_ArrType_,0,0,_ArrType_,_ArrSize_)
        ; update current union size
        If (_uix_:=_union_.MaxIndex()) && (_max_size_:=_offset_ + sizeof(_defobj_?_defobj_:%_ArrType_%) - _union_[_uix_])>_union_size_[_uix_]
          _union_size_[_uix_]:=_max_size_
        _max_size:=0
        ; if not a union or a union + structure then offset must be moved (when structure offset will be reset below
        If (!_uix_||_struct_[_struct_.MaxIndex()])
          _offset_+=this[" " _ArrName_]*sizeof(_defobj_?_defobj_:%_ArrType_%) ; move offset
        ;Continue
      } else {
        If ((_IsPtr_ || _Struct.HasKey(_ArrType_)))
          _offset_+=(_mod_:=Mod(_offset_,_max_size_:=_IsPtr_?A_PtrSize:_Struct[_ArrType_]))=0?0:(_IsPtr_?A_PtrSize:_Struct[_ArrType_])-_mod_
          ,_align_total_:=_max_size_>_align_total_?_max_size_:_align_total_
          ,_Struct.___InitField(this,_ArrName_,_offset_,_ArrType_,_IsPtr_?"PTR":_Struct.HasKey(_ArrType_)?_Struct["_" _ArrType_]:_ArrType_,_IsPtr_,_ArrType_,_ArrSize_)
        ; update current union size
        If (_uix_:=_union_.MaxIndex()) && (_max_size_:=_offset_ + _Struct[this["`n" _ArrName_]] - _union_[_uix_])>_union_size_[_uix_]
          _union_size_[_uix_]:=_max_size_
        _max_size_:=0
        ; if not a union or a union + structure then offset must be moved (when structure offset will be reset below
        If (!_uix_||_struct_[_uix_])
          _offset_+=_IsPtr_?A_PtrSize:(_Struct.HasKey(_ArrType_)?_Struct[_ArrType_]:%_ArrType_%)*this[" " _ArrName_]
      }
      ; Check for ENDING union and reset offset and union helpers
      While (SubStr(_LF_BKP_,0)="}"){
        If (!_uix_:=_union_.MaxIndex()){
          MsgBox,0, Incorrect structure, missing opening braket {`nProgram will exit now `n%_TYPE_%
          ExitApp
        } ; Increase total size of union/structure if necessary
        ; reset offset and align because we left a union or structure
        if (_uix_>1 && _struct_[_uix_-1]){
          if (_mod_:=Mod(_offset_,_struct_align_[_uix_]))
          _offset_+=Mod(_struct_align_[_uix_]-_mod_,_struct_align_[_uix_])
        } else _offset_:=_union_[_uix_]
        if (_struct_[_uix_]&&_struct_align_[_uix_]>_align_total_)
          _align_total_ := _struct_align_[_uix_]
        ; Increase total size of union/structure if necessary
        _total_union_size_ := _union_size_[_uix_]>_total_union_size_?_union_size_[_uix_]:_total_union_size_
        ,_union_._Remove(),_struct_._Remove(),_union_size_._Remove(),_struct_align_.Remove(),_LF_BKP_:=SubStr(_LF_BKP_,1,StrLen(_LF_BKP_)-1) ; remove latest items
        If (_uix_=1){ ; leaving top union, add offset
          if (_mod_:=Mod(_total_union_size_,_align_total_))
			_total_union_size_ += Mod(_align_total_-_mod_,_align_total_)
          _offset_+=_total_union_size_,_total_union_size_:=0
        }
      }
    }
	this.base:=_base_ ; apply new base which uses below functions and uses ___GET for __GET and ___SET for __SET
    If (IsObject(_init_)||IsObject(_pointer_)){ ; Initialization of structures members, e.g. _Struct(_RECT,{left:10,right:20})
      for _key_,_value_ in IsObject(_init_)?_init_:_pointer_
      {
        If !this["`r" _key_]{ ; It is not a pointer, assign value
          If InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ",")
            this.Alloc(_key_,StrLen(_value_)*(InStr(".LPWSTR,LPCWSTR,","," this["`t"] ",")||(InStr(",LPTSTR,LPCTSTR,","," this["`t" _key_] ",")&&A_IsUnicode)?2:1))
          if InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,CHAR,TCHAR,WCHAR,","," this["`t" _key_] ",")
            this[_key_]:=_value_
          else 
            this[_key_] := _value_
        }else if (_value_<>"") ; It is not empty
          if _value_ is integer ; It is a new pointer
            this[_key_][""]:=_value_
      }
    }
    Return this
  }
  ToObj(struct:=""){
		obj:=[]
		for k,v in struct?struct:struct:=this
			if (Asc(k)=10)
				If IsObject(_VALUE_:=struct[_TYPE_:=SubStr(k,2)])
					obj[_TYPE_]:=this.ToObj(_VALUE_)
				else obj[_TYPE_]:=_VALUE_
		return obj
	}
  SizeT(_key_=""){
    return sizeof(this["`t" _key_])
  }
  Size(){
    return sizeof(this)
  }
  IsPointer(_key_=""){
    return this["`r" _key_] 
  }
  Type(_key_=""){
    return this["`t" _key_] 
  }
  AHKType(_key_=""){
    return this["`n" _key_] 
  }
  Offset(_key_=""){
    return this["`b" _key_] 
  }
  Encoding(_key_=""){
    return this["`b" _key_] 
  }
  Capacity(_key_=""){
    return this._GetCapacity("`v" _key_)
  }
  Alloc(_key_="",size="",ptrsize=0){
    If _key_ is integer
      ptrsize:=size,size:=_key_,_key_:=""
   If size is integer
      SizeIsInt:=1
    If ptrsize {
      If (this._SetCapacity("`v" _key_,!SizeIsInt?A_PtrSize+ptrsize:size + (size//A_PtrSize)*ptrsize)="")
        MsgBox % "Memory for pointer ." _key_ ". of size " (SizeIsInt?size:A_PtrSize) " could not be set!"
      else {
        DllCall("RtlZeroMemory","UPTR",this._GetAddress("`v" _key_),"UInt",this._GetCapacity("`v" _key_))
			  If (this[" " _key_]>1){
					ptr:=this[""] + this["`b" _key_]
					If (this["`r" _key_] || InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ","))
						NumPut(ptrs:=this._GetAddress("`v" _key_),ptr+0,"PTR")
					else if _key_
						this[_key_,""]:=ptrs:=this._GetAddress("`v" _key_)
					else this[""]:=ptr:=this._GetAddress("`v" _key_),ptrs:=this._GetAddress("`v" _key_)+(SizeIsInt?size:A_PtrSize)
				} else {
	        If (this["`r" _key_] || InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR,","," this["`t" _key_] ","))
	          NumPut(ptr:=this._GetAddress("`v" _key_),this[""] + this["`b" _key_],"PTR")
	        else this[""]:=ptr:=this._GetAddress("`v" _key_)
	        ptrs:=ptr+(size?size:A_PtrSize)
				}
        Loop % SizeIsInt?(size//A_PtrSize):1
          NumPut(ptrs+(A_Index-1)*ptrsize,ptr+(A_Index-1)*A_PtrSize,"PTR")
      }
    } else {
      If (this._SetCapacity("`v" _key_,SizeIsInt?size:A_PtrSize)=""){
        MsgBox % "Memory for pointer ." _key_ ". of size " (SizeIsInt?size:A_PtrSize) " could not be set!"
      } else
          NumPut(ptr:=this._GetAddress("`v" _key_),this[""] + this["`b" _key_],"PTR"),DllCall("RtlZeroMemory","UPTR",ptr,"UInt",SizeIsInt?size:A_PtrSize)
    }
    return ptr
  }
  ___NEW(init*){
    this:=this.base
    newobj := this.__Clone(1) ;clone structure and keep pointer (1), it will be changed below
    If (init.MaxIndex() && !IsObject(init.1))
      newobj[""] := init.1
    else If (init.MaxIndex()>1 && !IsObject(init.2))
      newobj[""] := init.2
    else
      newobj._SetCapacity("`a",_StructSize_:=sizeof(this)) ; Set Capacity in key ["`a"]
      ,newobj[""]:=newobj._GetAddress("`a") ; Save pointer in key [""]
      ,DllCall("RtlZeroMemory","UPTR",newobj[""],"UInt",_StructSize_) ; zero-fill memory
    If (IsObject(init.1)||IsObject(init.2))
      for _key_,_value_ in IsObject(init.1)?init.1:init.2
          newobj[_key_] := _value_
    return newobj
  }
  
  ; Clone structure and move pointer for new structure
  ___Clone(offset){
    static _base_:={__GET:_Struct.___GET,__SET:_Struct.___SET,__SETPTR:_Struct.___SETPTR,__Clone:_Struct.___Clone,__NEW:_Struct.___NEW
          ,IsPointer:_Struct.IsPointer,Offset:_Struct.Offset,Type:_Struct.Type,AHKType:_Struct.AHKType,Encoding:_Struct.Encoding
          ,Capacity:_Struct.Capacity,Alloc:_Struct.Alloc,Size:_Struct.Size,SizeT:_Struct.SizeT,Print:_Struct.Print,ToObj:_Struct.ToObj}
    If offset=1
      return this
    newobj:={} ; new structure object
    for _key_,_value_ in this ; copy all values/objects
      If (_key_!="`a")
        newobj[_key_]:=_value_ ; add key to new object and assign value
    newobj._SetCapacity("`a",_StructSize_:=sizeof(this)) ; Set Capacity in key ["`a"]
    ,newobj[""]:=newobj._GetAddress("`a") ; Save pointer in key [""]
    ,DllCall("RtlZeroMemory","UPTR",newobj[""],"UInt",_StructSize_) ; zero-fill memory
    If this["`r"]{ ; its a pointer so we need too move internal memory
      NumPut(NumGet(this[""],"PTR")+A_PtrSize*(offset-1),newobj[""],"Ptr")
      newobj.base:=_base_ ;assign base of _Struct
    } else ; do not use internal memory, simply assign new pointer to new structure
      newobj.base:=_base_,newobj[]:=this[""]+sizeof(this)*(offset-1)
    return newobj ; return new object
  }
  ___GET(_key_="",p*){
    If (_key_="")           ; Key was not given so structure[] has been called, return pointer to structure
      Return this[""]
		else if !(idx:=p.MaxIndex())
			_field_:=_key_,opt:="~"
		else {
		  ObjInsert(p,1,_key_)
			opt:=ObjRemove(p),_field_:=_key_:=ObjRemove(p)
			for key_,value_ in p
				this:=this[value_]
		}
    If this["`t"] ; structure without keys/members
      _key_:="" ; set _key_ empty so items below will resolve to our structure
    If (opt!="~"){
      If (opt=""){
        If _field_ is integer
          return (this["`r"]?NumGet(this[""],"PTR"):this[""])+sizeof(this["`t"])*(_field_-1)
        else return this["`r" _key_]?NumGet(this[""]+this["`b" _key_],"PTR"):this[""]+this["`b" _key_] ;+sizeof(this["`t" _key_])*(_field_-1)
      } else If opt is integer
      { ;offset to a item e.g. struct.a[100] ("Uint a[100]")
		; MsgBox % "ja " 
        If (_Struct.HasKey("_" this["`t" _key_]) && this[" " _key_]>1) {
				  If (InStr( ",CHAR,UCHAR,TCHAR,WCHAR," , "," this["`t" _key_] "," )){  ; StrGet 1 character only
					Return StrGet(this[""]+this["`b" _key_]+(opt-1)*sizeof(this["`t" _key_]),1,this["`f" _key_])
				  } else if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," ){ ; StrGet string
					Return StrGet(NumGet(this[""]+this["`b" _key_]+(opt-1)*A_PtrSize,"PTR"),this["`f" _key_])
				  } else {
					Return NumGet(this[""]+this["`b" _key_]+(opt-1)*sizeof(this["`t" _key_]),this["`n" _key_])
				  }
				} else Return new _Struct(this["`t" _key_],this[""]+this["`b" _key_]+(opt-1)*sizeof(this["`t" _key_]))
      } else
        return this[_key_][opt]
    } else If _field_ is integer
    { ; array access (must be listed first because otherwise this["`r" _key_] cannot be resolved
      If (_key_){ ; Offset for item
        return this.__Clone(_field_)
      } else if this["`r"] {
        Pointer:=""
        Loop % (this["`r"]-1) ; dip into one step and return a new structure
          pointer.="*"
        If pointer
          Return new _Struct(pointer this["`t"],NumGet(this[""],"PTR")+A_PtrSize*(_field_-1))
        else Return new _Struct(pointer this["`t"],NumGet(this[""],"PTR")+sizeof(this["`t"])*(_field_-1)).1
      } else if _Struct.HasKey("_" this["`t"]) {
        ; If this[" "]
          ; Return new _Struct(this["`t"],this[""])
        ; else 
				If (InStr( ",CHAR,UCHAR,TCHAR,WCHAR," , "," this["`t"] "," )){  ; StrGet 1 character only
          Return StrGet(this[""]+sizeof(this["`t"])*(_field_-1),1,this["`f"])
        } else if InStr(",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t"] "," ){ ; StrGet string
					Return StrGet(NumGet(this[""]+A_PtrSize*(_field_-1),"PTR"),this["`f"])
        } else { ; resolve pointer
            Return NumGet(this[""]+sizeof(this["`t"])*(_field_-1),this["`n"])
        }
      } else {
			
				; return this.__Clone(_field_)
				; listVars
				; MsgBox % this[""] "+" sizeof(this["`t"])*(_field_-1) "-" this["`t"]
        Return new _Struct(this["`t"],this[""]+sizeof(this["`t"])*(_field_-1))
      }
    } else If this["`r" _key_] { ;pointer
      Pointer:=""
      Loop % (this["`r" _key_]-1) ; dip into one step and return a new structure
          pointer.="*"
      If (_key_=""){
        return this[1][_field_]
      } else {
        Return new _Struct(pointer this["`t" _key_],NumGet(this[""]+this["`b" _key_],"PTR"))
      }
    } else if _Struct.HasKey("_" this["`t" _key_]) { ; default data type, not pointer
      If (this[" " _key_]>1)
        Return new _Struct(this["`t" _key_],this[""] + this["`b" _key_])
      else If (InStr( ",CHAR,UCHAR,TCHAR,WCHAR," , "," this["`t" _key_] "," )){  ; StrGet 1 character only
        Return StrGet(this[""]+this["`b" _key_],1,this["`f" _key_])
      } else if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," ){ ; StrGet string
        Return StrGet(NumGet(this[""]+this["`b" _key_],"PTR"),this["`f" _key_])
      } else {
        Return NumGet(this[""]+this["`b" _key_],this["`n" _key_])
      }
    } else { ; the field is a non pointer structure
      Return new _Struct(this["`t" _key_],this[""]+this["`b" _key_])
    }
  }
  ___SET(_key_,p*){ ;="",_value_=-0x8000000000000000 ,opt="~"){
    If !(idx:=p.MaxIndex()) ; Set new Pointer, here a value was assigned e.g. struct[]:=&var
      return this[""] :=_key_,this._SetCapacity("`a",0) ; free internal memory, it will not be used anymore
    else if (idx=1)
			_value_:=p.1,opt:="~"
		else if (idx>1){
      ObjInsert(p,1,_key_)
			If (p[idx]="")
				opt:=ObjRemove(p),_value_:=ObjRemove(p),_key_:=ObjRemove(p)
      else _value_:=ObjRemove(p),_key_:=ObjRemove(p),opt:="~"
			for key_,value_ in p
				this:=this[value_]
    }
    If this["`t"] ; structure without members
      _field_:=_key_,_key_:="" ; set _key_ empty so it will resolve to our structure
    else _field_:=_key_
    If this["`r" _key_] { ; Pointer
			If opt is integer
        return NumPut(opt,this[""] + this["`b" _key_],"PTR")
      else if this.HasKey("`t" _key_) {
        Pointer:=""
        Loop % (this["`r" _key_]-1) ; dip into one step and return a new structure
          pointer.="*"
        If _key_
          Return (new _Struct(pointer this["`t" _key_],NumGet(this[""] + this["`b" _key_],"PTR"))).1:=_value_
        else Return (new _Struct(pointer this["`t"],NumGet(this[""],"PTR")))[_field_]:=_value_
      } else If _field_ is Integer
       if (_key_="") ; replace this for the operation
        _this:=this,this:=this.__Clone(_Field_)
      If InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," )
        StrPut(_value_,NumGet(NumGet(this[""]+this["`b" _key_],"PTR"),"PTR"),this["`f" _key_]) ; StrPut char to addr+A_PtrSize
      else if InStr( ",TCHAR,CHAR,UCHAR,WCHAR," , "," this["`t" _key_] "," ){ ; same as above but for 1 Character only
        StrPut(_value_,NumGet(this[""]+this["`b" _key_],"PTR"),this["`f" _key_]) ; StrPut char to addr
      } else
        NumPut(_value_,NumGet(this[""]+this["`b" _key_],"PTR"),this["`n" _key_])
      If _field_ is integer ; restore this after operation
        this:=_this
    } else if (RegExMatch(_field_,"^\d+$") && _key_="") {
      if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t"] "," ){ 
        StrPut(_value_,NumGet(this[""]+A_PtrSize*(_field_-1),"PTR"),this["`f"]) ; StrPut string to addr
      } else if InStr( ",TCHAR,CHAR,UCHAR,WCHAR," , "," this["`t" _key_] "," ){
        StrPut(_value_,this[""] + sizeof(this["`t"])*(_field_-1),this["`f"])
      } else
        NumPut(_value_,this[""] + sizeof(this["`t"])*(_field_-1),this["`n"]) ; NumPut new value to key
    } else if opt is integer
    {
      return NumPut(opt,this[""] + this["`b" _key_],"PTR")
    } else if InStr( ",LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR," , "," this["`t" _key_] "," ){ 
      StrPut(_value_,NumGet(this[""] + this["`b" _key_],"PTR"),this["`f" _key_]) ; StrPut string to addr
    } else if InStr( ",TCHAR,CHAR,UCHAR,WCHAR," , "," this["`t" _key_] "," ){
      StrPut(_value_,this[""] + this["`b" _key_],this["`f" _key_]) ; StrPut character key
    } else
      NumPut(_value_,this[""]+this["`b" _key_],this["`n" _key_]) ; NumPut new value to key
    Return _value_
  }
}





; -- BinRun.ahk --

Class _BinRun {
  static IMAGE_DOS_HEADER :="
  (
    WORD   e_magic;                     // Magic number
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // File address of new exe header
  )"
  ,IMAGE_FILE_HEADER :="
  (
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
  )"
  ,IMAGE_DATA_DIRECTORY :="
  (
    DWORD   VirtualAddress;
    DWORD   Size;
  )"
  ,IMAGE_OPTIONAL_HEADER64:="
  (
    WORD        Magic;
    BYTE        MajorLinkerVersion;
    BYTE        MinorLinkerVersion;
    DWORD       SizeOfCode;
    DWORD       SizeOfInitializedData;
    DWORD       SizeOfUninitializedData;
    DWORD       AddressOfEntryPoint;
    DWORD       BaseOfCode;
    ULONGLONG   ImageBase;
    DWORD       SectionAlignment;
    DWORD       FileAlignment;
    WORD        MajorOperatingSystemVersion;
    WORD        MinorOperatingSystemVersion;
    WORD        MajorImageVersion;
    WORD        MinorImageVersion;
    WORD        MajorSubsystemVersion;
    WORD        MinorSubsystemVersion;
    DWORD       Win32VersionValue;
    DWORD       SizeOfImage;
    DWORD       SizeOfHeaders;
    DWORD       CheckSum;
    WORD        Subsystem;
    WORD        DllCharacteristics;
    ULONGLONG   SizeOfStackReserve;
    ULONGLONG   SizeOfStackCommit;
    ULONGLONG   SizeOfHeapReserve;
    ULONGLONG   SizeOfHeapCommit;
    DWORD       LoaderFlags;
    DWORD       NumberOfRvaAndSizes;
    _BinRun.IMAGE_DATA_DIRECTORY DataDirectory[16]; // IMAGE_NUMBEROF_DIRECTORY_ENTRIES
  )"
  ,IMAGE_OPTIONAL_HEADER32 :="
  (
    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;
    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    _BinRun.IMAGE_DATA_DIRECTORY DataDirectory[16]; //IMAGE_NUMBEROF_DIRECTORY_ENTRIES
  )"
  ,IMAGE_NT_HEADERS:="
  (
    DWORD Signature;
    _BinRun.IMAGE_FILE_HEADER FileHeader;
    _BinRun.IMAGE_OPTIONAL_HEADER" (A_PtrSize=8?64:32) " OptionalHeader;
  )"
  ,IMAGE_NT_HEADERS32:="
  (
    DWORD Signature;
    _BinRun.IMAGE_FILE_HEADER FileHeader;
    _BinRun.IMAGE_OPTIONAL_HEADER32 OptionalHeader;
  )"
  ,IMAGE_NT_HEADERS64:="
  (
    DWORD Signature;
    _BinRun.IMAGE_FILE_HEADER FileHeader;
    _BinRun.IMAGE_OPTIONAL_HEADER64 OptionalHeader;
  )"
  ,IMAGE_SECTION_HEADER:="
  (
    BYTE    Name[8];
    union {
        DWORD   PhysicalAddress;
        DWORD   VirtualSize;
    };
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
  )"
  ,FLOATING_SAVE_AREA :="
  (
    DWORD   ControlWord;
    DWORD   StatusWord;
    DWORD   TagWord;
    DWORD   ErrorOffset;
    DWORD   ErrorSelector;
    DWORD   DataOffset;
    DWORD   DataSelector;
    BYTE    RegisterArea[80]; //SIZE_OF_80387_REGISTERS
    DWORD   Cr0NpxState;
  )"
  ,PROCESS_INFORMATION :="
  (
    HANDLE hProcess;
    HANDLE hThread;
    DWORD  dwProcessId;
    DWORD  dwThreadId;
  )"
  ,STARTUPINFO :="
  (
    DWORD  cb;
    LPTSTR lpReserved;
    LPTSTR lpDesktop;
    LPTSTR lpTitle;
    DWORD  dwX;
    DWORD  dwY;
    DWORD  dwXSize;
    DWORD  dwYSize;
    DWORD  dwXCountChars;
    DWORD  dwYCountChars;
    DWORD  dwFillAttribute;
    DWORD  dwFlags;
    WORD   wShowWindow;
    WORD   cbReserved2;
    LPBYTE lpReserved2;
    HANDLE hStdInput;
    HANDLE hStdOutput;
    HANDLE hStdError;
  )"
  ,M128A:="ULONGLONG Low;LONGLONG High"
  ,_XMM_SAVE_AREA32 :="
  (
      WORD ControlWord;
      WORD StatusWord;
      BYTE TagWord;
      BYTE Reserved1;
      WORD ErrorOpcode;
      DWORD ErrorOffset;
      WORD ErrorSelector;
      WORD Reserved2;
      DWORD DataOffset;
      WORD DataSelector;
      WORD Reserved3;
      DWORD MxCsr;
      DWORD MxCsr_Mask;
      _BinRun.M128A FloatRegisters[8];
      _BinRun.M128A XmmRegisters[16];
      BYTE Reserved4[96];
  )"
  ,CONTEXT64:="
  (
      DWORD64 P1Home;
      DWORD64 P2Home;
      DWORD64 P3Home;
      DWORD64 P4Home;
      DWORD64 P5Home;
      DWORD64 P6Home;
      DWORD ContextFlags;
      DWORD MxCsr;
      WORD SegCs;      
      WORD SegDs;      
      WORD SegEs;      
      WORD SegFs;      
      WORD SegGs;      
      WORD SegSs;      
      DWORD EFlags;    
      DWORD64 Dr0;     
      DWORD64 Dr1;     
      DWORD64 Dr2;     
      DWORD64 Dr3;     
      DWORD64 Dr6;     
      DWORD64 Dr7;     
      DWORD64 Rax;     
      DWORD64 Rcx;     
      DWORD64 Rdx;     
      DWORD64 Rbx;     
      DWORD64 Rsp;     
      DWORD64 Rbp;     
      DWORD64 Rsi;     
      DWORD64 Rdi;     
      DWORD64 R8;      
      DWORD64 R9;      
      DWORD64 R10;     
      DWORD64 R11;     
      DWORD64 R12;     
      DWORD64 R13;     
      DWORD64 R14;     
      DWORD64 R15;     
      DWORD64 Rip;     
      union {
          _BinRun._XMM_SAVE_AREA32 FltSave; 
          struct {
              _BinRun.M128A Header[2];     
              _BinRun.M128A Legacy[8];     
              _BinRun.M128A Xmm0;          
              _BinRun.M128A Xmm1;          
              _BinRun.M128A Xmm2;          
              _BinRun.M128A Xmm3;          
              _BinRun.M128A Xmm4;          
              _BinRun.M128A Xmm5;          
              _BinRun.M128A Xmm6;          
              _BinRun.M128A Xmm7;          
              _BinRun.M128A Xmm8;          
              _BinRun.M128A Xmm9;          
              _BinRun.M128A Xmm10;         
              _BinRun.M128A Xmm11;         
              _BinRun.M128A Xmm12;         
              _BinRun.M128A Xmm13;         
              _BinRun.M128A Xmm14;         
              _BinRun.M128A Xmm15;         
          };
      };
      _BinRun.M128A VectorRegister[26];    
      DWORD64 VectorControl;       
      DWORD64 DebugControl;        
      DWORD64 LastBranchToRip;     
      DWORD64 LastBranchFromRip;   
      DWORD64 LastExceptionToRip;  
      DWORD64 LastExceptionFromRip;
  )"
  ,CONTEXT32:="
  (
    DWORD ContextFlags;
    DWORD   Dr0;
    DWORD   Dr1;
    DWORD   Dr2;
    DWORD   Dr3;
    DWORD   Dr6;
    DWORD   Dr7;
    _BinRun.FLOATING_SAVE_AREA FloatSave;
    DWORD   SegGs;
    DWORD   SegFs;
    DWORD   SegEs;
    DWORD   SegDs;
    DWORD   Edi;
    DWORD   Esi;
    DWORD   Ebx;
    DWORD   Edx;
    DWORD   Ecx;
    DWORD   Eax;
    DWORD   Ebp;
    DWORD   Eip;
    DWORD   SegCs;              // MUST BE SANITIZED
    DWORD   EFlags;             // MUST BE SANITIZED
    DWORD   Esp;
    DWORD   SegSs;
    BYTE    ExtendedRegisters[512]; // MAXIMUM_SUPPORTED_EXTENSION
  )"
  __New(pData,cmdLine="",cmdLineScript="",Hide=0,ExeToUse=""){
    static IMAGE_NT_SIGNATURE:=17744,IMAGE_DOS_SIGNATURE:=23117,PAGE_EXECUTE_READWRITE:=64,CREATE_SUSPENDED:=4
    static MEM_COMMIT:=4096,MEM_RESERVE:=8192,STARTF_USESHOWWINDOW:=1
    If pData
      If pData is not digit
      {	
        ; Try first reading the file from Resource
        If res := DllCall("FindResource","PTR",lib:=DllCall("GetModuleHandle","PTR",0,"PTR"),"Str",pData,"PTR",10,"PTR")
          VarSetCapacity(data,sz :=DllCall("SizeofResource","PTR",lib,"PTR",res))
          ,DllCall("RtlMoveMemory","PTR",&data,"PTR",DllCall("LockResource","PTR",hres:=DllCall("LoadResource","PTR",lib,"PTR",res,"PTR"),"PTR"),"PTR",sz)
          ,DllCall("FreeResource","PTR",hres)
          ,BinRun_Uncompress(data)
        else ; else try reading file from disc etc...
          FileRead,Data,*c %pData%
        pData:=&Data
      }
    
    If InStr(cmdLine,"`n"){ ; a script was given, first line contains the cmdLine
      PipeName := "\\.\pipe\AHK" A_TickCount
      __PIPE_GA_ := DllCall("CreateNamedPipe","str",PipeName,"UInt",2,"UInt",0,"UInt",255,"UInt",0,"UInt",0,"PTR",0,"PTR",0)
      __PIPE_    := DllCall("CreateNamedPipe","str",PipeName,"UInt",2,"UInt",0,"UInt",255,"UInt",0,"UInt",0,"PTR",0,"PTR",0)
      if (__PIPE_=-1 or __PIPE_GA_=-1)
        Return 0
      Script:=(A_IsUnicode ? chr(0xfeff) : (chr(239) . chr(187) . chr(191))) SubStr(cmdLine,InStr(cmdLine,"`n")+1)
      cmdLine:=Trim(SubStr(cmdLine,1,InStr(cmdLine,"`n")),"`n`r") A_Space PipeName
    }
  
    IDH:=new _Struct(_BinRun.IMAGE_DOS_HEADER,pData)
    if (IDH.e_magic != IMAGE_DOS_SIGNATURE){
      MsgBox ERROR: e_magic not found
      return
    }
    INH := new _Struct(_BinRun.IMAGE_NT_HEADERS,pData + IDH.e_lfanew)
    
    if (INH.Signature != IMAGE_NT_SIGNATURE){
      MsgBox ERROR: Signature not found
      return
    }

    
    If (A_PtrSize=8&&INH.OptionalHeader.magic=267) ; x86 on x64
      pNtHeader:=new _Struct(_BinRun.IMAGE_NT_HEADERS32,pData + IDH.e_lfanew),ctx:=new _Struct(_BinRun.Context32),Force32Bit:=1
      ,ctx.ContextFlags := (A_PtrSize=8?0x100000:0x10000) | 0x2 ;CONTEXT_INTEGER
      ,UsedExe:=ExeToUse?ExeToUse:A_WinDir "\Microsoft.NET\Framework\v2.0.50727\vbc.exe"
    else if (A_PtrSize=4&&INH.OptionalHeader.magic=523) ; x64 on x86 not possible
      Return false
    else 
      pNtHeader:=INH,UsedExe:=ExeToUse?ExeToUse:A_IsCompiled?A_ScriptFullPath:A_AhkPath
      ,ctx:=new _Struct(A_PtrSize=8?_BinRun.Context64:_BinRun.Context32),ctx.ContextFlags := (A_PtrSize=8?0x100000:0x10000) | 0x2 ;CONTEXT_INTEGER
    pi:=new _Struct(_BinRun.PROCESS_INFORMATION)
    si:=new _Struct(_BinRun.STARTUPINFO),si.cb:=sizeof(si),si.dwFlags:=HIDE?STARTF_USESHOWWINDOW:0 ;si.wShowWindow already set to 0
    if DllCall("CreateProcess","PTR",0,"STR","""" UsedExe """" A_Space cmdLine (cmdLineScript?A_Space cmdLineScript:"")
              ,"PTR",0,"PTR",0,"int",0,"Int",CREATE_SUSPENDED,"PTR",0,"PTR",0,"PTR",si[],"PTR",pi[]){
        if DllCall((Force32Bit?"Wow64":"") "GetThreadContext","PTR",pi.hThread,"PTR", ctx[]){
            pPebImageBase:=ctx[A_PtrSize=8&&!Force32Bit?"Rdx":"Ebx"] + (Force32Bit?4:A_PtrSize)*2
            if DllCall("ReadProcessMemory","PTR",pi.hProcess, "PTR", pPebImageBase,"PTR*", dwImagebase,"PTR", (Force32Bit?4:A_PtrSize),"Uint*",NumberOfBytes){
                DllCall("ntdll\NtUnmapViewOfSection","PTR",pi.hProcess, "PTR",dwImagebase)
                pImagebase := DllCall("VirtualAllocEx","PTR",pi.hProcess, "PTR",pNtHeader.OptionalHeader.ImageBase, "PTR",pNtHeader.OptionalHeader.SizeOfImage,"UInt", MEM_COMMIT|MEM_RESERVE,"UInt", PAGE_EXECUTE_READWRITE,"PTR")
                if (pImagebase)
                {
                    if DllCall("WriteProcessMemory","PTR",pi.hProcess,"PTR",pImagebase,"PTR",pData,"PTR",pNtHeader.OptionalHeader.SizeOfHeaders,"UInt*",NumberOfBytes){
                        pSecHeader :=new _Struct(_BinRun.IMAGE_SECTION_HEADER)
                        pSecHeader[] :=pNtHeader.OptionalHeader[""]+pNtHeader.FileHeader.SizeOfOptionalHeader
                        counter := 0
                        while (++counter < pNtHeader.FileHeader.NumberOfSections+1){
                            DllCall("WriteProcessMemory","PTR",pi.hProcess,"PTR",pImagebase + pSecHeader.VirtualAddress,"PTR",pData + pSecHeader.PointerToRawData,"PTR",pSecHeader.SizeOfRawData,"UInt*", NumberOfBytes)
                            pSecHeader[]:=pSecHeader[]+sizeof(pSecHeader)
                        }
                        if DllCall("WriteProcessMemory","PTR",pi.hProcess,"PTR",pPebImageBase,"PTR",pNtHeader.OptionalHeader.ImageBase[""],"PTR",(Force32Bit?4:A_PtrSize),"UInt*",NumberOfBytes){
                            ctx[A_PtrSize=8&&!Force32Bit?"Rcx":"Eax"] := pImagebase + pNtHeader.OptionalHeader.AddressOfEntryPoint
                            if DllCall((Force32Bit?"Wow64":"") "SetThreadContext","PTR",pi.hThread, "PTR",ctx[]){
                                if DllCall("ResumeThread","PTR",pi.hThread){
                                  if (Script){ ; use pipe to pass script to new executable
                                    DllCall("ConnectNamedPipe","PTR",__PIPE_GA_,"PTR",0)
                                    DllCall("CloseHandle","PTR",__PIPE_GA_)
                                    DllCall("ConnectNamedPipe","PTR",__PIPE_,"PTR",0)
                                    if !DllCall("WriteFile","PTR",__PIPE_,"str",script,"UInt",(StrLen(script)+1)*(A_IsUnicode ? 2 : 1),"UInt*",0,"PTR",0)
                                    Return DllCall("CloseHandle","PTR",__PIPE_),0
                                    DllCall("CloseHandle","PTR",__PIPE_)
                                  }
                                  return pi.dwProcessId
                                }
                            }
                        }
                    }
                }
            }
        }
        DllCall("TerminateProcess","PTR",pi.hProcess,"UInt", 0)
    }
    return FALSE
  }
}
BinRun(pData,cmdLine="",cmdLineScript="",Hide=0,ExeToUse=""){
  return new _BinRun(pData,cmdLine,cmdLineScript,Hide,ExeToUse)
}
BinRun_Uncompress( ByRef D ) {  ; Shortcode version of VarZ_Decompress() of VarZ 2.0 wrapper
; VarZ 2.0 by SKAN, 27-Sep-2012. http://www.autohotkey.com/community/viewtopic.php?t=45559
 IfNotEqual, A_Tab, % ID:=NumGet(D,"UInt"), IfNotEqual, ID, 0x5F5A4C,  Return 0, ErrorLevel := -1
 savedHash := NumGet(D,4,"UInt"), TZ := NumGet(D,10,"UInt"), DZ := NumGet(D,14,"UInt")
 DllCall( "shlwapi\HashData", UInt,&D+8, UInt,DZ+10, UIntP,Hash, UInt,4 )
 IfNotEqual, Hash, %savedHash%, Return 0, ErrorLevel := -2
 VarSetCapacity( TD,TZ,0 ), NTSTATUS := DllCall( "ntdll\RtlDecompressBuffer", UShort
 , NumGet(D,8,"UShort"), PTR, &TD, UInt,TZ, PTR,&D+18, UInt,DZ, UIntP,Final, UInt )
 IfNotEqual, NTSTATUS, 0, Return 0, ErrorLevel := NTSTATUS
 VarSetCapacity( D,Final,0 ), DllCall( "RtlMoveMemory", PTR,&D, PTR,&TD, PTR,Final )
 If NumGet(D,"UInt")=0x315F5A4C && NumPut(0x005F5A4C,D,"UInt")
  Return BinRun_Uncompress( D )
Return Final, VarSetCapacity( D,-1 )
}

But i have a new Problem:

1) It's not working if i have special characters in the exe-filename. (not very important)

2) It's not working if i have 2 or more exe included. Only the first one is installed, the second fail. Any ideas? (important)
Last edited by Taurus on 17 Jun 2015, 09:50, edited 2 times in total.
:beard: Full Stack Developer > Dev for a better world | PHP for Web | AHK H for Local | with KISS (Keep IT Short and Simple) on Win 10 Pro (Version 2004) x64
User avatar
Soft
Posts: 174
Joined: 07 Jan 2015, 13:18
Location: Seoul
Contact:

Re: Creating Installer with 7zip SFX exe - without using Tem

23 Feb 2015, 21:02

use Enigma VirtualBox packer to add resources virtually, or use bxsdk.dll to virtualizes directory
AutoHotkey & AutoHotkey_H v1.1.22.07
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Creating Installer with 7zip SFX exe - without using Tem

23 Feb 2015, 22:55

By the way, does anybody know, if we are able to use the exe without copying it to the ClipboardAll?
BinRun by HotkeyIt.
User avatar
Taurus
Posts: 94
Joined: 20 Jan 2015, 10:31

Re: Creating Installer with 7zip SFX exe - without using Tem

24 Feb 2015, 09:10

Perfect, Thx! I will test it.
:beard: Full Stack Developer > Dev for a better world | PHP for Web | AHK H for Local | with KISS (Keep IT Short and Simple) on Win 10 Pro (Version 2004) x64
User avatar
Taurus
Posts: 94
Joined: 20 Jan 2015, 10:31

Re: Creating Installer with 7zip SFX exe - without using Tem

25 Feb 2015, 11:12

I tested it and it's working. I edit my first post.

One question to that:

How can i send parameters like -o"Path to extract" -y to the exe.

I know its's the second param of BinRun, but i am getting an Error:

"The following variable name contain an illegal character:"
:beard: Full Stack Developer > Dev for a better world | PHP for Web | AHK H for Local | with KISS (Keep IT Short and Simple) on Win 10 Pro (Version 2004) x64
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Creating Installer with 7zip SFX exe - without using Tem

13 May 2015, 03:30

Taurus wrote:I tested it and it's working. I edit my first post.

One question to that:

How can i send parameters like -o"Path to extract" -y to the exe.

I know its's the second param of BinRun, but i am getting an Error:

"The following variable name contain an illegal character:"

Code: Select all

cmdLine := "-o " . """d:\Path to extract"" -y"
MsgBox, % cmdLine
BinRun("YourExeFile.exe", cmdLine )

Return to “Tutorials (v1)”

Who is online

Users browsing this forum: No registered users and 37 guests