/Compiler.ahk

http://github.com/fincs/Ahk2Exe · AutoHotKey · 133 lines · 100 code · 26 blank · 7 comment · 14 complexity · dda9494e05a964d8568772df850f1823 MD5 · raw file

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