.Net DriveInfo() with UNC paths?
Asked Answered
L

3

3

Good morning,

is there a way to get a DriveInfo instance for UNC paths (e.g. "\fors343a.ww123.somedomain.net\folder\1\") because for example...

var driveInfo = new System.IO.DriveInfo(drive);

... throws an ArgumentException ("Object must be a root directory (\"C:\\") or a drive letter (\"C\").") when using that UNC path above.

What would I use in order to retrieve information about that or e.g. how would I check whether a given folder resides on a local drive or an unc path?

Landholder answered 24/3, 2009 at 9:56 Comment(0)
D
4

The Remarks section for the DriveInfo constructor says:

The drive name must be either an uppercase or lowercase letter from 'a' to 'z'. You cannot use this method to obtain information on drive names that are nullNothingnullptra null reference (Nothing in Visual Basic) or use UNC (\server\share) paths.

I was able to make it work by mapping a network drive in Windows Explorer. That is, I mapped "\server\share" to drive Z, and then DriveInfo("Z:\\"); gave me what I expected.

Unfortunately, there's no simple way to map a network drive from C#. You'll either have to execute an external command (i.e. "net use z: \server\share"), or call the Windows WNetAddConnection2 API function to do it. Either way you go, you'll need to remove the drive mapping when you're done.

Despoliation answered 24/3, 2009 at 22:37 Comment(1)
really silly why c# doesn't have an easy method for unc paths. What if someone else maps something to that drive letter later then program would fail. There must be a reliable way of just using unc path aloneStorehouse
S
1

On Windows, the following works great in C# (at least to get the sizes, which is what is most commonly needed):

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool GetDiskFreeSpaceEx(string lpDirectoryName, out ulong lpFreeBytesAvailable, out ulong lpTotalNumberOfBytes, out ulong lpTotalNumberOfFreeBytes);

Here is some sample code (this hasn't actually been compiled in this form, but is bits and pieces from working code scattered across multiple files):

/// <summary>
/// A compilation of the properties of folders and files in a file system.
/// </summary>
public struct FileSystemProperties
{
    private FileSystemProperties(long? totalBytes, long? freeBytes, long? availableBytes)
        : this()
    {
        TotalBytes = totalBytes;
        FreeBytes = freeBytes;
        AvailableBytes = availableBytes;
    }
    /// <summary>
    /// Gets the total number of bytes on the drive.
    /// </summary>
    public long? TotalBytes { get; private set; }
    /// <summary>
    /// Gets the number of bytes free on the drive.
    /// </summary>
    public long? FreeBytes { get; private set; }
    /// <summary>
    /// Gets the number of bytes available on the drive (counts disk quotas).
    /// </summary>
    public long? AvailableBytes { get; private set; }

    /// <summary>
    /// Gets the properties for this file system.
    /// </summary>
    /// <param name="volumeIdentifier">The path whose volume properties are to be queried.</param>
    /// <param name="cancel">An optional <see cref="CancellationToken"/> that can be used to cancel the operation.</param>
    /// <returns>A <see cref="FileSystemProperties"/> containing the properties for the specified file system.</returns>
    public static FileSystemProperties GetProperties(string volumeIdentifier)
    {
        ulong available;
        ulong total;
        ulong free;
        if (GetDiskFreeSpaceEx(volumeIdentifier, out available, out total, out free))
        {
            return new FileSystemProperties((long)total, (long)free, (long)available);
        }
        return new FileSystemProperties(null, null, null);
    }
    /// <summary>
    /// Asynchronously gets the properties for this file system.
    /// </summary>
    /// <param name="volumeIdentifier">The path whose volume properties are to be queried.</param>
    /// <param name="cancel">An optional <see cref="CancellationToken"/> that can be used to cancel the operation.</param>
    /// <returns>A <see cref="Task"/> containing the <see cref="FileSystemProperties"/> for this entry.</returns>
    public static async Task<FileSystemProperties> GetPropertiesAsync(string volumeIdentifier, CancellationToken cancel = default(CancellationToken))
    {
        return await Task.Run(() =>
        {
            ulong available;
            ulong total;
            ulong free;
            if (GetDiskFreeSpaceEx(volumeIdentifier, out available, out total, out free))
            {
                return new FileSystemProperties((long)total, (long)free, (long)available);
            }
            return new FileSystemProperties(null, null, null);
        }, cancel);
    }
}

Don't try to use this on Linux or Mac--it would have to be rewritten for those (and I'd be interested to see that).

Speleology answered 1/1, 2016 at 0:54 Comment(0)
Z
0

This is an old post but neither answer is the simplest answer: Read the registry & get the mapped drives + UNC paths.

The registry path is HKCU\Network. Each key is the mapped drive letter & the RemotePath value is the UNC path for the drive mapping.

Simple registry read.

Zipper answered 25/1, 2022 at 10:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.