[英]Detecting if the target volume is NTFS using NSIS
我正在使用NSIS为需要在NTFS卷上运行的程序创建安装程序。 如何检测路径安装是否在NTFS卷上并采取相应措施(显示帮助/警告消息)?
使用外部工具并非总是一个好主意(并非Windows的Home版本中存在每个命令行工具)总是最好使用系统插件直接调用正确的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的定义-如果是这样,请相应地更改它。 第一个调用创建包含文件,第二个调用附加到该文件(双>)... FIND的/ 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
编辑:(再次,大声笑)
这是一个片段,它将设置一个环境变量,据我所知,它在运行时应该很容易阅读-您可以构造一个变量来执行,从而相应地替换驱动器号。
ExecWait 'chkntfs c: | find /c "NTFS" > tempfile.abc'
ExecWait 'set /p NTFS= < tempfile.abc'
Exec 'del tempfile.abc'
现在,如果不是NTFS,则称为NTFS的环境变量应保留0,如果要检查的卷为NTFS,则应保留1。
或直接
ExecWait 'chkntfs c: | find /c "NTFS"' $0
$ 0保留返回码; 结果有点倒退,因为这是错误返回码。 如果为0,则表示已拥有NTFS,而> 0表示没有NTFS。
您的测试将需要在运行时进行,因此Borzio的答案本身不会起作用。
看起来ExecWait命令似乎不允许重定向,因此以这种方式执行然后检查文件内容将不起作用。
在我看来,您最好的选择是选择以下一项:
编辑: Borzio在我完成我的工作之前更新了他的:)
您可能需要添加在Winamp论坛上找到的内容: 具有文件重定向的ExecWait
ExpandEnvStrings $1 %COMSPEC%
ExecWait '"$1" /C chkntfs c: | find /c "NTFS"' $0
没有ExpandEnvStrings $1 %COMSPEC%
,它在我的系统上无法生成重定向文件。
我已经测试了上面的内容,并且确实可以使用,对于NTFS为0,对于非NTFS为1。
该方法的唯一可能的缺点是在执行代码期间会短暂弹出命令窗口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.