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

时间:2015-01-28 10:39:32

标签: java batch-file

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

什么是'完美'混合应该是这样的:

  1. 嵌入式代码必须按原样使用,您应该有能力 将其复制粘贴到您想要的任何其他编辑器/ IDE中。应该有 对临时文件和奇怪的转义序列没有无穷无尽的回声 支持多行评论的每种语言均可使用。)
  2. 没有“有毒”的错误消息打印(例如 / * 会打印错误 在命令提示符中,尽管批处理将继续执行 在下一行)
  3. 没有临时文件。除了编译的二进制文件之外 对于没有翻译的语言来说是不可避免的。
  4. 是否可以创建'完美'的java / batch hybrid?

2 个答案:

答案 0 :(得分:3)

答案差不多。

主要障碍是我所知道的所有编译器对文件扩展名都非常严格,并拒绝编译任何没有.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");
    }
}

.bat仍然会创建一个临时javaCaller.bat文件,但它不会“可见”,批量部分会更短。

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

答案 1 :(得分:1)

你没有在备用数据流上看到my DosTips post吗?这种方法具有完美混合脚本所需的所有优点,因为非批处理代码存储在自己的空间(备用流)中,所以它不需要一个额外的字符!可以使用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磁盘中测试此程序才能使其正常工作......