如何将.bat文件转换为'没有第三方工具的.exe?

时间:2015-01-27 15:45:27

标签: .net iexpress batch-file

有许多理由想要转换' .bat.exe - 隐藏/混淆实施,密码,资源路径,从批处理文件创建服务......主要是为了让您的工作看起来比实际更复杂和重要是

还有很多理由不想使用第三方工具。

那么,如果你想要转换'没有外部软件的.exe批处理文件? (转换是引号,因为我不认为有可能将批处理文件编译成可执行文件。有太多滥用的错误技术和广泛使用的错误,我知道的所有工具实际上创建了一个临时.bat文件,然后调用它)

5 个答案:

答案 0 :(得分:48)

一个非常明显的方法是使用IEXPRESS - 古老的内置工具,它可以创建自解压包,并且能够执行提取后命令。 所以这里的IEXPRESS sed-directive /。bat文件创建了一个带有压缩.bat的自解压.exe文件。 它接受两个参数 - 要转换的.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编译器(几乎每个win机器上都应该可用)。我选择 Jscript.net 。 这是一个混合jscript.net / .bat脚本,它将读取.batch文件内容。将使用.bat文件内容创建另一个jscript.net,并在编译后将在temp中创建一个新的bat文件文件夹,并将调用它。并将接受命令行参数。(解释可能看起来很复杂,但实际上它很简单):

@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方法的每一项改进提出建议: - )

UPDATE:第二个脚本已更改,现在可以通过双击启动转换后的bat文件中的exe。它使用与以前脚本相同的界面:

bat2exejs.bat example.bat example.exe

答案 1 :(得分:1)

我确实知道如何将bat / cmd手动转换为exe,请确保bat / cmd文件名仅包含字母和数字。以管理员身份打开“ IExpress Wizard”。

  1. 选择“创建新的自我提取指令文件”
  2. 选择“提取文件并运行安装命令”
  3. 给包裹起任何名字
  4. “无提示”为“确认提示”
  5. “许可协议”的“不显示许可”
  6. 点击“添加”作为“打包文件”,然后从其中选择bat / cmd文件
  7. 然后在“要启动的安装程序”的“安装程序”文本框中,键入cmd /c,后跟bat / cmd文件的全名,(例如:emptyrecyclebin.bat => {{ 1}})
  8. 按原样保留“安装后命令”
  9. “隐藏”为“显示窗口”
  10. “已完成的邮件”为“无邮件”
  11. 点击“浏览”,然后选择将exe下载到的位置
  12. 启用“从用户隐藏文件提取进度动画”
  13. 禁用“在包中使用长文件名存储文件”
  14. 对于“配置重启”绝对是“不重启”
  15. 如果您想稍后重新编译,则保存SED
  16. 然后创建包!命令窗口应迅速出现并消失
  17. 导航到您将exe下载到的位置, 享受

答案 2 :(得分:1)

您还可以开发一个简单的exe,该exe可以调用您的蝙蝠脚本。

例如,您可以用C#编写一个(我不是C#-Pro,这实际上是我的第一个程序,我从this other 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();
    }
}

如果将上面的代码存储在MySuperApp.bat旁边的MySuperApp.cs中,然后使用csc.exe /target:winexe MySuperApp.cs进行编译(甚至可以添加/win32icon:MySuperApp.ico来添加精美的图标),它将生成一个MySuperApp .exe。

启动MySuperApp.exe将调用MySuperApp.bat(同名的bat文件)。

csc.exe(应该?)是present on every Windows machine

答案 3 :(得分:1)

不同版本的Windows对相同的批处理文件命令具有不同的效果,并且某些命令仅限于某些Windows系统。 findstrshutdown
顺便说一句,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版本上都需要一个不同的编译器,最好是用相同的指令集吐出可以在尽可能多的CPU芯片上运行的二进制代码(通用)。大多数程序提供的解决方法是将脚本包装在exe文件中,该文件将在打开/运行时解包并执行脚本。 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操作不会在没有主机的情况下运行该文件。系统。

答案 4 :(得分:-2)

I found this answer on superuser.

在两个之中,我必须说bat到exe转换器是最好的。它允许Icon添加并运行带有管理员清单,版本信息,一些内置示例和编辑器的新创建的.exe

GUI的屏幕截图。

enter image description here

贷记到rammi


我强烈建议您使用2个免费程序来创建EXE批处理文件

1 - Bat To Exe Converter

2 - Bat 2 Exe

您可以通过简单的GUI使用这两个程序。

Bat To Exe Converter还支持CLI命令(\?标志以获取帮助)。文档中的基本示例:

Bat_To_Exe_Converter.exe -bat mybatfile.bat -save myprogram.exe -icon myicon