Menu

#1306 Bug in FileSeek or FileFunc.nsh to get file(folder) size ${GetSize}.

3.0 Series
open
nobody
${GetSize} (1)
5
2024-02-26
2024-02-22
nttwqz
No

${GetSize} fails to get the correct file size when a single file is large, such as 2.5G, and is also incorrect when there are large files in the folder.

Simple research found that FileFunc.nsh use FileSeek to get the file size bytes, and then related calculations, the problem is, FileSeek in the processing of larger files will be an error, such as 2716863167B (2.5GB) will return a negative number, and thus the calculation is wrong, I hope that the relevant authors can fix the error!

It would be nice to add a built-in function to access the folder size directly.

Here is an example:

Section
    StrCpy $R0 "D:\test.tmp"
    IfFileExists $R0 +2 0
        ExecWait "fsutil file createnew $R0 2716863167"

    SetDetailsPrint none        # 3.09 bug,Not turning it off will accidentally show something that shouldn't be shown at all
    ${GetSize} "D:\" "/M=test.tmp /S=0K" $0 $1 $2
    SetDetailsPrint both
    DetailPrint "$0:$1:$2"

    FileOpen $0 $R0 r
    FileSeek $0 0 END $1
    FileClose $0
    Math::Script "r2 = r1/1024/1024"
    DetailPrint "$1:$2"     # Return error results: $1=-1578104129

    StrCpy $0 "2716863167"
    IntOp $0 $0 + 0         #  Out of calculation range, probably due to this. The numbers that IntOp can calculate are just a little too small for the 21st century.
    DetailPrint "$$0:$0"    # Return error results: -1578104129
SectionEnd

Discussion

  • Jason

    Jason - 2024-02-22

    NSIS internally uses 32 bit integers for script variables, so it's not useful for anything over 2GB. That being said, I think FileSeek is also written the same way at the moment for backwards compatibility (ie Win 9x).

    One workaround is to use the system plugin to call windows API's directly, or write your own plugin that does the same thing.

     
    • nttwqz

      nttwqz - 2024-02-26

      I believe that many of the use of NSIS is not a professional programmer. System plug-ins for the will not be C has a fairly high learning difficulty, have watched tutorials dozens of times, query GetFileSizeEx official documentation, but also did not figure out how to get the correct value from the LARGE_INTEGER union. Relatively speaking, Python in this regard on the simple too much too much, so has been rewritten in Python all.

      import os
      print(os.path.getsize('D:/test.tmp'))
      sum = 0
      for root,dirs,files in os.walk('D:/test'):
          for fn in files:
              sum += os.path.getsize(os.path.join(root, fn))
      print(round(sum/1024/1024, 2), 'MB')
      

      When will NSIS be this easy?

      FileGetSize $0 'D:\test.tmp'
      DetailPrint $0
      DirGetSize $0 'D:\test'
      DetailPrint $0
      
       

Log in to post a comment.