You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have been looking into some way to compile GUI deno app to run on Windows with Tauri before, with great success but without making much FFI effort.
Here is what I have (found & made)
First simple method is to change a byte into the deno compile binary from Typescript after it's done.
the other method is directly a suggestion i have made in the denoland/deno repo that adds the -subsystem option in deno compile in order to select if you wish to bundle a GUI app or a console app (windows only)
// --allow-read --allow-write change_exe_subsystem.tsasyncfunctionreadN(r: Deno.Reader,n: number): Promise<Uint8Array|null>{constbuf=newUint8Array(n);letnRead=0;// a null value of r.read() will nullish coalesce into NaN and// polute nRead, causing (nRead < n) to be false and the loop to exitwhile(nRead<n){nRead+=awaitr.read(buf.subarray(nRead))??NaN;}returnisNaN(nRead) ? null : buf;}asyncfunctionwriteAll(w: Deno.Writer,buf: ArrayBufferView): Promise<void>{constbytes=newUint8Array(buf.buffer,buf.byteOffset,buf.byteLength);letnWritten=0;while(nWritten<bytes.byteLength){nWritten+=awaitw.write(bytes.subarray(nWritten));}}functionview(buf: ArrayBufferView){returnnewDataView(buf.buffer,buf.byteOffset,buf.byteLength);}// replace 'my_oak_server.exe' with your server binaryconstPATH_TO_BINARY="./my_oak_server.exe";constbin=awaitDeno.open(PATH_TO_BINARY,{read: true,write: true});// we're going to validate (loosely) that its a valid EXE/MZ// reset to index 0, just to be sureawaitbin.seek(0,Deno.SeekMode.Start);constmagicBytes=awaitreadN(bin,2);if(magicBytes==null){console.log("Encountered EOF at magicBytes");Deno.exit(1);}constbinMagic=newTextDecoder().decode(magicBytes);if("MZ"!=binMagic){console.log(`☹ we didnt find a valid exe at ${PATH_TO_BINARY}`);Deno.exit(1);}// we now know we have a valid exe file// next we need to get the offset of the 'PE Header'constPE_ADDRESS_OFFSET=0x3C;awaitbin.seek(PE_ADDRESS_OFFSET,Deno.SeekMode.Start);// read the peHeaderPointer as 32bit little-endian int/dword/u32constpeHeaderPointerBytes=awaitreadN(bin,4);if(peHeaderPointerBytes==null){console.log("Encountered EOF at peHeaderPointerBytes");Deno.exit(1);}constpeHeaderPointer=view(peHeaderPointerBytes).getUint32(0,true);// we've got the offset of the PE header now// we'll go to that offset, then a further 92 bytes// this is where the subsytem field isawaitbin.seek(peHeaderPointer+92,Deno.SeekMode.Start);// WINDOWS subsystem (don't show a terminal)// CONSOLE subsystem (show a terminal when running)constSUBSYSTEM_WINDOWS=2;constSUBSYSTEM_CONSOLE=3;// before we modify the value we'll do a very rough check// to make sure that we are modifying the right field// we'll need to get it as a little-endian u16constsubsystemBytes=awaitreadN(bin,2);if(subsystemBytes==null){console.log("Encountered EOF at subsystemBytes");Deno.exit(1);}constsubsystem=view(subsystemBytes).getUint16(0,true);if(!(SUBSYSTEM_WINDOWS==subsystem||SUBSYSTEM_CONSOLE==subsystem)){console.log("Oops! The subsystem is not WINDOWS=2 or CONSOLE=3.");console.log("We might be editing the wrong field,");console.log(" _or_ the EXE uses a different subsystem.");Deno.exit(1);}// okay, now we are pretty sure about the file// let's update its subsystemconstnewSubsystemData=newUint16Array(1);view(newSubsystemData).setUint16(0,SUBSYSTEM_WINDOWS,true);// go back to the subsytem fieldawaitbin.seek(peHeaderPointer+92,Deno.SeekMode.Start);// write out our data.awaitwriteAll(bin,newSubsystemData);// finish up with a helpful messageconstnewSubsystemValue=view(newSubsystemData).getUint16(0,true);if(SUBSYSTEM_WINDOWS==newSubsystemValue){console.log(`Done! Changed ${PATH_TO_BINARY} subsystem=2, WINDOWS.`);}elseif(SUBSYSTEM_CONSOLE==newSubsystemValue){console.log(`Done! Changed ${PATH_TO_BINARY} subsystem=3, CONSOLE.`);}
Both are great, but I believe for Astrodon it can be easier to just not "close" the console and instead just make it a real GUI app (Windows will know the difference)
this is a suggestion, let me know what you think.
The text was updated successfully, but these errors were encountered:
I have been looking into some way to compile GUI deno app to run on Windows with Tauri before, with great success but without making much FFI effort.
Here is what I have (found & made)
First simple method is to change a byte into the
deno compile
binary from Typescript after it's done.the other method is directly a suggestion i have made in the denoland/deno repo that adds the -subsystem option in
deno compile
in order to select if you wish to bundle a GUI app or a console app (windows only)From this issue denoland/deno#11638
And my suggestion to add directly to Deno :
denoland/deno#12941
Both are great, but I believe for Astrodon it can be easier to just not "close" the console and instead just make it a real GUI app (Windows will know the difference)
this is a suggestion, let me know what you think.
The text was updated successfully, but these errors were encountered: