Archive: add/remove programs - impossible file size


add/remove programs - impossible file size
An earlier thread mentioned a problem with impossible file sizes showing up when using add/remove programs to uninstall a file.

I have the same problem. Has anyone found a solution?

Thanks,
Randy


The file size is calculated by Windows, it has nothing to do with NSIS. I think it takes the size of the directory.

Did you write a "InstallLocation" string value with the $INSTDIR?


I did set a default directory using InstallDirRegKey and modified it to point to a subdirectory into which I installed the file. (This problem occurred with the sample code I posted for the webapps install).

If, indeed, the size is based on the directory that already exists (webapps is big), then that would explain the problem. Odd, though, that the calculation is made on the whole directory, rather than what is installed.

Randy


Windows doesn't keep the list of files your installer have installed, that would be a crazy thing to do. Therefore it relies on the data it does have, which is what you give it. If your files are in a sub directory of webapps then you should narrow Windows' search with InstallLocation as Joost mentioned. If that's not the case then you'll have to find a way to tell Windows to not calculate that size. If you find such a way please tell us :)


No, I am not installing into a subdirectory of webapps. What the Tomcat server does is automatically expand web applications that are "zipped .war" files into subdirectories. So I am just installing a file into that webapps subdirectory that will be expanded later by the server. (This is why, at the end of my uninstall, I delete a directory that I did not originally install - it is built by Tomcat.)

Oh well....

As the farmer told me, "Sorry, you can't get there from here." ;)


add/remove programs incorrect size
Try the following:

    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${INSTALLERDISPLAYNAME}" "EstimatedSize" <size>


Your mileage may vary by operating system.

However, from what I can tell, NSIS doesn't provide a way to get the size of a section. Nor is there a way to get the size of all files that are being installed. Ideally, NSIS would provide a way of getting the total size of everything that's going to install so I can write it to that to the aforementioned registry location.

Thanks Nullsoft for a great product!

Take care,
Andrew Koransky
www.koransky.com

Ah, what about this?

http://nsis.sourceforge.net/Docs/Chapter4.html#4.9.13.8

Not sure if that does what you need (get section size)

-Stu


Hmmm... I thought I was on the latest released (stable?) build? New for 2.0b4, eh? Looks like my wait will be brief. :-)

I guess to get the total size of an executing install (IE while writing uninstaller reg entry), I'll have to write a macro/function to iterate through sections, see if they are checked, and give me a total size. I'll try to post it when I have something.

Thanks for the heads up!

Take care,
Andrew Koransky
www.koransky.com


Yep, a simple loop that stops when an error rises will be easy enough to implement.

I couldn't resist :)

StrCpy $0 0
StrCpy $2 0
loop:
SectionGetSize $0 $1
IfErrors done
IntOp $2 $2 + $1
IntOp $0 $0 + 1
Goto loop
done:
DetailPrint "total of $2KB"

I couldn't resist either. :p

I'm finally getting around to adding this to our installers. Your sample didn't take into account whether or not the section is selected... thought I'd post it in case anyone else finds it of use.

FYI... the registry entry below is basically ignored by Microsoft, at least in my copy of W2K. <sigh> So far as I can tell, Microsoft doesn't have a way to get the size correct in the add/remove programs control panel applet. If anyone has found a way, please let me know!


!define SF_SELECTED 1
; Calculate estimated size of the installation in K

; save off variable state
Push $0 ; section counter
Push $1 ; current section size
Push $2 ; running total of selected section sizes
Push $3 ; current section flags

StrCpy $0 0
StrCpy $2 0
CreateUninstaller_SectionGetSize_Loop:

; get section size, break if we run out
ClearErrors
SectionGetSize $0 $1
IfErrors CreateUninstaller_SectionGetSize_LoopDone

; check to see if it is selected, otherwise, "continue" (increment counter and restart loop)
SectionGetFlags $0 $3
IntOp $3 $3 & ${SF_SELECTED}
IntCmp ${SF_SELECTED} $3 0 CreateUninstaller_SectionGetSize_LoopContinue CreateUninstaller_SectionGetSize_LoopContinue

; add the total up...
IntOp $2 $2 + $1

CreateUninstaller_SectionGetSize_LoopContinue:
IntOp $0 $0 + 1 ; loop increment
Goto CreateUninstaller_SectionGetSize_Loop
CreateUninstaller_SectionGetSize_LoopDone:

; write it to the registry
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${INSTALLERDISPLAYNAME}" "EstimatedSize" $2

; restore the variables
Pop $3
Pop $2
Pop $1
Pop $0

i think EstimatedSize only works with msi installers...

WindowsInstaller(dword)=1, but im not sure if that works


Actually, this article (PCMag.com) covers where the (A)dd and (R)emove (P)rograms (ARP) "EstimatedSize" information is set in the registry and it's under:
Software\Microsoft\Windows\CurrentVersion\App Management\ARPCache\<same uninstall key>" under "SlowInfoCache"
(As an aside, doesn't that key make more sense if it was spelt "ShowInfoCache" :weird: )

I modified the code listed by Andrew above, but I ran into a problem I couldn't find a solution to, even reading the NSIS forums and manuals.

The code I came up with is:


; Convert the result to Hex for the ARP cache
; It has a format of:
; Len - HasName - EstimatedSize
; 2802 - 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - <etc>
IntFmt $0 "2802000000000000%08X" $2
; Then write it to ARP cache
WriteRegBin HKLM \
"Software\Microsoft\Windows\CurrentVersion\App Management\ARPCache\${PRODUCT_PUBLISHER}" "SlowInfoCache" $0


Looks right, no? But the compiler complains and it's because of the "$0" variable. If I just hard code a value instead of $0, it works. I also tried putting quotations around the variable, tried different variables like $R0, etc, but no luck :eek: .

What is wrong? Do I have to define the variable as a hex type? Bug?

It says in the user manual that the format is

IntFmt user_var(output) format numberstring

and your code fits that format, so I don't know...

Edit: Just tried that code, and it works fine. Are you running latest CVS?

-Stu


No, but after your post, I got the latest release build (Feb 7th, 2004), and alas, the same error. I then got the latest development build (July 21st, 2004) and same thing.

I tried the code just by itself:


OutFile "MyTest.exe"
Section -Post
Push $0
StrCpy $0 12321
WriteRegBin HKLM "Software\Microsoft\Windows\CurrentVersion\App Management\ARPCache\Test" "SlowInfoCacheBak" $0
SectionEnd


That should work right? But the same error occurs:

Usage: WriteRegBin rootkey subkey entry_name hex_string_like_12848412AB
root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)
Error in script "C:\MyScripts\test.nsi" on line 8 -- aborting creation process


I thought one factor might be the that I am compiling in HM NIS edit 2.0rc2, but I tried MakenSISW and same thing. Any compile settings, etc. that I should check?

I've noticed other people have the same problem (note - he fixes the HKLM problem in a post farther down).

Oops, maybe this is what I need... To quote:

RegBin.dll - NSIS extension DLL
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Writes an arbitrarily large binary value (which can be set at runtime) to the Windows Registry.
This overcomes two shortcomings of the standard WriteRegBin command:
a) Binary values have to specified at compile-time.
b) Maximum size of the value is 511 bytes.

Yup, works now! :up: Get the dll from the RegBin plugin and put it in your NSIS\plugins directory.

But can someone convert the decimal result into an Int64 and then into hex? The code below doesn't show the size correctly in the ARP dialog window:


; Convert the result to Hex for the ARP cache
; It has a format of:
; Len - HasName? - EstimatedSize (int64)
; 2802 - 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - <etc>
IntFmt $0 "2802000000000000%016X0000000000000000FFFFFFFF000000000000000" $2 ; <-- this is messed

; Then write it to ARP cache, use RegBin plugin
RegBin::WriteRegBin HKLM \
"Software\Microsoft\Windows\CurrentVersion\App Management\ARPCache\${INSTALLERDISPLAYNAME}" \
"SlowInfoCache" $0


It would also be cool to get the current time in the "FileTime" format to replace the "FFFFFFFF" which just clear that field.

Cheers!

The reason that MakeNSIS does not accept variables for the binary value is that it packs the binary value into the installer at compile time.
Anyway, glad to see that someone else has found a use for the plugin.