For an integrated resource linker, you can detatch the console and parsing utilities. Then use LinkResources() directly.
LinkRes
'
'https://docs.microsoft.com/en-us/windows/win32/menurc/resource-file-formats
$ Filename "LinkRes.exe"
uses RTL64
uses kernel
%NoConsole
uses console
indexbase 1
type ResHead1
dword DataSize
dword HeaderSize
end type
type ResHead2
dword DataVersion
word MemFlags
word LangId
dword Version
dword Charistics
end type
function RetResType (int ResType) as string
===========================================
'
select ResType
case 0x0000 : return "NULL"
case 0x0001 : return "Cursor"
case 0x0002 : return "Bitmap"
case 0x0003 : return "Icon"
case 0x0004 : return "Menu"
case 0x0005 : return "Dialog"
case 0x0006 : return "String Table"
case 0x0007 : return "Font Directory"
case 0x0008 : return "Font"
case 0x0009 : return "Accelerators Table"
case 0x000A : return "RC Data (custom binary data)"
case 0x000B : return "Message table"
case 0x000C : return "Group Cursor"
case 0x000E : return "Group Icon"
case 0x0010 : return "Version Information"
case 0x0011 : return "Dialog Include"
case 0x0013 : return "Plug'n'Play"
case 0x0014 : return "VXD"
case 0x0015 : return "Animated Cursor"
case 0x0018 : return "Manifest"
case 0x2002 : return "Bitmap (new version)"
case 0x2004 : return "Menu (new version)"
case 0x2005 : return "Dialog (new version)"
end select
'
return "Unknown"
end function
function RetMemFlags (int flags) as string
==========================================
if flags = 0 then return "None"
string MemFlags
if flags and 0x10 then MemFlags="MOVEABLE"
if flags and 0x20 then MemFlags+=" PURE"
if flags and 0x40 then MemFlags+=" PRELOAD"
if flags and 0x1000 then MemFlags+=" DISCARDABLE"
return MemFlags
end function
function AddResources(string ResFile, TgtFile, int verbose=0) as int
====================================================================
sys hRes
sys ResBase
sys ResData
sys ResLen
sys ResPos
sys ResName
sys ResType
wchar* ResNameStr
wchar* ResTypeStr
wchar* unihead
int HeadOffset
int UniSize
int DataSpace
int Result
ResHead1 *rh1
ResHead2 *rh2
string ResBuf
ResBuf=getfile(ResFile)
if not ResBuf
print "File not found: " ResFile cr
return 1
endif
'
hRes=BeginUpdateResource(TgtFile, 1) ' File to add the resource to
if not hRes
print "BeginUpdateResource failed..."
return 1
endif
'
ResBase=strptr(ResBuf)
ResLen = len(ResBuf)
ResPos = 0
int rhe1 = sizeof(rh1)
int rhe2 = sizeof(rh2)
while ResPos < ResLen
@rh1=ResBase + ResPos
UniSize = rh1.HeaderSize - rhe1
Unisize=(Unisize + 3) and 0x7ffffffc 'dword align
@Unihead=ResBase + ResPos + rhe1 'unicode/ordinal data then rh2
@rh2 = @UniHead + UniSize - rhe2
'
' Get the resource type
word *w
wchar st[64],sn[64]
int i
'
@w=@unihead 'word overlay
if w=0xffff
ResType=w[2]
st=RetResType(ResType)
@ResTypeStr = @st
HeadOffset=4 'dword
else
@ResTypeStr=@Unihead 'unicode
ResType=@ResTypestr
'
'locate unicode null terminator
i=0
while w<>0
i+=2 : @w+=2
wend
HeadOffset=i+2 'for start of ResName
endif
'
' Get the resource name
word w at @unihead+HeadOffset
if w=0xffff
ResName = w[2]
sn=str(ResName)
@ResNameStr = @sn
else
@ResNameStr = @unihead+HeadOffset
ResName = @ResNameStr
endif
if Verbose
string rt,rn
rt=ResTypeStr
rn=ResNameStr
print "DataSize = " rh1.DataSize cr
print "HeaderSize = " rh1.HeaderSize cr
print "ResType = " rt cr
print "ResName = " rn cr
print "DataVersion = " rh2.DataVersion cr
print "MemFlags = " RetMemFlags(rh2.MemFlags) cr
print "LangId = " rh2.LangId cr
print "Version = " rh2.Version cr
print "Charistics = " rh2.Charistics cr
print string(60, "-") cr
endif
'
ResPos += rhe1 + UniSize 'ready for ResData
ResData = ResBase+ResPos
DataSpace = (rh1.DataSize+3) and 0x7ffffffc
'
ResPos+=DataSpace
'
if rh1.DataSize
if not UpdateResourceW( hRes, ResType, ResName, rh2.LangId, ResData, rh1.DataSize)
print "UpdateResource failed..."
Result = 1
exit while
endif
endif
wend
if not EndUpdateResource(hRes, Result)
print "EndUpdateResource failed..." cr
Result = 1
endif
return Result
end function
indexbase 1
int swd,lenw,ascw,ascn
sub SkipSpace(string*s, int*i)
==============================
byte bb at strptr(s)
do
ascn=bb[i]
select ascn
case 0 : exit do
'case 65 to 90 : ascn+=32 : exit do 'force lowercase
case 33 to 255 : exit do
end select
i++
loop
end sub
function GetWord(string*s, int*i) as string
===========================================
byte bb at strptr(s)
skipspace(s,i)
swd=i
do
ascn=bb[i]
select ascn
case 0 to 32 : exit do
case 34 : i=instr(i+1,s,chr(ascn))
if i=0
i=len(s)
endif
end select
i++
loop
lenw=i-swd
skipspace(s,i)
if lenw>0
return mid(s,swd,lenw)
endif
end function
function CommandLineArgs() as string
====================================
string s,command
int i=1
Command = (char*) GetCommandLine
s=GetWord command,i 'step over command filepath\file
SkipSpace command,i
return mid Command, i
end function
function main() as int
======================
int vb=0
int i=1
string s=lcase(CommandLineArgs())
string resfile=getword(s,i)
string tgtfile=getword(s,i)
string opts=getword(s,i)
'
AttachConsole(-1) 'attach to console of parent process
sys ho=GetStdHandle( STD_OUTPUT_HANDLE )
if ho<>consout then consout=ho 'Windows10
'
if tgtfile
if opts="-verbose"
vb=1
endif
function = AddResources(resfile, tgtfile, vb)
else
print " LinkRes 2019" cr " LinkRes file.res file.exe [-verbose]" cr
endif
FreeConsole
end function
return main()