Search code examples
c#uwpaccess-deniedremovable-storage

UWP application unable to access USB drive even though permissions are set


I am working on an app that is responsible for formatting a USB drive and prepare it for further use on an embedded system.

I am formatting the drive using the following method that I found on stack overflow (unfortunately I did not save the link. I'll post it there if I find it again)

public static bool FormatUSB(string driveLetter, string fileSystem = "FAT32", bool quickFormat = true,
                                   int clusterSize = 4096, string label = "USB_0000", bool enableCompression = false)
        {
            //add logic to format Usb drive
            //verify conditions for the letter format: driveLetter[0] must be letter. driveLetter[1] must be ":" and all the characters mustn't be more than 2
            if (driveLetter.Length != 2 || driveLetter[1] != ':' || !char.IsLetter(driveLetter[0]))
                return false;

            //query and format given drive 
            //best option is to use ManagementObjectSearcher

            var files = Directory.GetFiles(driveLetter);
            var directories = Directory.GetDirectories(driveLetter);

            foreach (var item in files)
            {
                try
                {
                    File.Delete(item);
                }
                catch (UnauthorizedAccessException) { }
                catch (IOException) { }
            }

            foreach (var item in directories)
            {
                try
                {
                    Directory.Delete(item);
                }
                catch (UnauthorizedAccessException) { }
                catch (IOException) { }
            }

            ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"select * from Win32_Volume WHERE DriveLetter = '" + driveLetter + "'");
            foreach (ManagementObject vi in searcher.Get())
            {
                try
                {
                    var completed = false;
                    var watcher = new ManagementOperationObserver();

                    watcher.Completed += (sender, args) =>
                    {
                        Console.WriteLine("USB format completed " + args.Status);
                        completed = true;
                    };
                    watcher.Progress += (sender, args) =>
                    {
                        Console.WriteLine("USB format in progress " + args.Current);
                    };

                    vi.InvokeMethod(watcher, "Format", new object[] { fileSystem, quickFormat, clusterSize, label, enableCompression });

                    while (!completed) { System.Threading.Thread.Sleep(1000); }


                }
                catch
                {

                }
            }
            return true;
        }

I also added all the capabilities that should be required (I think) in order to access a removable drive in my manifest:

<?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"
  xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10"
  IgnorableNamespaces="uap mp rescap iot">

  <Identity
    Name="7b9becad-6afd-4872-bcb7-7f414c098edf"
    Publisher="CN=vitto"
    Version="1.0.0.0" />

  <mp:PhoneIdentity PhoneProductId="7b9becad-6afd-4872-bcb7-7f414c098edf" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>

  <Properties>
    <DisplayName>DiskMakerApp</DisplayName>
    <PublisherDisplayName>vitto</PublisherDisplayName>
    <Logo>Assets\StoreLogo.png</Logo>
  </Properties>

  <Dependencies>
    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
  </Dependencies>

  <Resources>
    <Resource Language="x-generate"/>
  </Resources>

  <Applications>
    <Application Id="App"
      Executable="$targetnametoken$.exe"
      EntryPoint="DiskMakerApp.App">
      <uap:VisualElements
        DisplayName="DiskMakerApp"
        Square150x150Logo="Assets\Square150x150Logo.png"
        Square44x44Logo="Assets\Square44x44Logo.png"
        Description="DiskMakerApp"
        BackgroundColor="transparent">
        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
        <uap:SplashScreen Image="Assets\SplashScreen.png" />
      </uap:VisualElements>
    </Application>
  </Applications>

  <Capabilities>
      <rescap:Capability Name="broadFileSystemAccess" />
      <rescap:Capability Name="appCaptureSettings" />
      <Capability Name="internetClient" />
    <uap:Capability Name="removableStorage" />
      <iot:Capability Name="systemManagement"/>
      <DeviceCapability Name="usb"/>
  </Capabilities>
</Package>

And also allowed access to the file system in Window's settings page: enter image description here

But I am still getting: enter image description here

I am wondering if I am missing anything. Is there a way I could run the app as an administrator^ Would that solve the issue? (In any case, only admins would be able to run that app in a real life scenario)


Solution

  • UWP application unable to access USB drive even though permissions are set

    Directory.GetFiles can't not use to access file with path in UWP platform. And you can only use Windows Storage API to access file with path (enable broadFileSystemAccess ), by the way, System.Management Namespace is not work for UWP platform, and if you want to format USB device within UWP app, please use desktop extension to process. for more please refer stefan' blog UWP with Desktop Extension