Hoe kan een .bat-bestand worden ‘geconverteerd’ naar .exe zonder tools van derden?

Er zijn veel redenen om een ​​.batnaar .exete willen ‘converteren’ – om implementatie, wachtwoorden, pad naar bronnen te verbergen/verdoezelen, om een ​​service te maken uit batchbestand … en vooral om uw werk er ingewikkelder en belangrijker uit te laten zien dan het in werkelijkheid is.

Er zijn ook veel redenen om geen tools van derden te willen gebruiken.

Dus wat als je een batchbestand wilt ‘converteren’ naar .exezonder externe software?
(converteren staat tussen aanhalingstekens omdat ik niet denk dat er echt een manier is om een ​​batchbestand naar uitvoerbaar te compileren. Er zijn te veel beledigende, kronkelige technieken en bugs die uitgebreid worden gebruikt en alle tools die ik ken, maken in feite een tijdelijke .batbestand en noem het dan )


Antwoord 1, autoriteit 100%

Een zeer voor de hand liggende benadering is het gebruik van IEXPRESS– de oude ingebouwde tool die zelf -pakketten uitpakken en is in staat om commando’s na het uitpakken uit te voeren.
Dus hier is IEXPRESSsed-directive/.bat-bestand dat een zelf-uitpakkend .exe met ingepakt .bat aanmaakt.
Het accepteert twee argumenten – het .bat-bestand dat u wilt converteren en het uitvoerbare doelbestand:

;@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=<None>
AdminQuietInstCmd=
UserQuietInstCmd=

voorbeeld:

bat2exeIEXP.bat  myBatFile.bat MyExecutable.exe

Dit zou praktisch op elke Windows-machine moeten werken, maar heeft één belangrijke beperking: je kunt geen argumenten doorgeven aan het gemaakte .exe-bestand

Dus een andere mogelijke benadering is om naar de .NET-compilers te kijken (opnieuw beschikbaar op bijna elke win-machine). Ik heb gekozen voor Jscript.net.
Dit is een hybride jscript.net/.bat-script dat de inhoud van het .batch-bestand zal lezen. Zal een ander jscript.net maken met de inhoud van het .bat-bestand en na de compilatie zal een nieuw bat-bestand in de tijdelijke map maken en het aanroepen.En zal opdrachtregelargumenten accepteren.(uitgelegd ziet er misschien ingewikkeld uit, maar is in feite eenvoudig):

@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<batchContent.length-1;i++){
    content=content+batchContent[i]+","
}
content=content+batchContent[batchContent.length-1]+"]";
var temp=Path.GetTempPath();
var dt=(new Date()).getTime();
var tempJS=temp+"\\2exe"+dt+".js";
var toCompile="\r\n\
import System;\r\n\
import System.IO;\r\n\
import  System.Diagnostics;\r\n\
var batCommandLine:String='';\r\n\
//Remove the executable name from the command line\r\n\
try{\r\n\
var arguments:String[] = Environment.GetCommandLineArgs();\r\n\
batCommandLine=Environment.CommandLine.substring(arguments[0].length,Environment.CommandLine.length);\r\n\
}catch(e){}\r\n\
var content2:byte[]="+content+";\r\n\
var dt=(new Date()).getTime();\r\n\
var temp=Path.GetTempPath();\r\n\
var nm=Process.GetCurrentProcess().ProcessName.substring(0,Process.GetCurrentProcess().ProcessName.length-3);\r\n\
var tempBatPath=Path.Combine(temp,nm+dt+'.bat');\r\n\
File.WriteAllBytes(tempBatPath,content2);\r\n\
var pr=System.Diagnostics.Process.Start('cmd.exe','/c '+' '+tempBatPath+' '+batCommandLine);\r\n\
pr.WaitForExit();\r\n\
File.Delete(tempBatPath);\r\n\
";
File.WriteAllText(tempJS,toCompile);
var pr=System.Diagnostics.Process.Start(compilerLoc,'/nologo /out:"'+binName+'" "'+tempJS+'"');
pr.WaitForExit();
File.Delete(tempJS);

Het is eerder een POC , maar .NET System.Diagnostics en System.IO-bibliotheken zijn krachtig genoeg om functies zoals hidden start , enctiption en etc. toe te voegen. Je kunt ook de jsc.exe-compileeropties controleren om te zien wat er nog meer kan ( zoals het toevoegen van bronnen).

Ik beloof een upvote voor elke verbetering ten opzichte van de .NET-methode 🙂

UPDATE:het tweede script is gewijzigd en nu kan de exe van het geconverteerde bat-bestand worden gestart met dubbelklikken. Het gebruikt dezelfde interface als het vorige script:

bat2exejs.bat example.bat example.exe

Antwoord 2, autoriteit 7%

Ik weet wel hoe ik bat/cmd handmatig naar exe moet converteren, zorg ervoor dat de bat/cmd-bestandsnaam alleen letters en cijfers bevat. Open ‘IExpress Wizard‘ als beheerder.

  1. Selecteer ‘Nieuw bestand met zelfextractierichtlijn maken’
  2. Selecteer ‘Bestanden uitpakken en een installatieopdracht uitvoeren’
  3. Geef het pakket een naam
  4. ‘Geen prompt’ voor ‘Bevestigingsprompt’
  5. ‘Geen licentie weergeven’ voor ‘Licentieovereenkomst’
  6. Klik op ‘Toevoegen’ voor de ‘Verpakte bestanden’, selecteer daar het bat/cmd-bestand
  7. Typ vervolgens in het tekstvak ‘Programma installeren’ voor ‘Programma installeren om te starten’ cmd /c, gevolgd door de volledige naam van het bat/cmd-bestand, (voorbeeld: emptyrecyclebin.bat=> cmd /c emptyrecyclebin.bat)
  8. Laat de ‘Post Install Command’ ongewijzigd
  9. ‘Verborgen’ voor ‘Venster weergeven’
  10. ‘Geen bericht’ voor ‘Beëindigd bericht’
  11. Klik op ‘Bladeren’ en selecteer waar u de exe wilt downloaden
  12. Schakel ‘Bestand uitpakken van voortgangsanimatie verbergen van gebruiker’ in
  13. Schakel ‘Bestanden opslaan met lange bestandsnaam in pakket’ uit
  14. Absoluut ‘Geen herstart’ voor ‘Configureer herstart’
  15. Sla SED vervolgens op als u het later sneller opnieuw wilt compileren
  16. Vervolgens maak het pakket!Een opdrachtvenster zou snelmoeten verschijnen en verdwijnen
  17. Navigeer naar de plaats waar je de exe hebt gedownload, enveel plezier!

Antwoord 3, autoriteit 2%

Je kunt ook een eenvoudige exe ontwikkelen, die gewoon je bat-script aanroept.

Je zou er bijvoorbeeld een kunnen schrijven in C# (ik ben geen C#-Pro, dit is eigenlijk mijn eerste programma en ik heb er veel van gekopieerd van deze andere Stackoverflow-post.):

using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.IO;
class BatCaller {
    static void Main() {
        var batFile = System.Reflection.Assembly.GetEntryAssembly().Location.Replace(".exe", ".bat");
        if (!File.Exists(batFile)) {
            MessageBox.Show("The launch script could not be found.", "Critical error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            System.Environment.Exit(42);
        }
        var processInfo = new ProcessStartInfo("cmd.exe", "/c \"" + batFile + "\"");
        processInfo.CreateNoWindow = true;
        processInfo.UseShellExecute = false;
        processInfo.RedirectStandardError = true;
        processInfo.RedirectStandardOutput = true;
        var process = Process.Start(processInfo);
        process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => Console.WriteLine("output>>" + e.Data);
        process.BeginOutputReadLine();
        process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => Console.WriteLine("error>>" + e.Data);
        process.BeginErrorReadLine();
        process.WaitForExit();
        Console.WriteLine("ExitCode: {0}", process.ExitCode);
        process.Close();
    }
}

Als u deze code hierboven opslaat in MySuperApp.cs net naast MySuperApp.bat en deze vervolgens compileert met csc.exe /target:winexe MySuperApp.cs(en misschien zelfs /win32icon:MySuperApp.icoom een ​​mooi pictogram toe te voegen) genereert het een MySuperApp.exe.

Het starten van MySuperApp.exeroept MySuperApp.bat aan (het bat-bestand met dezelfde naam).

csc.exe(zou moeten?) aanwezig zijn op elke Windows-machine.


Antwoord 4, autoriteit 2%

Verschillende versies van Windows hebben verschillende effecten voor dezelfde opdrachten in batchbestanden, en sommige opdrachten zijn beperkt tot sommige Windows-systemen, bijv. findstren shutdown.
Trouwens, Win 10 CMD staat geen wijzigingen toe aan SETLOCALop de opdrachtregel. OK voor batchbestanden.

Zie deze link voor verschillende commando’s voor het herstarten van verschillende versies van Windows:
https://www.computerhope.com/issues/ch000321.htm

Dus als je een script zou compileren op Win 98 en zou draaien op Win 8.1, zou je onverwachte resultaten krijgen of scripts werken misschien niet eens.
Bekijk hier de lijst met opdrachten:
https://www.ionos.com/digitalguide/server /know-how/windows-cmd-commands/

Om deze reden zou men op elke versie van Windows een andere compiler nodig hebben, die bij voorkeur binaire code (generiek) zou uitspugen die op zoveel mogelijk CPU-chips kan worden uitgevoerd, met dezelfde instructiesets. Een tijdelijke oplossing die door de meeste programma’s wordt aangeboden, is om het script in een exe-bestand te verpakken dat het script zou uitpakken en uitvoeren wanneer het bijvoorbeeld werd geopend/uitgevoerd. Bat_To_Exe_Converter, Bat2Exe, BatchCompiler, iexpress of Winzip:
https:/ /support.winzip.com/hc/en-us/articles/115011794948-What-is-a-Self-Extracting-Zip-File-

Om dit probleem van overdraagbaarheid op te lossen, zijn virtuele machines populairder geworden en vandaar de opkomst van Java & gerelateerde scripts.

Dit zou echter nog steeds geïnterpreteerde code zijn, en niet zo snel als gecompileerde code. Zelfs bytecode (tussenliggende code) van virtuele machines moet nog worden gecompileerd, ook al is het (JIT):
https://aboullaite.me/understanding-jit-compiler-just -in-time-compiler/

Kortom, je kunt een exe-bestand krijgen dat een script zou bevatten dat zou worden geïnterpreteerd door de opdrachtprocessor, maar het zal geen native uitvoerbaar bestand zijn, wat betekent dat het niet kan worden uitgevoerd zonder een host door het Windows-besturingssysteem systeem.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

four × 5 =

Other episodes