Я создаю установщик с помощью NSIS для программы, которая должна работать на томе NTFS. Как определить, находится ли путь установки на томе NTFS, и действовать соответствующим образом (показать справку/предупреждающее сообщение)?
Определение того, является ли целевой том NTFS, с помощью NSIS
Ответы (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}
Я не знаком с 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.
Ваш тест должен быть во время выполнения, поэтому Ответ Борзио сам по себе не сработает.
Также похоже, что команда 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.
Единственным возможным недостатком этого метода является кратковременное всплывающее окно команд во время выполнения кода.