Не правильно выводятся кластеры на диске и день недели

Не правильно выводится день недели (всегда выводится понедельник monday, а сегодня вообще четверг), так же не правильно считает количество кластеров на диске считает разные числа, а должно быть 4096. Само задание

  1. Функции API Используя функции GetSystemTime и GetDiskFreeSpace определить день недели и количество свободных кластеров на диске. Не могу разобраться что я делаю не так.Спасибо за ответ заранее

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;// Подключаем пространство имен, которое содержит классы для создания графического интерфейса Windows Forms.
using System.Runtime.InteropServices;// Подключаем пространство имен, которое содержит классы для взаимодействия с низкоуровневыми операционными системами через вызовы API.

namespace WindowsFormsApp5
{
    public partial class Form1 : Form
    {
        [DllImport("kernel32.dll")]
        public static extern void GetSystemTime(ref SYSTEMTIME lpSystemTime);

        [DllImport("kernel32.dll")]
        public static extern bool GetDiskFreeSpace(string lpRootPathName, out uint lpSectorsPerCluster, out uint lpBytesPerSector,
            out uint lpNumberOfFreeClusters, out uint lpTotalNumberOfClusters);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Get current day of the week
            DayOfWeek dayOfWeek = DateTime.Now.DayOfWeek;
            // Display the result
            textBox1.Text = "Сегодня " + dayOfWeek.ToString();

            // Get information about the free space on the C drive
            uint sectorsPerCluster, bytesPerSector, numberOfFreeClusters, totalNumberOfClusters;
            if (GetDiskFreeSpace("C:\\", out sectorsPerCluster, out bytesPerSector, out numberOfFreeClusters, out totalNumberOfClusters))
            {
                // Calculate the free space in megabytes
                uint freeSpaceInMB = (uint)((numberOfFreeClusters * sectorsPerCluster * bytesPerSector) / (1024 * 1024));
                // Display the result
                textBox1.AppendText(Environment.NewLine + "  На диске свободно " + freeSpaceInMB + " МБ");
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SYSTEMTIME
        {
            public ushort wYear;
            public ushort wMonth;
            public ushort wDayOfWeek;
            public ushort wDay;
            public ushort wHour;
            public ushort wMinute;
            public ushort wSecond;
            public ushort wMilliseconds;
            public ushort wHighDateTime;
            public ushort wLowDateTime;
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}


Ответы (1 шт):

Автор решения: FIP

Проблема с выводом дня недели заключается в том, что код использует DateTime.Now.DayOfWeek, который возвращает текущий день недели для локального времени, в то время как используемая функция API GetSystemTime возвращает текущее время в UTC. Чтобы исправить это, можно использовать функцию GetLocalTime вместо GetSystemTime, которая возвращает локальное время:

[DllImport("kernel32.dll")]
public static extern void GetLocalTime(ref SYSTEMTIME lpSystemTime);

Затем можно получить день недели, используя метод ToString("dddd") объекта DateTime:

SYSTEMTIME st = new SYSTEMTIME();
GetLocalTime(ref st);
DayOfWeek dayOfWeek = new DateTime(st.wYear, st.wMonth, st.wDay).DayOfWeek;
textBox1.Text = "Сегодня " + dayOfWeek.ToString("dddd");

Относительно проблемы с количеством кластеров, необходимо убедиться, что используется правильный корневой путь для проверки дискового пространства. В данном случае используется корневой путь "C:", что может быть не верным для некоторых конфигураций. Чтобы узнать правильный корневой путь, можно использовать функцию GetLogicalDriveStrings, которая вернет список всех логических дисков:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern uint GetLogicalDriveStrings(uint nBufferLength, [Out] StringBuilder lpBuffer);

StringBuilder sb = new StringBuilder(256);
GetLogicalDriveStrings(256, sb);
string[] drives = sb.ToString().Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);

foreach (string drive in drives)
{
    uint sectorsPerCluster, bytesPerSector, numberOfFreeClusters, totalNumberOfClusters;
    if (GetDiskFreeSpace(drive, out sectorsPerCluster, out bytesPerSector, out numberOfFreeClusters, out totalNumberOfClusters))
    {
        // Calculate the free space in megabytes
        uint freeSpaceInMB = (uint)((numberOfFreeClusters * sectorsPerCluster * bytesPerSector) / (1024 * 1024));
        // Display the result
        textBox1.AppendText(Environment.NewLine + "  На диске " + drive + " свободно " + freeSpaceInMB + " МБ");
    }
}

Таким образом, весь исправленный код будет выглядеть так:

using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp5
{
    public partial class Form1 : Form
    {
        [DllImport("kernel32.dll")]
        public static extern void GetSystemTime(ref SYSTEMTIME lpSystemTime);

        [DllImport("kernel32.dll")]
        public static extern bool GetDiskFreeSpace(string lpRootPathName, out uint lpSectorsPerCluster, out uint lpBytesPerSector,
            out uint lpNumberOfFreeClusters, out uint lpTotalNumberOfClusters);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Get current day of the week
            SYSTEMTIME systemTime = new SYSTEMTIME();
            GetSystemTime(ref systemTime);
            DayOfWeek dayOfWeek = (DayOfWeek)systemTime.wDayOfWeek;
            // Display the result
            textBox1.Text = "Сегодня " + dayOfWeek.ToString();

            // Get information about the free space on the C drive
            uint sectorsPerCluster, bytesPerSector, numberOfFreeClusters, totalNumberOfClusters;
            if (GetDiskFreeSpace("C:\\", out sectorsPerCluster, out bytesPerSector, out numberOfFreeClusters, out totalNumberOfClusters))
            {
                // Calculate the free space in megabytes
                ulong freeSpaceInMB = numberOfFreeClusters * (ulong)sectorsPerCluster * (ulong)bytesPerSector / (1024 * 1024);
                // Display the result
                textBox1.AppendText(Environment.NewLine + "  На диске свободно " + freeSpaceInMB + " МБ");
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SYSTEMTIME
        {
            public ushort wYear;
            public ushort wMonth;
            public ushort wDayOfWeek;
            public ushort wDay;
            public ushort wHour;
            public ushort wMinute;
            public ushort wSecond;
            public ushort wMilliseconds;
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
→ Ссылка