繁体   English   中英

使用NSIS检测目标卷是否为NTFS

[英]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命令似乎不允许重定向,因此以这种方式执行然后检查文件内容将不起作用。

在我看来,您最好的选择是选择以下一项:

  • 制作一个将运行chkntfs的批处理文件,然后根据结果设置错误级别
  • 编写C / C ++ / VB / etc。 应用会运行chkntfs,然后根据结果设置错误级别
  • 编写C / C ++ / VB / etc。 使用Win32 API确定文件系统的应用程序
  • 为NSIS编写一个插件,该插件将使用Win32 API确定文件系统

编辑: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM