Определение того, является ли целевой том NTFS, с помощью NSIS

Я создаю установщик с помощью NSIS для программы, которая должна работать на томе NTFS. Как определить, находится ли путь установки на томе NTFS, и действовать соответствующим образом (показать справку/предупреждающее сообщение)?


person Abdullah Jibaly    schedule 28.01.2009    source источник


Ответы (3)


Использование внешних инструментов не всегда является хорошей идеей (не все инструменты командной строки существуют в домашних версиях Windows). Всегда лучше вызывать правильный API напрямую с системным подключаемым модулем.

!include LogicLib.nsh

StrCpy $0 "c:\"
System::Call 'Kernel32::GetVolumeInformation(t "$0",t,i ${NSIS_MAX_STRLEN},*i,*i,*i,t.r1,i ${NSIS_MAX_STRLEN})i.r0'
${If} $0 <> 0
    MessageBox mb_ok "fs=$1"
${EndIf}

Но в этом случае вы не должны проверять тип файловой системы, а должны искать те функции, которые вам нужны (сжатие, шифрование, соединения, разреженные файлы и т. д.).

!define FILE_SUPPORTS_ENCRYPTION 0x00020000
!define FILE_READ_ONLY_VOLUME 0x00080000
!define FILE_VOLUME_QUOTAS 0x00000020

!macro MakeBitFlagYesNo flags bit outvar
IntOp ${outvar} ${flags} & ${bit}
${IfThen} ${outvar} <> 0 ${|} StrCpy ${outvar} "Yes" ${|}
${IfThen} ${outvar} == 0 ${|} StrCpy ${outvar} "No" ${|}
!macroend

StrCpy $0 "c:\"
System::Call 'Kernel32::GetVolumeInformation(t "$0",t,i ${NSIS_MAX_STRLEN},*i,*i,*i.r1,t,i ${NSIS_MAX_STRLEN})i.r0'
${If} $0 <> 0
    !insertmacro MakeBitFlagYesNo $1 ${FILE_SUPPORTS_ENCRYPTION} $2
    !insertmacro MakeBitFlagYesNo $1 ${FILE_READ_ONLY_VOLUME} $3
    !insertmacro MakeBitFlagYesNo $1 ${FILE_VOLUME_QUOTAS} $4
    MessageBox mb_ok "flags=$1 $\nFILE_SUPPORTS_ENCRYPTION=$2$\nFILE_READ_ONLY_VOLUME=$3$\nFILE_VOLUME_QUOTAS=$4"
${EndIf}
person Anders    schedule 08.04.2009

Я не знаком с NSIS, но вам может пригодиться этот маленький трюк с DOS.

Я заметил, что можно открыть файл с помощью NSIS, так что это может помочь --

chkntfs c: | find "file system" > yourfile.abc

CHKNTFS — это утилита для управления операциями CHKDSK, но если вы запускаете команду без переключателей командной строки, она просто сообщает о результатах.

"C:" - это диск, который вас интересует --

Вы можете запустить это из командной строки, чтобы увидеть результат, конечно, без части "> yourfile.abc", которая направляет вывод в этот файл.

Прежде чем кто-либо проголосует за это, я просто предлагаю это как наводящее на размышления ПРЕДЛОЖЕНИЕ, возможно, подталкивающее к реальному решению, и помните ТАКОЙ девиз - будьте ДОБРЫМИ ... лол ...

РЕДАКТИРОВАТЬ: этот фрагмент может помочь - у меня нет возможности действительно ПРОВЕРИТЬ это - ЭТО ИСПОЛЬЗОВАНИЕ ВРЕМЕНИ КОМПИЛЯЦИИ - и вам, скорее всего, понадобится ВРЕМЯ ВЫПОЛНЕНИЯ... НО, это может дать вам представление...

Я «предполагаю», что уже нет определения с именем NTFS — если это так, измените его соответствующим образом. Первый вызов СОЗДАЕТ включаемый файл, второй ПРИСОЕДИНЯЕТ к нему (двойной > )... Опция /C для НАЙТИ просто ПОДСЧИТЫВАЕТ количество строк, содержащих искомый элемент. Следовательно, результат 0 или 1.

!system 'echo "!define NTFS=" > newinclude.nsh'
!system 'chkntfs c: | find /c "NTFS" >> newinclude.nsh'
!include newinclude.nsh
!ifdef NTFS
  !echo "NTFS is defined and value should reflect accordingly; 0=NO, 1=Yes it is NTFS"
!endif

EDIT: (опять же, лол)

вот фрагмент, который установит переменную ОКРУЖАЮЩУЮ СРЕДУ, которая, насколько я могу судить, должна быть довольно легко читаемой во время выполнения - вы можете создать переменную для выполнения, соответственно заменив букву диска.

ExecWait 'chkntfs c: | find /c "NTFS"  > tempfile.abc'
ExecWait 'set /p NTFS= < tempfile.abc'
Exec     'del tempfile.abc'

Теперь переменная среды с именем NTFS должна содержать 0, если не NTFS, и 1, если проверяемый том является NTFS.

Или напрямую

ExecWait 'chkntfs c: | find /c "NTFS"' $0

$0 содержит код возврата; Результаты немного обратные, так как это код возврата ERROR. Если 0 у вас ЕСТЬ NTFS и > 0 означает НЕТ NTFS.

person Borzio    schedule 28.01.2009
comment
Хорошее предложение! Я посмотрю на это, если не найду более прямого решения. Спасибо! - person Abdullah Jibaly; 28.01.2009
comment
Я не слышал об этом приложении до того, как вы спросили, и в результате скачал его — оно просто потрясающее, так что спасибо за вопрос. :) -- Если что найду, отпишусь... - person Borzio; 28.01.2009

Ваш тест должен быть во время выполнения, поэтому Ответ Борзио сам по себе не сработает.

Также похоже, что команда ExecWait не допускает перенаправления, поэтому выполнить ее таким образом и потом проверить содержимое файла не получится.

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

  • создайте пакетный файл, который будет запускать chkntfs, а затем установите уровень ошибки на основе результата
  • написать C/C++/VB/и т.д. приложение, которое будет запускать chkntfs, а затем устанавливать уровень ошибки на основе результата
  • написать C/C++/VB/и т.д. приложение, которое будет использовать Win32 API для определения файловой системы
  • написать плагин для NSIS, который бы использовал Win32 API для определения файловой системы

Правка: Борзио обновил свой до того, как я закончил свой :)

Возможно, вам придется добавить что-то, что я нашел на форумах Winamp: ExecWait с перенаправлением файлов

  ExpandEnvStrings $1 %COMSPEC%
  ExecWait '"$1" /C chkntfs c: | find /c "NTFS"' $0

Без ExpandEnvStrings $1 %COMSPEC% в моей системе не работало создание перенаправленного файла.

Я проверил вышеизложенное, и оно работает: 0 для NTFS и 1 для не NTFS.

Единственным возможным недостатком этого метода является кратковременное всплывающее окно команд во время выполнения кода.

person crashmstr    schedule 28.01.2009
comment
Хорошо, что у вас была возможность проверить это - проблема с окружающей средой была неизвестна... :) - person Borzio; 29.01.2009
comment
Использование COMSPEC здесь немного бессмысленно, Win9x не поддерживает NTFS (поддерживает с надстройкой sysinternals, но не имеет программы chkntfs) - person Anders; 08.04.2009
comment
Про Win9x никто ничего не говорил и без COMSPEC execWait может не работать. Просто как тот. - person crashmstr; 09.04.2009
comment
уверен, что будет, просто хардкод cmd.exe. В любом случае вы не должны использовать ExecWait при использовании перенаправления, используйте nsExec или один из сторонних плагинов DosExec на вики nsis. - person Anders; 09.04.2009