Как найти полный путь к приложению в пакетном скрипте - PullRequest
16 голосов
/ 17 сентября 2009

Как мне в пакетном скрипте найти полный путь к приложению XYZ, если оно установлено

Разъяснения:

  1. Приложение не в ПУТИ
  2. Все, что у меня есть, это имя в данном случае "ISTool.exe", и я хотел бы получить C: \ Program \ ISTool \ ISTool.exe

Ответы [ 6 ]

28 голосов
/ 17 сентября 2009

Вы можете найти исполняемый файл по пути (или другой похожей на путь строке, если необходимо):

c:\> for %i in (cmd.exe) do @echo. %~$PATH:i
C:\WINDOWS\system32\cmd.exe

c:\> for %i in (python.exe) do @echo. %~$PATH:i
C:\Python25\python.exe

Подробности можно найти в конце текста справки для команды "for", "for /?", но сводка:

%~i    - expands %i removing any surrounding quotes.
%~fi   - expands %i to a fully qualified path name.
%~di   - expands %i to a drive letter only.
%~pi   - expands %i to a path only.
%~ni   - expands %i to a file name only.
%~xi   - expands %i to a file extension only.
%~si   - expanded path contains short names only.
%~ai   - expands %i to file attributes of file.
%~ti   - expands %i to date/time of file.
%~zi   - expands %i to size of file.
%~$P:i - searches the directories listed in the P environment variable
         and expands %i to the fully qualified name of the first one found.
         If the environment variable name is not defined or the file is not
         found by the search, then this modifier expands to the empty string.

Модификаторы можно комбинировать для получения составных результатов:

%~dpi    - expands %i to a drive letter and path only.
%~nxi    - expands %i to a file name and extension only.
%~fsi    - expands %i to a full path name with short names only.
%~dp$P:i - searches the directories listed in the P environment variable
           for %i and expands to the drive letter and path of the first
           one found.
%~ftzai  - expands %i to a DIR like output line.

Если ваш исполняемый файл находится не по пути (в соответствии с вашими правками), вам лучше всего использовать формат голого / подкаталога dir, который сделает это за вас. Из корневого каталога:

dir /b /s ISTool.exe

выдаст вам все файлы на этом диске с этим именем. Затем вам просто нужно проанализировать вывод. Я бы предпочел использовать "find /cygdrive -name ISTool.exe" от Cygwin, но это потому, что он у меня уже установлен. Вы можете этого не хотеть (или даже иметь такую ​​возможность).

Обновление:

Эта команда dir /b /s займет некоторое время, так как она в основном ищет весь диск. Если это проблема, вы можете периодически создавать кэшированную запись всех файлов на всех дисках с помощью cmd-файла, например:

@echo off
setlocal enableextensions enabledelayedexpansion
del c:\files.cache.tmp >nul: 2>nul:
for %%d in (c d e) do (
    cd /d %%d:\
    dir /b /s >>c:\files.cache.tmp
)
del c:\files.cache >nul: 2>nul:
move c:\files.cache.tmp c:\files.cache
endlocal

Вы можете сделать это с запланированными заданиями либо ночью (для постоянно включенного сервера), либо при загрузке (для рабочего стола). Вы могли бы даже сделать сценарий более интеллектуальным, чтобы делать это только каждые пару дней (у меня есть сценарий автоматического резервного копирования, который выполняет аналогичные действия на машинах семейства, которые я поддерживаю). Это создает список во временном файле кэша, а затем перезаписывает исходный, чтобы свести к минимуму время, когда файл не существует.

Тогда вы можете просто использовать:

findstr \\ISTool.exe c:\files.cache

чтобы найти все ваши файлы.

8 голосов
/ 24 сентября 2012

Основываясь на действительно полезных ответах здесь, я взломал эти две партии, которые, как мне показалось, я поделился здесь (я знаю, что этой ветке уже 3 года, но она найдена как 1-е совпадение при поиске ...):

1) which.bat:

@echo off
REM emulate the Linux which command
if "%1" == "" (
  echo Usage: %~nx0 ^<command[.ext]^>
  exit /b
)
setlocal
for %%P in (%PATHEXT%) do (
  for %%I in (%1 %1%%P) do (
    if exist "%%~$PATH:I" (
      echo %%~$PATH:I
      exit /b
    )
  )
)

не идеально, потому что всегда есть два теста, но он достаточно быстрый, так что я больше не беспокоился; уверен, что 1-й может сделать отдельный тест только с% 1 ...

2) findfile.bat:

@echo off
REM emulate the Linux find command
if "%1" == "" (
  echo Usage: %~nx0 ^<startdir^> ^<file^>
  exit /b
)
setlocal
for /f "delims=" %%A in ('dir /b /s %1\%2') do set F=%%A
if exist "%F%" echo %F%
1 голос
/ 17 сентября 2009

Это самое близкое, что у меня есть. Один недостаток заключается в том, что он работает только для одного диска на исполнение, но это может сделать его более гибким. Другой - это вывод, который всегда содержит // между путем и именем файла. Но по определению это правильный путь.

@ECHO OFF

SET filename=autoexec.bat

FOR /R C:\ %%a IN (\) DO (
   IF EXIST "%%a\%filename%" (

      SET fullpath=%%a%filename%
      GOTO break
   )
)
:break

ECHO %fullpath%

Доставим: C:\\autoexec.bat

EDIT:

Для пояснения, цикл for перебирает все каталоги, начиная с заданного пути (C: \), и проверяет, существует ли имя файла в этом каталоге. Если это так, обе переменные объединяются и сохраняются в% fullpath%, и цикл прерывается переходом.

0 голосов
/ 16 января 2014

В качестве альтернативы, такие программы, как Все и UltraSearch (бесплатное программное обеспечение), SwiftSearch могут выполнять поиск файлов в MFT (вашего NTFS-раздела) (что позволяет сделайте это очень быстро), (но Википедия утверждает, что подобные вещи могут нарушить вашу модель безопасности, обнаружив вещи, которые не должны) - некоторые из них выглядят так, как будто имеют некоторые параметры командной строки, я не использовал их, но, возможно, это может быть полезно, если вы прибегаете к полному поиску диска.

0 голосов
/ 12 июня 2013

Иногда это простое решение работает, когда вы проверяете, соответствует ли результат ожидаемому. Первая строка запускает команду и захватывает последнюю строку стандартного вывода.

FOR /F "tokens=*" %%i in (' "xcopy /? 2> nul" ') do SET xcopyoutput=%%i
if "%xcopyoutput%"=="" echo xcopy not in path.
0 голосов
/ 17 сентября 2009

Ответы, которые я получил от других, работали (но медленно или использовали дополнительные файлы) и работали для любого exe, но не очень подходили моим потребностям.

Так как я хотел найти конкретный exe-файл, я начал искать в реестре, используя REG QUERY . Я нашел ключ, который содержал данные, которые я хотел найти, и извлек их.

Результат быстрый, имеет мало строк кода, но не очень красив и не пригоден для повторного использования.

Краткий пример:

@ECHO off
SETLOCAL
set found=
FOR /F "tokens=1-3 delims= " %%a IN ('REG QUERY "HKEY_CLASSES_ROOT\Applications\ISTool.exe\shell\OpenWithISTool\command"') DO (
 set found=%%c
)

for /f "tokens=1-2" %%a in ("%found%") do (
 set my_exe=%%a
)
echo %my_exe%
ENDLOCAL

В результате получается "C:\Program\ISTool\ISTool.exe" (с кавычками)
Примечание : за разделителями = выше следует символ табуляции

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...