简体   繁体   中英

How to create a batch file to run a jar file that is in any location of the system

I have a MyFile.jar file. I need a batch file that searches for the jar file and triggers it.

I found the following solution. But for that batch file and jar file must be in the same folder.

java -jar %~dp0MyFile.jar %*

We don't know where the client will place jar file in their system. But they will put batch file in startup folder.

Edit: I managed to write this batch file for now.

`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%`

This is working now in my system. But I am not sure if there will be a simpler way to check all the drives at once.

As gknicker and I commented above, this is the way it should be done. If you used an installer (like NSIS or similar) to deploy the .jar file and .bat script, have the installer write the registry value, and a search or file browse may never be needed. If the .jar file is moved after installation, pop up a GUI file chooser and let the user browse to the location he saved MyFile.jar . Save the updated location to the registry. Re-prompt if the file is moved again.

@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

If you insist on searching all local drives for MyFile.jar , you can query a drive list with wmic logicaldisk . Exclude network drives by adding where "not drivetype=4" . You should still save the result to the registry to prevent a several minute delay on every run.

@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

First find the file and set a variable to its path, then use that variable as the path you want. From your use of %~dp0, I assume you are working on windows only, so the following example is for windows

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

Be warned - the search could take quite a long time eg if you search a whole drive...

EDIT:

In response to OPs comments requesting a script that will search any drive on the system, here it is. Please note - I don't think use of this is a good idea for user experience - it will be very inefficient and it could take ages... Tested on a very simple case with a dummy jar on a path that occurs early in the search on my machine. Note - if the user will know which drive the jar is on, or even better the path, you could always prompt them to enter that drive / path instead of looping through.

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% %*

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM