0

我正在编写一个 Metro 风格的应用程序,并想确定托管用户音乐库的驱动器的可用存储容量。我想在磁盘上没有剩余空间或剩余空间很少时禁用某些应用程序功能。我正在使用 P/Invoke 调用 GetDiskFreeSpaceExW 并得到错误并且没有有效的字节数。

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetDiskFreeSpaceExW(
   string lpDirectoryName,
   out ulong lpFreeBytesAvailable,
   out ulong lpTotalNumberOfBytes,
   out ulong lpTotalNumberOfFreeBytes
);

[DllImport("kernel32.dll", SetLastError = true)]
static extern int GetLastError();

async static void TestDiskSpace()
{
   IStorageFolder musicFolder = KnownFolders.MusicLibrary;
   IStorageFolder testFolder = await musicFolder.CreateFolderAsync("test", CreationCollisionOption.OpenIfExists);
   IStorageFolder appFolder = ApplicationData.Current.LocalFolder; 
   ulong a, b, c;
   string[] paths = new[]
   {
      null,
      "."
      "C:",
      "C:\\",
      "C:\\Users\\Jonas\\Music",
      "C:\\Users\\Jonas\\Music\\",
      musicFolder.Path,
      testFolder.Path,
      appFolder.Path
   };
   foreach(string path in paths)
   {
      GetDiskFreeSpaceExW(path, out a, out b, out c);
      int error = GetLastError();
      Debug.WriteLine(
         string.Format("{0} - Error {1} - free = {2}",
         path ?? "null", error, a));
   }
}

调试输出:

null - Error 5 - free = 0
. - Error 123 - free = 0
C: - Error 3 - free = 0
C:\ - Error 3 - free = 0
C:\Users\J909\Music - Error 3 - free = 0
C:\Users\J909\Music\ - Error 3 - free = 0
 - Error 3 - free = 0
C:\Users\J909\Music\test - Error 123 - free = 0
C:\Users\J909\AppData\Local\Packages\long-app-id\LocalState - Error 123 - free = 0

看来我提供了错误的输入。错误代码为 3:ERROR_PATH_NOT_FOUND、5:ERROR_ACCESS_DENIED、123:ERROR_INVALID_NAME。我在带有 VS Ultimate 2012 RC 的 Windows 8 RP (x64) 上运行此代码,从 Metro 风格的应用程序调用。我的应用被授予访问用户音乐库的权限。

有人设法从 Metro 风格的应用程序中成功调用此函数吗?接受什么样的目录名称来产生对可用空间的有效读取?

4

2 回答 2

4

我根据Metro 的 Win32 和 COM 文档创建了这个问题中的代码。它调用 GetDiskFreeSpaceExW 以在 Metro 中可用,但使用 P/Invoke 的托管应用程序需要调用 GetDiskFreeSpaceEx:

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetDiskFreeSpaceEx(
    string lpDirectoryName,
    out ulong lpFreeBytesAvailable,
    out ulong lpTotalNumberOfBytes,
    out ulong lpTotalNumberOfFreeBytes);

static void TestDiskSpace()
{
    IStorageFolder appFolder = ApplicationData.Current.LocalFolder;
    ulong a, b, c;
    if(GetDiskFreeSpaceEx(appFolder.Path, out a, out b, out c))
        Debug.WriteLine(string.Format("{0} bytes free", a));
}
于 2012-06-29T22:09:57.610 回答
0

你可能有更好的运气

long free = new DriveInfo(driveName).TotalFreeSpace;
于 2012-06-21T07:04:29.583 回答