.Net Core Найдите свободное место на диске в разных ОС

Есть ли способ найти свободное место в разных ОС (в основном Linux и Windows) с помощью C # ASP.NET Core.

Я нашел способ (используя DriveInfo) получить свободное место, передав имя диска в качестве параметра. Это отлично работает в Windows, но я хочу того же и для Linux.

public static int CheckDiskSpace(string driveLetter)
{
    DriveInfo drive = new DriveInfo(driveLetter);

    var totalBytes = drive.TotalSize;
    var freeBytes = drive.AvailableFreeSpace;

    var freePercent = (int)((100 * freeBytes) / totalBytes);

    return freePercent;
}

Передача диска (C:/), как показано ниже:

var freespace = DriveDetails.CheckDiskSpace("C:/");

Обновление: это также работает для Linux.


person Dot Net Dev    schedule 17.07.2018    source источник
comment
Вы знаете, что ваш код, запускаемый как часть приложения ASP.NET Core, выполняется на сервере, а не на клиенте, верно? Таким образом, вы всегда будете получать примерно одну и ту же информацию о дисковом пространстве сервера.   -  person Camilo Terevinto    schedule 18.07.2018
comment
Название моего вопроса было изменено, мне нужно найти свободное место на диске приложения в разных ОС   -  person Dot Net Dev    schedule 18.07.2018
comment
@ johnny5 Этот дубликат даже близко не соответствует тому, о чем здесь спрашивают. OP хочет путь к запущенному в данный момент приложению, а не к исходному коду. Редактирование было не совсем уместным   -  person Camilo Terevinto    schedule 18.07.2018
comment
Моя ошибка, но текущий заголовок вводит в заблуждение, этот вопрос связан с поиском пути, а не места на диске.   -  person johnny 5    schedule 18.07.2018
comment
@ johnny5, найти путь - это часть вопроса, главный вопрос - найти место на диске.   -  person Dot Net Dev    schedule 18.07.2018
comment
Dot Net Dev, вы сказали, что уже нашли способ использовать информацию о диске, разве этот вопрос больше не относится к получению пути?   -  person johnny 5    schedule 18.07.2018
comment
@johnny5 Я нашел способ в Windows. Я хочу что-то, что работает для Windows, Linux.   -  person Dot Net Dev    schedule 18.07.2018


Ответы (2)


Для Net.Core под Linux вы можете просто позвонить

var freeBytes = new DriveInfo(path).AvailableFreeSpace; 

где путь — это некоторое относительное или абсолютное имя папки, и он автоматически предоставляет вам информацию о диске о разделе, в котором хранится этот путь. Протестировано на Net.Core 2.2.

Напротив, в Windows вы либо:

A) Необходимо указать букву диска (которую, к сожалению, нельзя получить непосредственно из относительного пути, поэтому вам нужно выполнить некоторую дополнительную работу, и ее вообще нельзя вычислить для пути UNC).

B) Необходимо использовать Windows API (это также работает с путями UNC):

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

GetDiskFreeSpaceEx(path, out var freeBytes, out var _, out var __);

Есть также некоторые другие исключительные случаи, поэтому в итоге мое использование выглядит следующим образом:

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

public long? CheckDiskSpace()
{
    long? freeBytes = null;

    try     
    {
#if DEBUG //RuntimeInformation and OSPlatform seem to not exist while building for Linux platform
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            long freeBytesOut;
            //On some drives (for example, RAM drives, GetDiskFreeSpaceEx does not work
            if (GetDiskFreeSpaceEx(_path, out freeBytesOut, out var _, out var __))
                freeBytes = freeBytesOut;
        }
#endif

        if (freeBytes == null)
        {
            //DriveInfo works well on paths in Linux    //TODO: what about Mac?
            var drive = new DriveInfo(_path);
            freeBytes = drive.AvailableFreeSpace;
        }
    }
    catch (ArgumentException)
    {
        //ignore the exception
    }

    return freeBytes;
}
person Roland Pihlakas    schedule 18.07.2020

Вы можете использовать System.AppContext.BaseDirectory, если используете .Net Core

(OR)

Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
person Rahul    schedule 17.07.2018