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

时间:2009-01-28 18:24:04

标签: windows installer nsis ntfs

我正在为NSIS创建一个安装程序,用于需要在NTFS卷上运行的程序。如何检测路径安装是否在NTFS卷上并采取相应措施(显示帮助/警告消息)?

3 个答案:

答案 0 :(得分:3)

使用外部工具并不总是一个好主意(不是每个命令行工具都存在于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}

答案 1 :(得分:1)

我不熟悉NSIS,但您可能会发现这个小“DOS”技巧很有帮助。

我确实注意到可以用NSIS打开文件,所以这可能会有所帮助 -

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

CHKNTFS是一个用于管理CHKDSK操作的实用程序,但是如果在没有命令行开关的情况下运行该命令,它只会报告结果。

“C:”是您感兴趣的驱动器 -

您可以从命令提示符运行此命令以查看结果,而不使用“&gt; yourfile.abc”  当然,部分是将输出定向到该文件的内容。

在任何人投票之前,我只是提出它作为一个发人深省的建议,或许引发真正的解决方案,并记住SO座右铭 - 是亲切的......大笑......

编辑:这个片段可能会有所帮助 - 我无法真正测试这个 - 这是编辑时间的用法 - 你很可能想要运行时...但是,它可能会给你一个想法..

我“假设”没有已经命名为NTFS的定义 - 如果是这样,请相应地更改它。第一个调用创建包含文件,第二个APPENDS到它(double&gt;)... 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保存返回码;结果有点向后,因为这是ERROR返回码。如果为0,你有NTFS和&gt; 0表示无NTFS。

答案 2 :(得分:1)

您的测试需要在运行时进行,因此Borzio's答案本身不起作用。

看起来ExecWait命令也不允许重定向,因此无法以这种方式执行,然后检查文件的内容。

在我看来,你最好的选择是选择以下之一:

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

编辑: Borzio在我完成之前更新了他:)

您可能需要在Winamp论坛上添加我发现的内容:ExecWait with file redirection

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

没有ExpandEnvStrings $1 %COMSPEC%,我的系统无法生成重定向文件。

我已经测试了上面的内容,它确实有效,0表示NTFS,1表示非NTFS。

此方法唯一可能的缺点是在代码执行期间会短暂弹出命令窗口。