从.bat,.exe和其他一些数据文件创建Windows可执行文件

时间:2017-01-18 16:36:36

标签: windows batch-file

我有一个必须使用以下语法调用的应用程序app.exe:

 app.exe -c COM1 <data file>

我还有一个名为data.dat的数据文件。所以我创建了一个launch.bat脚本:

app.exe -c COM1 data.dat

我想创建一个单个可执行文件 app_launcher.exe,它应该自动提取临时目录中的三个文件并自动启动launch.bat脚本。我希望在app.exe完成后自动删除这三个文件。

我应该使用哪种技术?

1 个答案:

答案 0 :(得分:0)

我设计了一种有趣的方法,将几个文本文件和一个二进制文件组合成一个批处理文件,可以以任何所需的方式提取和操作它们。诀窍在于组合批处理文件中的所有文件,然后通过一个命令块读取其内容,并将其输入重定向到批处理文件,因此可以单独读取其自身的不同部分。例如:

@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 ...

要生成工作批处理文件,请将此基本代码与二进制.exe文件组合使用:

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

但是,此方法受findstr.exe命令读取二进制数据的功能限制,因此根据二进制文件的内容,它可能有效,也可能无效。

为了解决这一问题,我编写了一个非常简单的辅助.exe程序,它只是从重定向的文件句柄中读取字节并将它们输出到Stdout。使用这个名为ReadFile.exe的程序,可以将任何二进制文件嵌入到批处理文件中并将其解压缩。这是使用findstr.exe文件作为示例二进制文件的此方法示例的输出:

C:\Users\Antonio\Documents\ASMB\test> copy base.bat +findstr.exe /B working.bat /B

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

C:\Users\Antonio\Documents\ASMB\test> ren findstr.exe findstr2.exe

C:\Users\Antonio\Documents\ASMB\test> working

C:\Users\Antonio\Documents\ASMB\test> fc /B findstr.exe findstr2.exe
Comparando archivos findstr.exe y FINDSTR2.EXE
FC: no se han encontrado diferencias

要获取ReadFile.exe辅助文件,请下载并执行此批处理文件:

@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]

这是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

注意ReadFile可以读取一定数量的字节;这意味着使用它,并且给定适当的大小,可以在同一个批处理文件中嵌入几个二进制文件!的 ;)