forked from AutoHotkey/Ahk2Exe
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Compiler.ahk
138 lines (111 loc) · 3.82 KB
/
Compiler.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#Include ScriptParser.ahk
#Include IconChanger.ahk
AhkCompile(ByRef AhkFile, ExeFile="", ByRef CustomIcon="", BinFile="", UseMPRESS="", fileCP="")
{
global ExeFileTmp
AhkFile := Util_GetFullPath(AhkFile)
if AhkFile =
Util_Error("Error: Source file not specified.")
SplitPath, AhkFile,, AhkFile_Dir,, AhkFile_NameNoExt
if ExeFile =
ExeFile = %AhkFile_Dir%\%AhkFile_NameNoExt%.exe
else
ExeFile := Util_GetFullPath(ExeFile)
;ExeFileTmp := ExeFile
ExeFileTmp := Util_TempFile()
if BinFile =
BinFile = %A_ScriptDir%\AutoHotkeySC.bin
Util_DisplayHourglass()
IfNotExist, %BinFile%
Util_Error("Error: The selected AutoHotkeySC binary does not exist.", 1, BinFile)
try FileCopy, %BinFile%, %ExeFileTmp%, 1
catch
Util_Error("Error: Unable to copy AutoHotkeySC binary file to destination.")
BinType := AHKType(ExeFileTmp)
DerefIncludeVars.A_AhkVersion := BinType.Version
DerefIncludeVars.A_PtrSize := BinType.PtrSize
DerefIncludeVars.A_IsUnicode := BinType.IsUnicode
BundleAhkScript(ExeFileTmp, AhkFile, CustomIcon, fileCP)
if FileExist(A_ScriptDir "\mpress.exe") && UseMPRESS
{
Util_Status("Compressing final executable...")
RunWait, "%A_ScriptDir%\mpress.exe" -q -x "%ExeFileTmp%",, Hide
}
; the final step...
try FileCopy, %ExeFileTmp%, %ExeFile%, 1
catch
Util_Error("Error: Could not copy final compiled binary file to destination.")
Util_HideHourglass()
Util_Status("")
}
BundleAhkScript(ExeFile, AhkFile, IcoFile="", fileCP="")
{
; weird bug prevention, for non working default param 'fileCP'
if fileCP is space
fileCP := A_FileEncoding
try FileEncoding, %fileCP%
catch e
Util_Error("Error: Invalid codepage parameter """ fileCP """ was given.")
SplitPath, AhkFile,, ScriptDir
ExtraFiles := []
PreprocessScript(ScriptBody, AhkFile, ExtraFiles)
;FileDelete, %ExeFile%.ahk
;FileAppend, % ScriptBody, %ExeFile%.ahk
VarSetCapacity(BinScriptBody, BinScriptBody_Len := StrPut(ScriptBody, "UTF-8") - 1)
StrPut(ScriptBody, &BinScriptBody, "UTF-8")
module := DllCall("BeginUpdateResource", "str", ExeFile, "uint", 0, "ptr")
if !module
Util_Error("Error: Error opening the destination file.")
if IcoFile
{
Util_Status("Changing the main icon...")
if !ReplaceAhkIcon(module, IcoFile, ExeFile)
{
; Error was already displayed
gosub _EndUpdateResource
Util_Error("Error changing icon: Unable to read icon or icon was of the wrong format.")
}
}
Util_Status("Compressing and adding: Master Script")
if !DllCall("UpdateResource", "ptr", module, "ptr", 10, "str", IcoFile ? ">AHK WITH ICON<" : ">AUTOHOTKEY SCRIPT<"
, "ushort", 0x409, "ptr", &BinScriptBody, "uint", BinScriptBody_Len, "uint")
goto _FailEnd
oldWD := A_WorkingDir
SetWorkingDir, %ScriptDir%
for each,file in ExtraFiles
{
Util_Status("Compressing and adding: " file)
StringUpper, resname, file
IfNotExist, %file%
goto _FailEnd2
; This "old-school" method of reading binary files is way faster than using file objects.
FileGetSize, filesize, %file%
VarSetCapacity(filedata, filesize)
FileRead, filedata, *c %file%
if !DllCall("UpdateResource", "ptr", module, "ptr", 10, "str", resname
, "ushort", 0x409, "ptr", &filedata, "uint", filesize, "uint")
goto _FailEnd2
VarSetCapacity(filedata, 0)
}
SetWorkingDir, %oldWD%
gosub _EndUpdateResource
return
_FailEnd:
gosub _EndUpdateResource
Util_Error("Error adding script file:`n`n" AhkFile)
_FailEnd2:
gosub _EndUpdateResource
Util_Error("Error adding FileInstall file:`n`n" file)
_EndUpdateResource:
if !DllCall("EndUpdateResource", "ptr", module, "uint", 0)
Util_Error("Error: Error opening the destination file.")
return
}
Util_GetFullPath(path)
{
VarSetCapacity(fullpath, 260 * (!!A_IsUnicode + 1))
if DllCall("GetFullPathName", "str", path, "uint", 260, "str", fullpath, "ptr", 0, "uint")
return fullpath
else
return ""
}