![]() |
#1 |
Moderator
Join Date: Aug 2004
Location: Poland
Posts: 563
|
Get available disk space of Network drive
I am writing my own Directory Page, based on nsDialogs.
Everything is fine but I have few problems: I am creating a button that user can choose directory: PHP Code:
PHP Code:
Here are the problems: 1. We don't want to see Network drives (\\SOMETHING) in select folder dialog. How to create SelectFolderDialog control without Network drives? 2. We want to see network drives (\\SOMETHING) in select folder dialog. But how to get size of this (available disk space of network disk)? To get disk space of local disk I use this code: (I also check if drive is local or removable etc, but it is not related to my issues (System::Call "kernel32::GetDriveType(t R0) i.R1")) PHP Code:
What am I doing wrong? Maybe ${GetRoot} fails? For sure ${DriveSpace} need a drive letter and get something like '\\blablabl\... If someone could show some working example I would be happy ![]() I am sure I am missing something... I forgot to mention - NSIS directory page (built-in) do it correctly! Regards, -Pawel |
![]() |
![]() |
![]() |
#2 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,548
|
You should not use ${GetRoot} because volumes can be mounted in subfolders! On Vista+ you can also create symlinks to network shares.
You could try calling SHBrowseForFolder with the System plug-in and using the BIF_DONTGOBELOWDOMAIN flag. Call GetDiskFreeSpaceEx to get the size. (NSIS calls it in a loop, removing the last component and backslash until the function returns success or the string is at the root drive letter) IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#3 | |||
Moderator
Join Date: Aug 2004
Location: Poland
Posts: 563
|
@Anders,
Thanks for tips! I would like to sum up things... I am correctly get available disk space for local drives, right? (assuming that I only use drive types like: DRIVE_REMOVABLE and DRIVE_FIXED) Quote:
Quote:
Quote:
Again, thank you for your help. |
|||
![]() |
![]() |
![]() |
#4 | |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,548
|
You don't seem to understand, the drive letters are irrelevant. If I type "c:\Stuff\YourApp" in the directory box that does not mean it is really going to be installed on volume c:, the "c:\Stuff" directory could be redirected to d:, a network location or a volume could be mounted directly there! Windows has supported this since Windows 2000.
The loop should work like this: Quote:
IntOp $PostCount $PostCount + 1 |
|
![]() |
![]() |
![]() |
#5 |
Moderator
Join Date: Aug 2004
Location: Poland
Posts: 563
|
OK. Will read, analyze and code it in best way
![]() -Pawel Ps: I only want to add, that in my installer user can not change path manually - he need to use BrowseForFolder dialog - it means I don't have to validate path, as I am sure the path is correct and exists. Only problem I have was network drives (directories, like \\path\to\directory). I am gonna do 2 installation modes: normal (full system integration - user can install files in local drives or removable - not on network or ram drive etc) and portable (no system integration, no system directories, no shortcuts, etc - user can install files where he wants (not on system directories), also on network directories). I need to think twice about it to make it work correctly. If I didn't understand you well, sorry... i am still learning ![]() -Pawel |
![]() |
![]() |
![]() |
#6 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,548
|
If the path starts with "\\" or the drive letter type is network then you can probably just block it but you should still use GetDiskFreeSpaceEx in a loop to get the size.
IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#7 |
Moderator
Join Date: Aug 2004
Location: Poland
Posts: 563
|
Yup. As I know that user can not brake the path (he has to use Browse Dialog which will return correct path or error) I only check if the path is '\\' or X:\ . All other possibilities are blocked.
|
![]() |
![]() |
![]() |
#8 |
Moderator
Join Date: Aug 2004
Location: Poland
Posts: 563
|
Here is the pseudo code...
Would you change anything? Macro ${GET_AVAILABLE_DISK_SPACE} gets Text control handle (with directory path chosen by Browse Button) and a handle to label control where result will be displayed... In macro, I check path in loop if exists (it seems that existing path need to be passed to GetDiskFreeSpaceEx()), then get size and display it on label control. Those all MessageBox's of course are only for debug... PHP Code:
|
![]() |
![]() |
![]() |
#9 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,548
|
You don't have to check with ${FileExists}, just call GetDiskFreeSpaceEx and check the return value. Stop if GetDiskFreeSpaceEx succeeds or if you removed all folders and are at the drive root and it still fails (because the drive letter is invalid etc.).
IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#10 |
Moderator
Join Date: Aug 2004
Location: Poland
Posts: 563
|
${FileExists} -> Yes, but I add not existing directory, which have to be removed (GetDiskFreeSpaceEx fails, if path is invalid). It works nice. I paste here only pseudo code... When I am sure the path is correct and exists I check the size -> if size is > 0 it is ok, if not then I know it fails). Tested on win10 and win7, works very nice.
|
![]() |
![]() |
![]() |
#11 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,548
|
You have to check the return value from GetDiskFreeSpaceEx no matter what, you cannot just look at the size. Usually the results of a function are undefined if the function fails. Look at the return value first, then look at the size!
IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#12 |
Moderator
Join Date: Aug 2004
Location: Poland
Posts: 563
|
Yes. I am checking if the return value is zero or not.
GetDiskFreeSpaceEx function If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0). To get extended error information, call GetLastError. |
![]() |
![]() |
![]() |
#13 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,548
|
You are not checking the return value in the code you posted.
IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#14 |
Moderator
Join Date: Aug 2004
Location: Poland
Posts: 563
|
I wrote:
System::Call "${GET_DISK_FREE_SPACE}(r0,.,.,.r1)" MessageBox MB_OK "Drive Space: $1" ${If} "$1" L= "0" ... Am I doing it wrong? |
![]() |
![]() |
![]() |
#15 |
Moderator
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,548
|
Yes.
System::Call "${GET_DISK_FREE_SPACE}(r0,.,.,.r1).r9" and then check $9 <> 0 IntOp $PostCount $PostCount + 1 |
![]() |
![]() |
![]() |
#16 |
Moderator
Join Date: Aug 2004
Location: Poland
Posts: 563
|
Yup. Fixed. thx.
... Todo: Read system plugin documentation and then again, and again ![]() |
![]() |
![]() |
![]() |
|
Tags |
disk, drive, space |
Thread Tools | Search this Thread |
Display Modes | |
|
|