Как файл.bat "конвертировать" в.exe без сторонних инструментов?

Есть много причин, чтобы хотеть "преобразовать" .bat в .exe - скрыть / запутать реализацию, пароли, путь к ресурсам, создать сервис из командного файла... и, главным образом, сделать вашу работу более сложной и важной, чем она есть на самом деле.

Есть также много причин, чтобы не использовать сторонние инструменты.

Так что, если вы хотите "преобразовать" командный файл в .exe без внешнего софта? (convert находится в кавычках, потому что я не думаю, что на самом деле есть способ скомпилировать командный файл в исполняемый файл. Существует слишком много ошибочных извилистых методов и ошибок, которые широко используются, и все инструменты, которые я знаю, фактически создают временные .bat файл, а затем назвать его)

7 ответов

Решение

Один очень очевидный подход заключается в использовании IEXPRESS - древнего встроенного инструмента, который создает самораспаковывающиеся пакеты и способен выполнять команды после извлечения. Итак, вот файл IEXPRESS sed-directive /.bat, который создает самораспаковывающийся.exe с упакованным.bat. Он принимает два аргумента - файл.bat, который вы хотите преобразовать, и целевой исполняемый файл:

 ;@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=

пример:

bat2exeIEXP.bat  myBatFile.bat MyExecutable.exe

Это должно работать практически на каждой машине с Windows, но имеет одно важное ограничение - вы не можете передавать аргументы в созданный файл.exe

Так что еще один возможный подход - посмотреть на.NET-компиляторы (опять же, они должны быть доступны почти на каждой выигрышной машине). Я выбрал Jscript.net. Это гибрид jscript.net/.bat скрипт, который будет читать содержимое файла.batch. Создаст еще один jscript.net с содержимым файла.bat, а после компиляции создаст новый файл bat в папке temp и вызовет его. И примет аргументы командной строки. может показаться сложным, но на самом деле все просто):

@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);

Это скорее POC, но библиотеки.NET System.Diagnostics и System.IO достаточно мощные, чтобы добавлять такие функции, как скрытый запуск, шифрование и т. Д. Вы также можете проверить параметры компиляции jsc.exe, чтобы увидеть, на что еще способен (например, добавить ресурсы).).

Я обещаю приветствовать каждое улучшение по сравнению с методом.NET:-)

ОБНОВЛЕНИЕ: второй скрипт был изменен, и теперь исполняемый файл из преобразованного файла bat может быть запущен двойным щелчком. Он использует тот же интерфейс, что и предыдущий скрипт:

bat2exejs.bat example.bat example.exe

Я знаю, как конвертировать bat/cmd в exe вручную, убедитесь, что имя файла bat/cmd содержит только буквы и цифры. Откройте " Мастер IExpress" в качестве администратора.

  1. Выберите "Создать новый файл директивы самоизвлечения"
  2. Выберите "Извлечь файлы и запустить команду установки".
  3. Назовите пакет что-нибудь
  4. "Нет запроса" для "Подтверждение запроса"
  5. "Не отображать лицензию" для "Лицензионного соглашения"
  6. Нажмите "Добавить" для "Упакованных файлов", оттуда выберите файл bat/cmd
  7. Затем в текстовом поле "Установить программу" для "Установить программу для запуска" введите cmd /cс последующим полным именем файла bat/cmd (пример: emptyrecyclebin.bat => cmd /c emptyrecyclebin.bat)
  8. Оставьте "Команду после установки" как есть
  9. "Скрыто" для "Показать окно"
  10. "Нет сообщения" для "Готового сообщения"
  11. Нажмите "Обзор" и выберите, куда загрузить файл
  12. Включить "Скрыть файл извлечения анимации прогресса от пользователя"
  13. Отключить "Хранить файлы, используя длинное имя файла внутри пакета"
  14. Определенно "Нет перезагрузки" для "Настроить перезагрузку"
  15. Затем сохраните SED, если вы хотите перекомпилировать его быстрее
  16. Тогда создайте пакет! Окно команд должно быстро появиться и исчезнуть
  17. Перейдите к месту, где вы скачали исполняемый файл, и наслаждайтесь!

Все вышеперечисленные методы никоим образом не защищают ваш исходный код. Недавно я увидел в новостях пресс-релиз о новом компиляторе, не зависящем от CMD.exe. Я точно не знаю, как это работает, но он не создает временные файлы во время выполнения. https://www.prlog.org/12882479-the-worlds-first-true-compiler-for-batch-files.html

Вы также можете разработать простой exe-файл, который просто вызывает ваш bat-скрипт.

Например, вы могли бы написать один на C# (я не C#-Pro, это на самом деле моя первая программа, и я скопировал много из этого другого поста Stackru.):

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();
    }
}

Если вы сохраните этот код выше в MySuperApp.cs рядом с MySuperApp.bat, а затем скомпилируете его с csc.exe /target:winexe MySuperApp.cs (и, возможно, даже добавить /win32icon:MySuperApp.ico чтобы добавить причудливый значок), он сгенерирует MySuperApp.exe.

Запуск MySuperApp.exe вызовет MySuperApp.bat (bat-файл с тем же именем).

csc.exe (должен?) присутствовать на каждом компьютере с Windows.

Различные версии Windows имеют разные эффекты для одних и тех же команд командного файла, а некоторые команды ограничены некоторыми системами Windows, например. findstr а также shutdown.
Кстати, Win 10 CMD не позволяет изменятьSETLOCALв командной строке. ОК для командных файлов.

См. По этой ссылке различные команды для перезапуска разных версий Windows:https://www.computerhope.com/issues/ch000321.htm

Поэтому, если бы вы скомпилировали сценарий в Win 98 и запустили в Win 8.1, вы бы получили неожиданные результаты, или сценарии могут даже не работать. См. Список команд здесь:https://www.ionos.com/digitalguide/server/know-how/windows-cmd-commands/

По этой причине для каждой версии Windows потребуется отдельный компилятор, предпочтительно, который будет выдавать двоичный код (общий), который можно запускать на максимально возможном количестве микросхем ЦП с одинаковыми наборами инструкций. Обходной путь, предлагаемый большинством программ, заключается в том, чтобы обернуть сценарий в исполняемый файл, который будет разворачивать и выполнять сценарий при открытии / запуске, например. Bat_To_Exe_Converter, Bat2Exe, BatchCompiler, iexpress или Winzip:https://support.winzip.com/hc/en-us/articles/115011794948-What-is-a-Self-Extracting-Zip-File-

Чтобы решить эту проблему переносимости, виртуальные машины стали более популярными, что привело к появлению Java и связанных скриптов.

Однако это все равно будет интерпретируемым кодом, а не таким быстрым, как скомпилированный код. Даже байт-код (промежуточный код) виртуальных машин все равно нужно компилировать, даже если он (JIT):https://aboullaite.me/understanding-jit-compiler-just-in-time-compiler/

Короче говоря, вы можете получить exe-файл, который будет содержать скрипт, который будет интерпретироваться командным процессором, но он не будет собственным исполняемым файлом, то есть он не будет работать без хоста операционной системой Windows.

Пакетный компилятор (http://batchcompile.com) - лучшее бесплатное решение для компиляции пакетных файлов. вы можете включить информацию о версии, информацию об авторских правах, значки, ресурсы и графику.

Я нашел этот ответ на суперпользователе.

Из двух я должен сказать, что конвертер bat в exe является лучшим. Это позволяет Icon добавлять и запускать вновь созданные.exe с манифестом администратора, информацией о версиях, некоторыми встроенными примерами и редактором.

Скриншот графического интерфейса.

Кредит Рамми


Вот 2 бесплатные программы, которые я настоятельно рекомендую для создания EXE из командных файлов.

1 - Конвертер Bat в Exe

2 - Летучая мышь 2 Exe

Вы можете использовать обе программы с простым графическим интерфейсом.

Bat To Exe Converter поддерживает также команды CLI (\?флаг для помощи). Базовый пример из документации:

Bat_To_Exe_Converter.exe -bat mybatfile.bat -save myprogram.exe -icon myicon
Другие вопросы по тегам