如何将java代码嵌入到批处理脚本中?是否可以创建.java / .bat混合?

虽然有一些技术允许您使用一些“本机”Windows脚本语言创建完美 (而不是那么完美 )批处理文件混合。

什么是“完美”混合应该是什么样的:

  1. 嵌入的代码必须按原样使用,并且您应该能够将其复制粘贴到您想要的任何其他编辑器/ IDE中。 对于临时文件和奇怪的转义序列应该没有无穷无尽的回声。(对于支持多行注释的每种语言都是如此)。
  2. 没有“有毒”的错误消息打印(例如/ *将在命令提示符中打印错误,尽管批处理的执行将在下一行继续)
  3. 没有临时文件。除了编译的二进制文件之外,对于没有解释器的语言来说这是不可避免的。

是否有可能创建’完美’的java /批混合?

答案差不多。

主要障碍是我所知道的所有编译器对文件扩展都非常严格,并且拒绝编译任何没有.java扩展名的文件。

由于任何以@开头的批处理文件中的命令都不会显示,我们可以使用java注释来消除来自java注释的错误消息(应该使用.bat扩展名保存):

 @Deprecated /* >nul 2>&1 :: self compiled java/.bat hybrid :: :: deprecated is the only one annotation that can be used outside the class definition :: and is needed for 'mute' start of multi-line java comment :: that will be not printed by the batch file. :: though it still creates two files - the .class and the .java :: it still allows you to embed both batch and java code into one file @echo off setlocal java -version >nul 2>&1 || ( echo java not found exit /b 1 ) ::find class name ::can be different than the script name for /f "usebackq tokens=3 delims=} " %%c in (`type %~f0 ^|find /i "public class"^|findstr /v "for /f"`) do ( set "javaFile=%%c" goto :skip ) :skip copy "%~f0" "%javaFile%.java" >nul 2>&1 javac "%javaFile%.java" java "%javaFile%" ::optional ::del %javaFile%.* >nul 2>&1 end local exit /b 0 *******/ public class TestClass { public static void main(String args[]) { System.out.println("selfcompiled .bat/.java hybrid"); } } 

上面的例子涵盖了第1点和第2点。但是当然仍然需要创建.java文件。静态复制比逐行回显java内容要快。

更进一步 (或半步) – 使.java扩展名像.bat (或几乎)

让我们说你不喜欢代码中找到java类名和自我复制代码的部分。 您可以使.java扩展名像.bat文件一样。或者几乎 – %0将丢失,文件名将存储在%1 。 为此,您需要使用管理员权限调用此批处理文件:

  @echo off :: requires Admin permissions :: allows a files with .JAVA (in this case ) extension to act like .bat/.cmd files. :: Will create a 'caller.bat' asociated with the extension :: which will create a temp .bat file on each call (you can consider this as cheating) :: and will call it. :: Have on mind that the %0 argument will be lost. rem :: "installing" a caller. if not exist "c:\javaCaller.bat" ( echo @echo off echo copy "%%~nx1" "%%temp%%\%%~nx1.bat" /Y ^>nul echo "%%temp%%\%%~nx1.bat" %%* ) > c:\javaCaller.bat rem :: associating file extension assoc .java=javafile ftype javafile=c:\javaCaller "%%1" %%* 

然后自编译的.java文件将如下所示(应使用.java扩展名保存):

 @Deprecated /* >nul 2>&1 :: requires ran javaExtInstaller.bat :: https://github.com/npocmaka/batch.scripts/blob/master/Java/javaExtInstaller.bat :: :: self compiled java/.bat hybrid :: :: deprecated is the only one annotation that can be used outside the class definition :: and is needed for 'mute' start of multi-line java comment :: that will be not printed by the batch file. :: allows you to embed both batch and java code into one file @echo off setlocal java -version >nul 2>&1 || ( echo java not found exit /b 1 ) if not exist "%~n1.class" javac "%~nx1" :: to compile the class every time use: :: javac "%~nx1" java "%~n1" endlocal exit /b 0 *******/ public class TestClass { public static void main(String args[]) { System.out.println("selfcompiled .bat/.java hybrid"); } } 

javaCaller.bat创建temp .bat文件,但它不会“可见”,批处理部分会短得多。

在示例中没有包,因为使用了唯一的单个java文件.Packages只会使示例更难理解。

你没有在备用数据流上看到我的DosTipspost吗? 这种方法具有完美混合脚本所需的所有优点,因为非批处理代码存储在自己的空间 (备用流)中,因此不需要单个附加字符! 可以使用Windows记事本编辑代码。 “唯一”问题是如果java编译器被设计为识别备用数据流。 我用VBS,JScript和PowerShell成功测试了这个方法,但不幸的是我还没有安装java编译器……

但是,检查此方法是否适用于您的java编译器的测试非常简单。 复制下面的代码并使用它创建BatchJavaTest.bat文件:

 @echo off rem Compile the java code stored in this file as an ADS with name "TestClass.java" javac "%~F0:TestClass.java" java "TestClass" 

现在我们需要使用java代码创建ADS。 为此,请在命令行中输入以下内容:

 notepad BatchJavaTest.bat:TestClass.java 

打开记事本时,将以下内容粘贴到其上:

 public class TestClass { public static void main(String args[]) { System.out.println("selfcompiled .bat/.java hybrid from an ADS!"); } } 

保存此文件并测试批处理文件。 这就对了!

请报告结果!

PS – 必须在NTFS磁盘中测试该程序才能使其正常工作……