Opret en Windows-eksekverbar fra en .bat, .exe og nogle andre datafiler

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har en applikation app.exe, der skal kaldes med følgende syntaks:


 app.exe -c COM1 <data file>


Jeg har også en datafil, der hedder data.dat. Så jeg oprettede et launch.bat script:


app.exe -c COM1 data.dat


Jeg vil gerne oprette en enkeltkørbar app\_launcher.exe, der automatisk skal udpakke de tre filer i en midlertidig mappe og automatisk starte launch.bat scriptet. Jeg vil have de tre filer slettet automatisk, når app.exe er færdig.


Hvilken teknologi skal jeg bruge?

Bedste reference


Jeg udtænkte en interessant metode til at kombinere flere tekstfiler plus en binær fil i en Batch-fil, der kan udtrække og manipulere dem på en hvilken som helst ønsket måde. Tricket består i at kombinere alle filer i Batch-filen og derefter læse indholdet via en blok kommandoer med dens input omdirigeret til Batch-filen, så forskellige dele af sig selv kan læses separat. For eksempel:


@echo off
setlocal EnableDelayedExpansion

< "\%~F0" (

   rem Skip this Batch code: 20 lines
   for /L \%\%i in (1,1,20) do set /P =

   rem Copy the data file: 2 lines
   (for /L \%\%i in (1,1,2) do (
      set /P "line="
      echo !line!
   )) > data.txt

   rem Copy the rest of this file into an .exe
   findstr "^" > theProgram.exe

)

goto :EOF
These are the lines
of the data file
... the binary code of the .exe file ...
... must be placed here ...


For at generere den fungerende Batch-fil kombineres denne baskode med den binære .exe-fil på denne måde:


copy base.bat +theProgram.exe /B working.bat /B


Denne metode er dog begrænset af kapaciteterne i findstr.exe kommandoen til at læse binære data, så det kan eller måske ikke virker afhængigt af indholdet af den binære fil.


For at rette dette punkt skrev jeg et meget simpelt ekstra .exe-program, der bare læser bytes fra et omdirigeret filhåndtag og sender dem til Stdout. Ved hjælp af dette program, kaldet ReadFile.exe, er det muligt at indlejre enhver binær fil i en Batch-fil og uddrage den. Dette er resultatet af et eksempel på denne metode ved hjælp af findstr.exe-filen som eksemplet binærfil:


C:UsersAntonioDocumentsASMB	est> copy base.bat +findstr.exe /B working.bat /B

base.bat
findstr.exe
        1 archivo(s) copiado(s).

C:UsersAntonioDocumentsASMB	est> ren findstr.exe findstr2.exe

C:UsersAntonioDocumentsASMB	est> working

C:UsersAntonioDocumentsASMB	est> fc /B findstr.exe findstr2.exe
Comparando archivos findstr.exe y FINDSTR2.EXE
FC: no se han encontrado diferencias


For at få ReadFile.exe hjælpefil download og udfør denne Batch-fil:


@echo off
setlocal EnableDelayedExpansion

rem Create ReadFile.exe auxiliary program
rem Antonio Perez Ayala

echo Creating ReadFile.exe file, please wait...
rem Code modified based on :genchr subroutine
type nul > t.tmp
set "options=/d compress=off /d reserveperdatablocksize=26"
(for /F \%\%a in ('more +49 "\%~F0"') do (
   set input=\%\%a
   set i=0
   for /L \%\%I in (0,2,120) do for \%\%i in (!i!) do if "!input:~\%\%i,1!" neq "" (
      set hex=!input:~\%\%i,2!
      set /A i+=2
      if "!hex:~0,1!" neq "[" (
         set /A chr=0x!hex!
         if not exist !chr!.chr call :genchr !chr!
         type !chr!.chr
      ) else (
         for /L \%\%J in (1,1,5) do for \%\%i in (!i!) do if "!input:~\%\%i,1!" neq "]" (
            set "hex=!hex!!input:~\%\%i,1!"
            set /A i+=1
         )
         if not exist 0.chr call :genchr 0
         for /L \%\%J in (1,1,!hex:~1!) do type 0.chr
         set /A i+=1
      )
   )
)) > ReadFile.exe
del *.chr t.tmp temp.tmp
exit /B


:genchr
REM This code creates one single byte. Parameter: int
REM Teamwork of carlos, penpen, aGerman, dbenham
REM Tested under Win2000, XP, Win7, Win8
if \%~1 neq 26 (
   makecab \%options\% /d reserveperfoldersize=\%~1 t.tmp \%~1.chr > nul
   type \%~1.chr | ( (for /l \%\%N in (1,1,38) do pause)>nul & findstr "^" > temp.tmp )
   >nul copy /y temp.tmp /a \%~1.chr /b
) else (
   copy /y nul + nul /a 26.chr /a >nul
)
exit /B


4d5a900003[3]04[3]ffff[2]b8[7]40[35]b0[3]0e1fba0e00b409cd21b8014ccd21546869732070726f6772616d2063616e6e6f742062
652072756e20696e20444f53206d6f64652e0d0d0a24[7]55917b8611f015d511f015d511f015d59fef06d51bf015d5edd007d513f015d5
5269636811f015d5[8]5045[2]4c01020069629657[8]e0000f010b01050c0002[3]02[7]10[3]10[3]20[4]40[2]10[3]02[2]04[7]04[8]
30[3]02[6]03[5]10[2]10[4]10[2]10[6]10[11]2020[2]28[84]20[2]20[27]2e74657874[3]4801[3]10[3]02[3]02[14]20[2]602e
7264617461[2]dc[4]20[3]02[3]04[14]40[2]40[8]e806[3]50e81301[2]558bec83c4ece8da[3]e8f9[3]c745ec[4]0fb606460ac00f
84b3[3]2c30040af7d850e8f0[3]8945fcb8f5ffffff50e8e2[3]8945f8e8c4[3]0fb6064633db0ac00f8483[3]eb038a06463c30720e3c
39770a2c308d1c9b8d1c58ebebe8aa[3]85c074688bd068[2]04006a0052e8a3[3]85c074558bf88bcb0bc97505b9[2]040081f9[2]0400
7605b9[2]04006a008d45f4505157ff75fce87b[3]6a008d45f050ff75f457ff75f8e86f[3]8b45f00145ec394df472090bdb74b72b5df4
75b28b45ecc9c3b8ffffffffc9c3cccccce84d[3]8bf08a06463c2275098a06463c2275f9eb0c8a06463c20740484c075f54ec38a06463c
2074f94ec3ccff2518204000ff2500204000ff2504204000ff2508204000ff250c204000ff2510204000ff25142040[185]7620[2]8820[2]
9820[2]a420[2]b020[2]bc20[2]6820[6]4820[10]ce20[3]20[22]7620[2]8820[2]9820[2]a420[2]b020[2]bc20[2]6820[6]9b0045
78697450726f6365737300560147657450726f6365737348656170[2]6a0147657453746448616e646c65[2]bd0148656170416c6c6f63
003d025265616446696c65[2]f702577269746546696c6500e600476574436f6d6d616e644c696e6541006b65726e656c33322e646c6c[294]


Dette er hjælp fra ReadFile.exe:


Read bytes from a redirected input file handle and output they to StdOut.

ReadFile handle numOfBytes

If numOfBytes is zero, read all bytes from current FP position until EOF.

At end, the number of output bytes is returned in ERRORLEVEL.

An example of this program is shown at:
http://www.dostips.com/forum/viewtopic.php?f=3&t=6236&p=42161#p42161


Bemærk, at ReadFile kan læse et bestemt antal byte; Det betyder, at det er muligt at indlejre flere binære filer i samme Batch-fil, hvis du bruger det og givet de rigtige størrelser. ;)