代码之家  ›  专栏  ›  技术社区  ›  Albert Mulder

NSIS GetVolumeInformation结果

  •  0
  • Albert Mulder  · 技术社区  · 8 年前

    好的,我从另一个问题中找到了这段代码,我是NSIS的新手。下面的问题

    !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}
    

    以下是我需要得到的:

    驱动器卷标:

    文件系统:(Fat32、NTFS、exFat…)

    可用空间:(4.62TB,632GB,…)

    分配单元大小:(4096b、16kb、32kb,…)

    然后我需要在if-then语句中使用这些信息 只是不知道如何将上述代码和结果转换为下面的代码列表。

    ${If} $File_System <> "NTFS"
    ${EndIf}
    
    ${If} $Disk_Capacity < "1.86TB"
    ${EndIf}
    
    ${If} $Free_Space < "1.25TB"
    ${EndIf}
    
    ${If} $Allocation_Unit_Size <> "4096 bytes"
    ${EndIf}
    
    MessageBox mb_ok "$Drive_Volume_Label$\n$File_System$\n$Disk_Capacity$\n$Free_Space$\n$Allocation_Unit_Size"
    

    如果你能帮我贴出答案代码,然后告诉我你从哪里得到信息(代码的解释)。这有助于我更快地学习代码,如果我知道它在做什么,我需要什么。

    艾伯特

    1 回复  |  直到 8 年前
        1
  •  0
  •   Anders    8 年前

    中的代码 answer you found 实际上返回文件系统的名称,然后它继续告诉您这可能不是最好的方式。如果可能,您应该使用文件系统标志。例如,微软的新文件系统 ReFS 支持一些NTFS功能,并添加了一些新的可靠性功能。

    !include LogicLib.nsh
    StrCpy $9 "c:\"
    System::Call 'Kernel32::GetVolumeInformation(t "$9",t.r3,i ${NSIS_MAX_STRLEN},*i,*i,*i.r1,t.r2,i ${NSIS_MAX_STRLEN})i.r0'
    ${If} $0 <> 0
        IntFmt $1 "%#.8x" $1
        MessageBox MB_OK " FileSystemFlags=$1 $\n FileSystemName=$2 $\n VolumeName=$3"
    
        ${If} $2 == "NTFS"
            MessageBox MB_OK "$9 is NTFS"
        ${Else}
            MessageBox MB_OK "$9 is $2 and not NTFS but hopefully you don't care"
        ${EndIf}
    ${EndIf}
    

    您的其他属性不会被此函数公开,如果您查看其 documentation on MSDN

    !include LogicLib.nsh
    StrCpy $9 "c:\"
    System::Call 'Kernel32::GetDiskFreeSpaceEx(t "$9", *l.r1, *l.r2, *l.r3)i.r0' ; This function does not work on Windows 95
    ${If} $0 <> 0
        MessageBox MB_OK " FreeBytesAvailable=$1 $\n TotalNumberOfBytes=$2 $\n TotalNumberOfFreeBytes=$3"
    
        System::Call 'ShLwApi::StrFormatByteSizeW(l $1, w.r4, i ${NSIS_MAX_STRLEN})'
        MessageBox MB_OK "Friendly FreeBytesAvailable: $4" ; For display in UI only!
    
        !define /math MYSIZE 0x100000 * 666 ; 666 MiB
        ${If} $1 L>= ${MYSIZE}
            MessageBox MB_OK "Disk quota on $9 allows you to write at least ${MYSIZE} bytes on this volume"
        ${Else}
            MessageBox MB_OK|MB_ICONSTOP "Not enough space on volume, ${MYSIZE} bytes required!"
            Quit
        ${EndIf}
    ${EndIf}
    

    NSIS已经提供了一个目录页来检查磁盘空间,如果可能的话可以使用它。注意:您不能比较不同比例的数字(TB与GB等),必须比较64位字节计数。

    按分配单位,我假设你说的是 cluster size ?

    !include LogicLib.nsh
    StrCpy $9 "c:\"
    System::Call 'Kernel32::GetDiskFreeSpace(t "$9", *i.r1, *i.r2, *i, *i)i.r0'
    ${If} $0 <> 0
        IntOp $1 $1 * $2
        System::Call 'ShLwApi::StrFormatByteSizeW(l $1, w.r3, i ${NSIS_MAX_STRLEN})'
        MessageBox MB_OK "Cluster size: $3 ($1 bytes)"
    
        ${If} 4096 <> $1
          ; ...
        ${EndIf}
    ${EndIf}
    

    (报告的群集大小可能是逻辑大小,而不是物理大小)