Не правильно выводятся кластеры на диске и день недели
Не правильно выводится день недели (всегда выводится понедельник monday, а сегодня вообще четверг), так же не правильно считает количество кластеров на диске считает разные числа, а должно быть 4096. Само задание
- Функции 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 шт):
Проблема с выводом дня недели заключается в том, что код использует 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)
{
}
}
}