问题
I am writting a Metro-style app and want to determine the available storage capacity of the drive that hosts the user's music library. I want to disable some app functions while there's no or little space left on the disk. I am Using P/Invoke to call GetDiskFreeSpaceExW and get errors and no valid byte counts.
[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));
}
}
Debug output:
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
It appears I am providing the wrong input. The error codes are 3: ERROR_PATH_NOT_FOUND, 5: ERROR_ACCESS_DENIED, 123: ERROR_INVALID_NAME. I am running this code on Windows 8 RP (x64) with VS Ultimate 2012 RC, called from a Metro-style app. My app was granted permission to access the user's Music Library.
Has somebody managed to call this function successfully from within a Metro-style app? What kind of directory name is accepted to produce a valid reading of free space?
回答1:
I created the code in this question based on the Win32 and COM documentation for Metro. It calls out GetDiskFreeSpaceExW to be available in metro, but a managed app that uses P/Invoke needs to call GetDiskFreeSpaceEx instead:
[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));
}
回答2:
You might have better luck with
long free = new DriveInfo(driveName).TotalFreeSpace;
来源:https://stackoverflow.com/questions/11133084/unable-to-get-free-disk-space-from-metro-style-app