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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27849493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:30:51  来源:igfitidea点击:

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

javabatch-filejar

提问by Jenny

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

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

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

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

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.

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

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.

这现在在我的系统中工作。但我不确定是否会有更简单的方法来一次检查所有驱动器。

采纳答案by J Richard Snape

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

首先找到该文件并为其路径设置一个变量,然后将该变量用作您想要的路径。从您对 %~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 %*

Be warned - the search could take quite a long time e.g. 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.

为了响应 OP 的评论,要求一个脚本来搜索系统上的任何驱动器,这里是。请注意 - 我不认为使用这个对用户体验来说是一个好主意 - 它会非常低效并且可能需要很长时间......在一个非常简单的案例中进行了测试,在路径上出现了早期的路径在我的机器上搜索。注意 - 如果用户知道 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% %*

回答by rojo

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 .jarfile and .batscript, have the installer write the registry value, and a search or file browse may never be needed. If the .jarfile is moved after installation, pop up a GUI file chooserand 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.

正如 gknicker 和我在上面评论的那样,应该这样做。如果您使用安装程序(如 NSIS 或类似程序)部署.jar文件和.bat脚本,请让安装程序写入注册表值,并且可能永远不需要搜索或文件浏览。如果.jar安装后文件被移动,弹出一个GUI 文件选择器,让用户浏览到他保存的位置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


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.

如果您坚持搜索所有本地驱动器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