如何创建批处理文件以运行位于系统任何位置的jar文件

时间:2015-01-08 21:06:12

标签: java batch-file jar

我有一个MyFile.jar文件。我需要一个批处理文件来搜索jar文件并触发它。

我找到了以下解决方案。但是对于那个批处理文件和jar文件必须在同一个文件夹中。

java -jar %~dp0MyFile.jar %*

我们不知道客户端将jar文件放在他们的系统中的哪个位置。但是他们会将批处理文件放在启动文件夹中。

编辑:我现在设法写了这个批处理文件。

`ECHO
 ECHO Locating the Jar

 IF EXIST java -jar MyFile.jar  ELSE (GOTO 

 SearchJar)

:SearchJar
SET the_path=D: & CD\
DIR /S/B File.jar > installer_location.txt
SET /P the_path=< installer_location.txt
if defined the_path goto :FoundIt

E: & CD\
DIR /S/B MyFile.jar > installer_location.txt
SET /P the_path=< installer_location.txt
if defined the_path goto :FoundIt

C: & CD\
DIR /S/B MyFile.jar > installer_location.txt
SET /P the_path=< installer_location.txt
if defined the_path goto :FoundIt

G: & CD\
DIR /S/B MyFile.jar > installer_location.txt
SET /P the_path=< installer_location.txt
if defined the_path goto :FoundIt

H: & CD\
DIR /S/B MyFile.jar > installer_location.txt
SET /P the_path=< installer_location.txt
if defined the_path goto :FoundIt

I: & CD\
DIR /S/B MyFile.jar > installer_location.txt
SET /P the_path=< installer_location.txt
if defined the_path goto :FoundIt
ECHO Jar not found.

:FoundIt
ECHO Jar file found at %the_path%

CALL java -jar %the_path%`

这在我的系统中正在运行。但我不确定是否会有一种更简单的方法来检查所有驱动器。

2 个答案:

答案 0 :(得分:1)

正如gknicker和我在上面评论的那样,这是它应该做的方式。如果您使用安装程序(如NSIS或类似程序)来部署.jar文件和.bat脚本,请让安装程序编写注册表值,并且可能永远不需要搜索或文件浏览。如果在安装后移动.jar文件,则弹出GUI file chooser并让用户浏览到他保存的位置MyFile.jar。将更新的位置保存到注册表。重新提示是否再次移动文件。

@echo off
setlocal enabledelayedexpansion

set "jarfile=MyFile.jar"
set "regkey=HKLM\Software\Company Name"
set "regvalue=jarfile"

set jarpath=
for /f "tokens=2*" %%I in ('reg query "%regkey%" /v "%regvalue%" 2^>NUL') do (
    set "jarpath=%%~J"
)

if not exist "%jarpath%" (
    call :chooser jarpath "%jarfile%" "%jarfile% (*.jar)|*.jar"
)

if exist "%jarpath%" (
    reg add "%regkey%" /v "%regvalue%" /t REG_SZ /d "%jarpath%" /f 2>&1>NUL
) else (
    <NUL set /P "=Unable to locate %jarfile%.  This thread will self-destruct in 5 seconds... "
    ping -n 6 0.0.0.0 >NUL
    echo bang.
    exit /b 1
)

java -jar "%jarpath%"

goto :EOF

:chooser <var_to_set> <filename> <filter>
:: based on https://stackoverflow.com/questions/15885132

setlocal enabledelayedexpansion
:: Does powershell.exe exist within %PATH%?
for %%I in (powershell.exe) do if "%%~$PATH:I" neq "" (
    set chooser=powershell "Add-Type -AssemblyName System.windows.forms|Out-Null;$f=New-Object System.Windows.Forms.OpenFileDialog;$f.InitialDirectory='%cd%';$f.Filter='%~3';$f.showHelp=$true;$f.Title='Locate %~2';$f.ShowDialog()|Out-Null;$f.FileName"
) else (
rem :: If not, compose and link C# application to open file browser dialog
    set chooser=%temp%\chooser.exe
    >"%temp%\c.cs" echo using System;using System.Windows.Forms;
    >>"%temp%\c.cs" echo class dummy{
    >>"%temp%\c.cs" echo public static void Main^(^){
    >>"%temp%\c.cs" echo OpenFileDialog f=new OpenFileDialog^(^);
    >>"%temp%\c.cs" echo f.InitialDirectory=Environment.CurrentDirectory;
    >>"%temp%\c.cs" echo f.Filter="%~3";
    >>"%temp%\c.cs" echo f.ShowHelp=true;
    >>"%temp%\c.cs" echo f.Title="Locate %~2";
    >>"%temp%\c.cs" echo f.ShowDialog^(^);
    >>"%temp%\c.cs" echo Console.Write^(f.FileName^);}}
    for /f "delims=" %%I in ('dir /b /s "%windir%\microsoft.net\*csc.exe"') do (
        if not exist "!chooser!" "%%I" /nologo /out:"!chooser!" "%temp%\c.cs" 2>NUL
    )
    del "%temp%\c.cs"
    if not exist "!chooser!" (
        echo Error: Please install .NET 2.0 or newer, or install PowerShell.
        goto :EOF
    )
)

:: capture choice to a variable
endlocal && for /f "delims=" %%I in ('%chooser%') do set "%~1=%%I"

:: Clean up the mess
del "%temp%\chooser.exe" 2>NUL
goto :EOF

如果您坚持在MyFile.jar搜索所有本地驱动器,则可以使用wmic logicaldisk查询驱动器列表。通过添加where "not drivetype=4"排除网络驱动器。您仍应将结果保存到注册表中,以防止每次运行几分钟的延迟。

@echo off
setlocal

set "jarfile=MyFile.jar"
set "regkey=HKLM\Software\Company Name"
set "regvalue=jarfile"

set jarpath=
for /f "tokens=2*" %%I in ('reg query "%regkey%" /v "%regvalue%" 2^>NUL') do (
    set "jarpath=%%~J"
)

if not exist "%jarpath%" (
    call :finder jarpath "%jarfile%"
)

if exist "%jarpath%" (
    reg add "%regkey%" /v "%regvalue%" /t REG_SZ /d "%jarpath%" /f 2>&1>NUL
) else (
    <NUL set /P "=Unable to locate %jarfile%.  This thread will self-destruct in 5 seconds... "
    ping -n 6 0.0.0.0 >NUL
    echo bang.
    exit /b 1
)

java -jar "%jarpath%"

goto :EOF

:finder <var_to_set> <file_to_find>
setlocal
:: in wmic, drivetype=4 is network drive
for /f "tokens=2 delims=:=" %%I in (
    'wmic logicaldisk where "not drivetype=4" get DeviceID /format:list ^| find "="'
) do (
    <NUL set /P "=Searching %%I: for %~2... "
    for /f "delims=" %%a in ('dir /s /b "%%I:\*%~2"') do (
        echo %%~dpa
        endlocal & set "%~1=%%a"
        goto :EOF
    )
    echo Not found.
)
goto :EOF

答案 1 :(得分:0)

首先找到文件并将变量设置为其路径,然后将该变量用作所需的路径。从你使用%~dp0开始,我假设你只在windows上工作,所以下面的例子是针对windows的

echo off
for /r C:\search_folder_root %%a in (*) do if "%%~nxa"=="MyFile.jar" set jarLoc=%%~dpa
java -jar %jarLoc%MyFile.jar %*

警告 - 搜索可能需要很长时间,例如如果你搜索整个驱动​​器......

<强> 编辑:

响应OP请求将搜索系统上任何驱动器的脚本的注释,就在这里。请注意 - 我不认为使用这个对于用户体验是一个好主意 - 它将是非常低效的并且可能需要很长时间...在一个非常简单的情况下测试,在早期发生的路径上使用虚拟jar在我的机器上搜索。注意 - 如果用户知道jar在哪个驱动器上,或者甚至更好的路径,你总是可以提示他们输入该驱动器/路径而不是循环。

echo off
setlocal
set jarName=MyFile.jar

rem -- loop through each drive on system --
for /F "usebackq skip=1" %%i in (`wmic logicaldisk get caption 2^>NUL`) do (
  echo Checking drive %%i for %jarName%

  rem -- temporarily change to the drive --
  pushd %%i\

  rem -- recursively loop through every file of every subdirectory on that drive --
  for /r %%a in (*) do (
    if "%%~nxa"=="%jarName%" set jarLoc=%%~dpa
    if defined jarLoc goto :Found
  )
  popd
)

rem -- if we get to here, the jar has not been found --

echo %jarName% not found on any drive in this system
goto :eof

:Found
echo Jar found at %jarLoc%
popd
java -jar %jarLoc%%jarName% %*