rlively
asked on
Disk free space on network drives using UNC path? (400 pts)
How can I get a list of drives available on a server by passing in the
server UNC (\\ServerName) and then for each of those drives get the
available disk space? (or at least for one known server and drive be able to get the free space on that drive - \\ServerName\E$).
What I want to do is very similar to this question but it will be done from a Windows Forms application instead of an ASP page: https://www.experts-exchange.com/questions/20175600/Get-disksize-and-free-space-of-hd's-from-remote-server.html
I have looked at the System.Management and System.IO classes in help,
searched newsgroup postings (dotnet247.com, etc) and on google and I have
had no luck finding any examples. There are plenty of examples for getting
the free disk space and enumerating drives for the local machine using FSO and System.Management classes and WQL, but not
for network servers.
server UNC (\\ServerName) and then for each of those drives get the
available disk space? (or at least for one known server and drive be able to get the free space on that drive - \\ServerName\E$).
What I want to do is very similar to this question but it will be done from a Windows Forms application instead of an ASP page: https://www.experts-exchange.com/questions/20175600/Get-disksize-and-free-space-of-hd's-from-remote-server.html
I have looked at the System.Management and System.IO classes in help,
searched newsgroup postings (dotnet247.com, etc) and on google and I have
had no luck finding any examples. There are plenty of examples for getting
the free disk space and enumerating drives for the local machine using FSO and System.Management classes and WQL, but not
for network servers.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Here is one of my failed attempts: \\ServerName has only one drive, but moMOC contains more than one object.
The first MessageBox I see is blank, and the second throws an exception: "System.ArgumentException: Argument 'Prompt' cannot be converted to type 'String'."
When I change MsgBox to MessageBox.Show I get a different exception: "System.InvalidCastExcepti on: Cast from type 'UInt64' to type 'String' is not valid. at Microsoft.VisualBasic.Comp ilerServic es.StringT ype.FromOb ject(Objec t Value)"
moMOC.Count and moMOC.Items.Count both throw exceptions:
Count: <error: an exception of type: {System.NotSupportedExcept ion} occurred>
Dim oOptions As New System.Management.Connecti onOptions( )
Dim moMOS As System.Management.Manageme ntObjectSe archer
Dim moMOC As System.Management.Manageme ntObjectCo llection
Dim moObject As System.Management.Manageme ntObject
'Dim moScope As New System.Management.Manageme ntScope("\ \ServerNam e")
oOptions.Username = "DOMAIN\USERID"
oOptions.Password = "PASSWORD"
moMOS = New System.Management.Manageme ntObjectSe archer("\\ ServerName \", _
"select * from Win32_LogicalDisk")
moMOC = moMOS.Get
For Each moObject In moMOC
'There should only be one.
MsgBox(moObject("FreeSpace "))
Next
The first MessageBox I see is blank, and the second throws an exception: "System.ArgumentException:
When I change MsgBox to MessageBox.Show I get a different exception: "System.InvalidCastExcepti
moMOC.Count and moMOC.Items.Count both throw exceptions:
Count: <error: an exception of type: {System.NotSupportedExcept
Dim oOptions As New System.Management.Connecti
Dim moMOS As System.Management.Manageme
Dim moMOC As System.Management.Manageme
Dim moObject As System.Management.Manageme
'Dim moScope As New System.Management.Manageme
oOptions.Username = "DOMAIN\USERID"
oOptions.Password = "PASSWORD"
moMOS = New System.Management.Manageme
"select * from Win32_LogicalDisk")
moMOC = moMOS.Get
For Each moObject In moMOC
'There should only be one.
MsgBox(moObject("FreeSpace
Next
ASKER
Thanks for getting me on the right track! I needed to convert your code to VB.NET so this is what I have:
Declare Function GetDiskFreeSpaceEx Lib "kernel32.dll" Alias "GetDiskFreeSpaceExA" _
(ByVal lpDirectoryName As IntPtr, _
ByVal lpFreeBytesAvailableToCall er As Long, _
ByVal lpTotalNumberOfBytes As Long, _
ByVal lpTotalNumberOfFreeBytes As Long) As Integer
Public Function GetAvailableDiskSpace(ByVa l strUncPath As String) As Long
Dim lBytesAvailable As Long = -1
Dim lTotalBytes As Long = 0
Dim lTotalFreeBytes As Long = 0
Dim pszPath As IntPtr
pszPath = System.Runtime.InteropServ ices.Marsh al.StringT oHGlobalAu to(strUncP ath)
Try
Dim iVal As Integer
iVal = GetDiskFreeSpaceEx(pszPath , lBytesAvailable, _
lTotalBytes, lTotalFreeBytes)
Catch excep As Exception
MessageBox.Show(excep.ToSt ring)
Finally
System.Runtime.InteropServ ices.Marsh al.FreeHGl obal(pszPa th)
End Try
Return lBytesAvailable
End Function
--------------------
But when I run it I get an "Object reference not set to an instance of an object." exception on the line calling the API and I can't figure out why. The contents of the parameters are as follows: pszPath = 1886200, lBytesAvailable = -1, lTotalBytes = 0, lTotalFreeBytes = 0.
Any idea why this doesn't work for me and I get an exception every time? The string I am sending in is "\\ServerName\C$"
Declare Function GetDiskFreeSpaceEx Lib "kernel32.dll" Alias "GetDiskFreeSpaceExA" _
(ByVal lpDirectoryName As IntPtr, _
ByVal lpFreeBytesAvailableToCall
ByVal lpTotalNumberOfBytes As Long, _
ByVal lpTotalNumberOfFreeBytes As Long) As Integer
Public Function GetAvailableDiskSpace(ByVa
Dim lBytesAvailable As Long = -1
Dim lTotalBytes As Long = 0
Dim lTotalFreeBytes As Long = 0
Dim pszPath As IntPtr
pszPath = System.Runtime.InteropServ
Try
Dim iVal As Integer
iVal = GetDiskFreeSpaceEx(pszPath
lTotalBytes, lTotalFreeBytes)
Catch excep As Exception
MessageBox.Show(excep.ToSt
Finally
System.Runtime.InteropServ
End Try
Return lBytesAvailable
End Function
--------------------
But when I run it I get an "Object reference not set to an instance of an object." exception on the line calling the API and I can't figure out why. The contents of the parameters are as follows: pszPath = 1886200, lBytesAvailable = -1, lTotalBytes = 0, lTotalFreeBytes = 0.
Any idea why this doesn't work for me and I get an exception every time? The string I am sending in is "\\ServerName\C$"
ASKER
Nevermind! I just realized my mistake. All the params defaulted to ByVal in my API declaration and I forgot to change them to ByRef. It works now :)
ASKER
Ok, the call goes through just fine, but it doesn't matter which server I send into the call I get the same return value each time. It appears to be returning the disk free space on my own local C:\ drive, and never the free space on the server that I am querying. I even sent a UNC path for a drive that doesn't even exist ("\\Server2\E$" where Server2 only has a C:\ drive) and it still returned the free space on my own C:\ drive.
In what format do UNC paths need to be for this function to work on them?
In what format do UNC paths need to be for this function to work on them?
Sorru about C# code. I Am just not good at VB at all. Its great that things have worked out for you using Interop.
Put a break point in GetAvailableDiskSpace function and see if you are getting right values or not. And most importantly check what folder path is being sent as input to API. I have been using this component for some time and never had any trouble.
UNC path should be ..
\\Server\\Drive\
UNC path should be ..
\\Server\\Drive\
ASKER
Ok, the call goes through just fine, but it doesn't matter which server I send into the call I get the same return value each time. It appears to be returning the disk free space on my own local C:\ drive, and never the free space on the server that I am querying. I even sent a UNC path for a drive that doesn't even exist ("\\Server2\E$" where Server2 only has a C:\ drive) and it still returned the free space on my own C:\ drive.
In what format do UNC paths need to be for this function to work on them?
In what format do UNC paths need to be for this function to work on them?
UNC path.
\\Server\Drive\
In your case it would be..
\\Server2\E$\
\\Server\Drive\
In your case it would be..
\\Server2\E$\
ASKER
I'm sending in for strUNCPath "\\ATLCPAIMSWEB\\C\" "\\ATLCPAIMSWEB\\E\" "\\ATLCPDSQL03\\C\" and various others, but lTotalFreeBytes is still always the available space on my C:\ drive.
These are the values returned each time (always the same) - these values are accurate for my C:\ drive (I have converted the bytes to GB).
ltotalbytes 29.21964 GB
ltotalbytes 37.2601 GB
ltotalfreebytes 29.21964 GB
Does anything look amiss in the API Declaration or the function?
If this function should work with UNC paths then I should be very close to a solution.
Sorry for all the double-posts. I only hit submit once for each post.
These are the values returned each time (always the same) - these values are accurate for my C:\ drive (I have converted the bytes to GB).
ltotalbytes 29.21964 GB
ltotalbytes 37.2601 GB
ltotalfreebytes 29.21964 GB
Does anything look amiss in the API Declaration or the function?
If this function should work with UNC paths then I should be very close to a solution.
Sorry for all the double-posts. I only hit submit once for each post.
ASKER
I did get it working. The help for GetDiskFreeSpaceEx states that you can send a UNC path in directly. Thanks for the help. GetAvailableDiskSpace("\\S ERVER\E$\" )) works with the API called to use the passed in UNC path instead of the pszPath:
iVal = GetDiskFreeSpaceEx(strUncP ath, lBytesAvailable, lTotalBytes, lTotalFreeBytes)
iVal = GetDiskFreeSpaceEx(strUncP
ASKER
The first MessageBox I see is blank, and the second throws an exception: "System.ArgumentException:
When I change MsgBox to MessageBox.Show I get a different exception: "System.InvalidCastExcepti
moMOC.Count and moMOC.Items.Count both throw exceptions:
Count: <error: an exception of type: {System.NotSupportedExcept
Dim oOptions As New System.Management.Connecti
Dim moMOS As System.Management.Manageme
Dim moMOC As System.Management.Manageme
Dim moObject As System.Management.Manageme
'Dim moScope As New System.Management.Manageme
oOptions.Username = "DOMAIN\USERID"
oOptions.Password = "PASSWORD"
moMOS = New System.Management.Manageme
"select * from Win32_LogicalDisk")
moMOC = moMOS.Get
For Each moObject In moMOC
'There should only be one.
MsgBox(moObject("FreeSpace
Next