Search code examples
c#compact-frameworkwindows-cemscorlibdriveinfo

How can I determine free space on a Windows CE device?


I need to determine how much free space there is on a Windows CE device, to conditionally determine whether a particular operation should proceed.

I thought Ken Blanco's answer here (which bears a striking similarity to the example yonder) would work, which I adapted as:

internal static bool EnoughStorageSpace(long spaceNeeded)
{
    DriveInfo[] allDrives = DriveInfo.GetDrives();
    long freeSpace = 0;
    foreach (DriveInfo di in allDrives)
    {
        if (di.IsReady)
        {
            freeSpace = di.AvailableFreeSpace;
        }
    }
    return freeSpace >= spaceNeeded;
}

...but DriveInfo is not available in my Windows CE / compact framework project.

I am referencing mscorlib, and am using System.IO, but as DriveInfo is redder than a Kansas City Chiefs jersey in my editor, I reckon it's not available to me.

Is there an alternative way of accomplishing the same thing?

UPDATE

I adapted this:

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

public static bool EnoughStorageSpace(ulong freespaceNeeded)
{
    String folderName = "C:\\";
    ulong freespace = 0;
    if (string.IsNullOrEmpty(folderName))
    {
        throw new ArgumentNullException("folderName");
    }    

    ulong free, dummy1, dummy2;

    if (GetDiskFreeSpaceEx(folderName, out free, out dummy1, out dummy2))
    {
        freespace = free;
    }
    return freespace >= freespaceNeeded;
}

...from here, which compiles, but I don't know what "folderName" should be for a Windows CE device; in Windows Explorer, it has no name at all. I'm sure what I have as of now ("C:\") is not right...

UPDATE 2

According to "Windows programmer" here: "If you're running Windows CE then \ is the root directory"

So, should I use:

String folderName = "\";

...or do I need to escape it:

String folderName = "\\";

...or...???


Solution

  • The Windows CE API documentation explains how to use the function: http://msdn.microsoft.com/en-us/library/ms890887.aspx

    lpDirectoryName

    [in] Pointer to a null-terminated string that specifies a directory on the specified disk. This string can be a Universal Naming Convention (UNC) name.

    If lpDirectoryName is NULL, the GetDiskFreeSpaceEx function obtains information about the object store. Note lpDirectoryName does not have to specify the root directory on a disk. The function accepts any directory on the disk.

    Windows CE doesn't use drive-letters, instead the filesystem is a unified tree that, like on Linux, can be comprised of directories that don't actually exist, or where subdirectories of a parent directory can exist on different physical volumes (or perhaps not even traditional volumes at all: CE supports merging ROM and RAM volumes with traditional Flash storage, all in the same filesystem tree).

    Assuming that your device has multiple volumes combined into a single tree, we can still assume that your application's directory will be on a single volume, and it is this volume you're interested in, in which case this code will suit you:

    String executingFileName = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
    String executingDirectory = System.IO.Path.GetDirectoryName( executingFileName );
    
    UInt64 userFreeBytes, totalDiskBytes, totalFreeBytes;
    if( GetDiskFreeSpaceEx( executingDirectory, out userFreeBytes, out totalDiskBytes, totalFreeBytes ) {
        // `userFreeBytes` is the number of bytes available for your program to write to on the mounted volume that contains your application code.
    }