我有一个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%`
这在我的系统中正在运行。但我不确定是否会有一种更简单的方法来检查所有驱动器。
答案 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% %*