¿Cómo se puede convertir un archivo .bat a .exe sin herramientas de terceros?

Hay muchas razones para querer ‘convertir’ un .bat a .exe – para ocultar / ocultar la implementación, las contraseñas, la ruta a los recursos, para crear un servicio a partir de un archivo por lotes … y principalmente para hacer que su trabajo parezca más complicado y importante de lo que realmente es

También hay muchas razones para no querer usar herramientas de terceros.

Entonces, ¿qué sucede si desea ‘convertir’ un archivo por lotes a .exe sin software externo? (la conversión se encuentra entre comillas porque no creo que exista una forma de comstackr un archivo por lotes en el ejecutable. Hay demasiadas técnicas y bugs abusivos utilizados ampliamente y todas las herramientas que conozco de hecho crean un archivo .bat temporal y luego llámalo )

Un enfoque muy obvio es utilizar IEXPRESS , la antigua herramienta integrada que crea paquetes autoextraíbles y que es capaz de ejecutar comandos de post extracción. Así que aquí está el archivo IEEPRESS sed-directive /.bat que crea un .exe autoextraíble con .bat empaquetado. Acepta dos argumentos: el archivo .bat que desea convertir y el ejecutable de destino:

  ;@echo off ; rem https://github.com/npocmaka/batch.scripts/edit/master/hybrids/iexpress/bat2exeIEXP.bat ;if "%~2" equ "" ( ; echo usage: %~nx0 batFile.bat target.Exe ;) ;set "target.exe=%__cd__%%~2" ;set "batch_file=%~f1" ;set "bat_name=%~nx1" ;set "bat_dir=%~dp1" ;copy /y "%~f0" "%temp%\2exe.sed" >nul ;(echo()>>"%temp%\2exe.sed" ;(echo(AppLaunched=cmd.exe /c "%bat_name%")>>"%temp%\2exe.sed" ;(echo(TargetName=%target.exe%)>>"%temp%\2exe.sed" ;(echo(FILE0="%bat_name%")>>"%temp%\2exe.sed" ;(echo([SourceFiles])>>"%temp%\2exe.sed" ;(echo(SourceFiles0=%bat_dir%)>>"%temp%\2exe.sed" ;(echo([SourceFiles0])>>"%temp%\2exe.sed" ;(echo(%%FILE0%%=)>>"%temp%\2exe.sed" ;iexpress /n /q /m %temp%\2exe.sed ;del /q /f "%temp%\2exe.sed" ;exit /b 0 [Version] Class=IEXPRESS SEDVersion=3 [Options] PackagePurpose=InstallApp ShowInstallProgramWindow=0 HideExtractAnimation=1 UseLongFileName=1 InsideCompressed=0 CAB_FixedSize=0 CAB_ResvCodeSigning=0 RebootMode=N InstallPrompt=%InstallPrompt% DisplayLicense=%DisplayLicense% FinishMessage=%FinishMessage% TargetName=%TargetName% FriendlyName=%FriendlyName% AppLaunched=%AppLaunched% PostInstallCmd=%PostInstallCmd% AdminQuietInstCmd=%AdminQuietInstCmd% UserQuietInstCmd=%UserQuietInstCmd% SourceFiles=SourceFiles [Strings] InstallPrompt= DisplayLicense= FinishMessage= FriendlyName=- PostInstallCmd= AdminQuietInstCmd= UserQuietInstCmd= 

ejemplo:

 bat2exeIEXP.bat myBatFile.bat MyExecutable.exe 

Esto debería funcionar prácticamente en todas las máquinas de Windows, pero tiene una limitación importante: no se pueden pasar argumentos al archivo .exe creado.

Entonces, otro enfoque posible es mirar los comstackdores .NET (nuevamente debería estar disponible en casi todas las máquinas ganadoras). He elegido Jscript.net . Este es un script híbrido jscript.net / .bat que leerá el contenido del archivo .batch. Creará otro jscript.net con el contenido del archivo .bat y luego de la comstackción creará un nuevo archivo bat en la carpeta temporal y lo llamará .Y aceptará argumentos de línea de comando. (Explicado puede parecer complejo, pero de hecho es simple):

 @if (@X)==(@Y) @end /* JScript comment @echo off setlocal del %~n0.exe /q /s >nul 2>nul for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do ( set "jsc=%%v" ) if not exist "%~n0.exe" ( "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0" ) %~n0.exe "%jsc%" %* del /q /f %~n0.exe 1>nul 2>nul endlocal & exit /b %errorlevel% */ //https://github.com/npocmaka/batch.scripts/blob/master/hybrids/.net/bat2exe.bat import System; import System; import System.IO; import System.Diagnostics; var arguments:String[] = Environment.GetCommandLineArgs(); if (arguments.length<3){ Console.WriteLine("Path to cmd\bat file not given"); Environment.Exit(1); } var binName=Path.GetFileName(arguments[2])+".exe"; if(arguments.length>3){ binName=Path.GetFileName(arguments[3]); } var batchContent:byte[]= File.ReadAllBytes(arguments[2]); var compilerLoc=arguments[1]; var content="[" for (var i=0;i 

Es más bien un POC, pero las bibliotecas System.Diagnostics y System.IO de .NET son lo suficientemente poderosas como para agregar funciones como inicio oculto, enctiption, etc. También puede verificar las opciones de comstackción de jsc.exe para ver qué más es capaz de hacer (como agregar recursos )

Prometo un voto a favor de cada mejora sobre el método .NET 🙂

ACTUALIZACIÓN: la segunda secuencia de comandos se ha cambiado y ahora el archivo exe del bat convertido se puede iniciar con doble clic. Utiliza la misma interfaz que la secuencia de comandos anterior:

 bat2exejs.bat example.bat example.exe