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

我使用NSIS为需要在NTFS卷上运行的程序创build安装程序。 如何检测安装path是否在NTFS卷上,并相应地执行(显示帮助/警告消息)?

Solutions Collecting From Web of "使用NSIS检测目标卷是否为NTFS"

使用外部工具并不总是一个好主意(不是每个命令行工具都存在于家庭版本的Windows中)最好直接使用系统插件调用正确的API。

!include LogicLib.nsh StrCpy $0 "c:\" System::Call 'coreel32::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 'coreel32::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”部分,这就是把输出导入到那个文件中的东西。

在任何人投票之前,我只是把它作为一个令人兴奋的建议提出,也许引发了真正的解决方案,并记住SO的座右铭 – 是KIND …大声笑…

编辑:这个片段可能会有所帮助 – 我没有办法真正测试这个 – 这是编译时间使用 – 而且你很可能想要运行时间…但是,它可能会给你一个想法…

我“假设”没有一个已经命名为NTFS的定义 – 如果是的话,相应地改变它。 第一次调用CREATE包含文件,第二个APPENDS(包含double>)… 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的环境变量应该保存0,如果不是NTFS,则1保存为NTFS。

或直接

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

$ 0保存返回码; 结果是有点倒退,因为这是错误返回码。 如果你有NTFS和> 0意味着没有NTFS。

你的测试需要在运行时间,所以Borzio的答案本身不起作用。

它看起来像ExecWait命令不允许重定向,所以它不会工作,以这种方式执行,然后检查文件的内容。

它看起来像我最喜欢的选择将是挑选其中之一:

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

编辑: Borzio更新之前,我完成了我的:)

您可能需要添加一些我在Winamp论坛上找到的东西: 带文件重定向的ExecWait

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

如果没有ExpandEnvStrings $1 %COMSPEC% ,它不能在我的系统上生成重定向的文件。

我已经测试了上面的,并且它工作,0为NTFS和1为非NTFS。

这种方法唯一可能的缺点是在代码执行过程中会弹出一个命令窗口。