Search code examples
c#dlluwpkernel32

Call GetDiskFreeSpaceExA from UWP (C#)


I am working on a UWP app (C#, Visual Studio 2019) and I want to find out the total, free for user and free space of C:. In order to do this, I want to call GetDiskFreeSpaceExA (about GetDiskFreeSpaceExA: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespaceexa).

I tried the following:

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
 [return: MarshalAs(UnmanagedType.Bool)]
 static extern bool GetDiskFreeSpaceExA(string path,
                                        out ulong freeBytesForUser,
                                        out ulong totalNumberOfBytes,
                                        out ulong totalNumberOfFreeBytes);

Then, I call GetDiskFreeSpaceExA:

ulong freeUser;
ulong total;
ulong free;
string pathC= @"C:\"; // also tried with "C:\\" and @"C:\\"
bool success =  GetDiskFreeSpaceExA(pathC,
                                    out freeUser,
                                    out total,
                                    out free);

if(success)
{
     // ...
}

success is always false. Why? How can I find out the space on C: from UWP? I know that there are some C# methods, but I want DLLs.

Thank you!


Solution

  • You could add the broadFileSystemAccess capability in Package.appxmanifest. This is a restricted capability. Access is configurable in Settings > Privacy > File system.

    Please refer to the following code.

    Package.appxmanifest:

    <?xml version="1.0" encoding="utf-8"?>
    <Package
    xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
    xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
    xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"   
    
     xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
    IgnorableNamespaces="uap mp rescap">
    ……
     <Capabilities>
       <rescap:Capability Name="broadFileSystemAccess" />
       <Capability Name="internetClient" />   
     </Capabilities>
    

    Code behind:

    public async void test()
        {
    
            const String k_freeSpace = "System.FreeSpace";
            const String k_totalSpace = "System.Capacity";
    
            try
                {
                   
                    StorageFolder folder = await StorageFolder.GetFolderFromPathAsync("C:\\");
                    var props = await folder.Properties.RetrievePropertiesAsync(new string[] { k_freeSpace, k_totalSpace });
                    Debug.WriteLine("FreeSpace: " + (UInt64)props[k_freeSpace]);
                    Debug.WriteLine("Capacity:  " + (UInt64)props[k_totalSpace]);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(String.Format("Couldn't get info for drive C."));
                }
            
        }