首页 > 解决方案 > 条件未按预期解决

问题描述

我正在使用这个库来获取可用磁盘空间的数量:

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

我在方法中使用它:

var result = GetDiskFreeSpaceEx(desiredInstallLocation, out var freeBytesAvailable, out var totalNumberOfBytes, out var totalNumberOfFreeBytes);

然后条件来了:

if (gameSize > (int)freeBytesAvailable)
{
    MessageBox.Show($"There is not enough disk space!\nYou need to free at least {ConvertBytesToMegabytes(gameSize - (int)freeBytesAvailable)} MB.", "Not enough space on a disk", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
    return false;
}

以下是调试记录:

在此处输入图像描述

在此处输入图像描述

为什么条件通过了?

标签: c#wpf.net-corekernelmarshalling

解决方案


问题是您freeBytesAvailable转换为int,但它是ulong. is返回的值GetDiskFreeSpaceEx超过了( )377,325,965,312的最大值。int2,147,483,647

因此,至少 32 位ulong用于向下转换int,在您的情况下为负数,因为它的最高有效位是1. 因此,条件将是true

11011010011000010101000000000000 (-631156736)

相反,将gameSizeto 转换为ulong,这样您就不会丢失信息。

if ((ulong)gameSize > freeBytesAvailable)

推荐阅读