【问题标题】:.Net DriveInfo() with UNC paths?.Net DriveInfo() 与 UNC 路径?
【发布时间】:2010-10-15 04:09:11
【问题描述】:

早上好,

有没有办法获取 UNC 路径的 DriveInfo 实例(例如“\fors343a.ww123.somedomain.net\folder\1\”),因为例如...

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

... 使用上述 UNC 路径时,会引发 ArgumentException(“对象必须是根目录 (\"C:\\") 或驱动器号 (\"C\")。")。

我将使用什么来检索有关该信息的信息,例如如何检查给定文件夹是否位于本地驱动器或 unc 路径上?

【问题讨论】:

    标签: .net unc driveinfo


    【解决方案1】:

    DriveInfo 构造函数的备注部分说:

    驱动器名称必须是 来自“a”的大写或小写字母 到“z”。您不能使用此方法 获取有关驱动器名称的信息 是 nullNothingnullptra 空引用 (Visual Basic 中没有)或使用 UNC (\server\share) 路径。

    我能够通过在 Windows 资源管理器中映射网络驱动器来使其工作。也就是说,我将“\server\share”映射到驱动器 Z,然后DriveInfo("Z:\\"); 给了我我期望的结果。

    不幸的是,没有简单的方法可以从 C# 映射网络驱动器。您要么必须执行外部命令(即“net use z:\server\share”),要么调用 Windows WNetAddConnection2 API 函数来执行此操作。无论哪种方式,您都需要在完成后删除驱动器映射。

    【讨论】:

    • 真的很傻,为什么 c# 没有用于 unc 路径的简单方法。如果其他人稍后将某些东西映射到该驱动器号,那么程序将会失败。必须有一种可靠的方法来单独使用 unc 路径
    【解决方案2】:

    在 Windows 上,以下内容在 C# 中效果很好(至少可以获取最常用的尺寸):

        [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);
    

    这是一些示例代码(实际上并没有以这种形式编译,而是分散在多个文件中的工作代码的点点滴滴):

    /// <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);
        }
    }
    

    不要尝试在 Linux 或 Mac 上使用它——它必须为它们重写(我很想看看)。

    【讨论】:

      【解决方案3】:

      这是一篇旧帖子,但两个答案都不是最简单的答案:读取注册表并获取映射驱动器 + UNC 路径。

      注册表路径是 HKCU\Network。每个键都是映射的驱动器号,RemotePath 值是驱动器映射的 UNC 路径。

      简单的注册表读取。

      【讨论】:

        猜你喜欢
        • 2012-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多