Adding multiple files to the EXE - Petr - 03-06-2023
To add more files to EXE you will need the programs listed in this thread, but first also the PMF2 compressor program which is in the previous thread: https://staging.qb64phoenix.com/showthread.php?tid=1532&pid=14125#pid14125
Be careful what you do, I always recommend COPYING the program to another folder and putting the files there. I've tried it all and it's a working procedure. The described procedure assumes that you have already created a PMF2 file that contains all the files you need to include in the EXE file.
STEP 1:
Code: (Select All) 'STEP 1: Your EXE file is named Step1 (for example, but EXE file name must be the same as second parameter for ExtractExe!)
' Copy to this EXE ExtractEse, and all need sources for PMF2 extractor as in this example
' DO NOT RUN IT, MAKE EXE FILE ONLY and then goto step 2 in example 2 for completing this operation.
Type Header ' Header 1
ID As String * 4 ' file format signature PMF2
Files_Total As Long ' how much files container contains
End Type
Type File_List ' Header 2
FileNameLEN As _Unsigned _Byte 'Lenght for file name (example: Untitled.bas = file name lenght = 12)
Compress As _Unsigned _Byte ' Compression. 0 = not used, 1 = used (_INFLATE$)
Offset As Long ' Area in file (offset) where start this file data
BlockSize As Long ' Byte size (how much bytes is used for this file in PMF2 container, size after compression if used)
End Type
Dim Shared PMF2H As Header
ReDim Shared PMF2FL(0) As File_List 'each added file has its own index in this field
Const Show = -1
Const Unpack_All = 0
ExtractExe "archive.pmf2", "Step1.exe" 'get PMF2 from EXE
_Delay 1 'is need!
UnPack_PMF2 "archive.pmf2", Unpack_All ' get files from PMF2
'your program is here
End
Sub ExtractExe (OutputFile As String, ThisExeFile As String)
Dim As Long ExeSize
TEF = FreeFile
Open ThisExeFile For Binary As #TEF
Get #TEF, LOF(TEF) - 3, ExeSize
' Print "Original EXE size: "; ExeSize
If ExeSize < 0 Then Print "Invalid record.": End
OutputFileBinary$ = Space$(LOF(TEF) - ExeSize - 4)
Get #TEF, ExeSize + 1, OutputFileBinary$
Close #TEF
' Print "V RAM je "; Len(OutputFileBinary$); "bytes"
Open OutputFile For Binary As #TEF
Put #TEF, , OutputFileBinary$
OutputFileBinary$ = ""
Close #TEF
End Sub
Sub UnPack_PMF2 (ArchiveName As String, METHOD As _Byte)
'method: -1 = show files in PMF2 file
' 0 = UnPack all files from PMF2 file
' > 0 = Unpack file writed in this position in PMF2 file (-1) - use record number printed in Show mode
If _FileExists(ArchiveName) Then
FF = FreeFile
Open ArchiveName For Binary As FF
Get FF, , PMF2H ' read head 1
If PMF2H.ID = "PMF2" Then
If PMF2H.Files_Total > -1 Then
ReDim As File_List PMF2FL(PMF2H.Files_Total)
Get FF, , PMF2FL() ' read head 2
ReDim As String Names(PMF2H.Files_Total)
For ReadFileNames = 0 To PMF2H.Files_Total ' read files names in file
N$ = Space$(PMF2FL(ReadFileNames).FileNameLEN)
Get FF, , N$
Names(ReadFileNames) = N$
N$ = ""
Next
Select Case METHOD ' This is information block (Show)
Case -1
Print "Pos. File name Compressed Size in PMF2 file [bytes]"
Print "-----------------------------------------------------------------"
For ReadContent = 0 To PMF2H.Files_Total
F_Name$ = Names(ReadContent)
If Len(F_Name$) > 15 Then F_Name$ = Mid$(F_Name$, 1, 12) + "..."
If PMF2FL(ReadContent).Compress Then F_Compress$ = "Yes" Else F_Compress$ = "No"
F_Size& = PMF2FL(ReadContent).BlockSize
ddd = Len(LTrim$(Str$(ReadContent)))
Print LTrim$(Str$(ReadContent + 1)) + "."; Spc(4 - ddd); F_Name$; Spc(18 - Len(F_Name$) + ddd); F_Compress$; Spc(12); F_Size&
If ReadContent Mod 18 = 0 And ReadContent > 0 Then
Print "Press any key for next..."
Sleep
Cls
Print "Pos. File name Compressed Size in PMF2 file [bytes]"
Print "-----------------------------------------------------------------"
End If
Next
Case 0 ' extract it
For UnPack = 0 To PMF2H.Files_Total
If _FileExists(Names(UnPack)) Then 'add automaticaly parentheses and number, if file exists
u = 0
Do Until _FileExists(Names(UnPack)) = 0
Dot = InStr(1, Names(UnPack), ".") - 1
Test$ = Mid$(Names(UnPack), 1, Dot) + "(" + _Trim$(Str$(u) + ")") + Right$(Names(UnPack), PMF2FL(UnPack).FileNameLEN - Dot)
If _FileExists(Test$) = 0 Then Names(UnPack) = Test$
Test$ = ""
u = u + 1
Loop
End If
EF = FreeFile
Open Names(UnPack) For Binary As EF
N$ = Space$(PMF2FL(UnPack).BlockSize)
Get FF, , N$
If PMF2FL(UnPack).Compress Then Rec$ = _Inflate$(N$) Else Rec$ = N$
Put EF, , Rec$
N$ = ""
Rec$ = ""
Close EF
Next UnPack
Case Is > 0 ' unpack just one concrete file
Fi = METHOD - 1
If Fi > UBound(Names) Then Print "Invalid record add as parameter for Unpack_PMF2 SUB!": Sleep 3: End
If _FileExists(Names(Fi)) Then 'add automaticaly parentheses and number, if file exists
u = 0
Do Until _FileExists(Names(Fi)) = 0
Dot = InStr(1, Names(Fi), ".") - 1
Test$ = Mid$(Names(Fi), 1, Dot) + "(" + _Trim$(Str$(u) + ")") + Right$(Names(Fi), PMF2FL(Fi).FileNameLEN - Dot)
If _FileExists(Test$) = 0 Then Names(Fi) = Test$
Test$ = ""
u = u + 1
Loop
End If
EF = FreeFile
Open Names(Fi) For Binary As EF
N$ = Space$(PMF2FL(Fi).BlockSize)
Seek FF, PMF2FL(Fi).Offset
Get FF, , N$
If PMF2FL(Fi).Compress Then Rec$ = _Inflate$(N$) Else Rec$ = N$
Put EF, , Rec$
N$ = ""
Rec$ = ""
Close EF
End Select
Else
Print "Invalid record: Number of files in PMF2 file: "; PMF2H.Files_Total: Sleep 3: End
End If
Else
Print "Invalid PMF2 file format. ": Sleep 3: End
End If
Else
Print "PMF2 file: "; ArchiveName$; " not exists. Can not continue.": Sleep 3: End
End If
End Sub
Place to your program PMF2 headers and source code as in this example. COMPILE IT, DO NOT RUN IT! We need EXE file named Step1.exe, this program is named as Step1.bas it is very important for correct function!
Then, when EXE file is done, we can add files to EXE - Step 2:
Code: (Select All) 'STEP 2: USE PMF2 archiver for compress more files to PMF2 and then insert it to EXE file.
AddToExe "pmf2test2023.pmf2", "step1.exe"
End
Sub AddToExe (File As String, ExeFile As String)
Dim As Long FileSize
If _FileExists(ExeFile) Then
If _FileExists(File) Then
Af = FreeFile
Open File For Binary As #Af
FileBin$ = Space$(LOF(Af))
Get #Af, , FileBin$
Close #Af
Af = FreeFile
Open ExeFile For Binary As #Af
FileSize = LOF(Af)
Seek #Af, LOF(Af) + 1
Put #Af, , FileBin$
Put #Af, , FileSize
Close #Af
FileBin$ = ""
Else Print "Sorry, file "; File; "not exists"
End If
Else Print "Sorry, file "; ExeFile; "not exists."
End If
End Sub
Program insert archive file pmf2test2023.pmf2 to file test1.exe
If you do all correct, after running program Step1.exe all files from PMF2 are extracted to harddrive.
If there is interest, I am willing to modify the output of PMF2 so that the files are not saved to the hard disk, but to the computer's memory.
But then of course you have to have your own solution for working with these yours files.
|