question

ansalc-1556 avatar image
0 Votes"
ansalc-1556 asked ·

Reading from SD card

I want to use the StreamReader class to read from an encrypted SD card on a computer.

In VB.NET I successfully use


     Dim sr As New System.IO.StreamReader("F:\log\my item.txt")

     Dim id As String() = sr.ReadLine().Split(CChar("&"))

I have read the information at https://docs.microsoft.com/en-us/windows/uwp/files/access-the-sd-card

But I am still at a loss.

I have allowed Removable Storage in the manifest and have included the following:

     private async void Page_Loaded(object sender, RoutedEventArgs e)
     {
         

         StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;

     
         StorageFolder sdCard = (await externalDevices.GetFoldersAsync()).FirstOrDefault();


But I get "Access denied" error at the last line.

My SD card is in a slot in the laptop. I have read: If your SD card reader is an embedded reader (for example, a slot in the laptop or PC itself), it may not be accessible through KnownFolders.RemovableDevices. but I don't know if this is the reason.


Can someone detailed the steps required to do the above?

Thank you



windows-uwp
· 5
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

This seems to be by design since the document already mentioned this behavior. If you use StorageFile.GetFileFromPathAsync(@"F:\log\my item.txt"), add broadFileSystemAccess capability and allow your app can access file system in the setting, can you get the file successfully?

0 Votes 0 · ·

I have added broadFileSystemAccess and my computer says "File system access for this device is on"

However when I run

private async void Page_Loaded(object sender, RoutedEventArgs e)
{

         StorageFile storageFile = await StorageFile.GetFileFromPathAsync(@"F:\log\My Item.txt"); 

         string storageFileName;

         storageFileName = storageFile.Name;



It compiles and runs fine, but I get error CS0103: The name 'storageFileName' does not exist in the current context.

The same happens if I read the same file from the Desktop, where I have copied it:

StorageFile storageFile = await StorageFile.GetFileFromPathAsync(@"C:\Users\Antonio\Desktop\My Item.txt"));

Consequently, the streamreader that I have next, does not read anything

0 Votes 0 · ·

Based on the exception, it seems the storageFileName property has something wrong, when you call the GetFileFromPathAsync() method, can it return the storageFile successfully? If you try to get other file, will the same issue occur?

0 Votes 0 · ·
Show more comments
danielescipioni avatar image
0 Votes"
danielescipioni answered ·

Here https://docs.microsoft.com/en-us/windows/uwp/files/access-the-sd-card#requirements-for-accessing-files-on-the-sd-card the documentation tells

You also have to register to handle the file extensions associated with the type of media that you want to access.

So you have to go to package.appxmanifest and register the .txt extension:

  • double click on Package.appxmanifest

  • go in Declaration section

  • under "Available Declarations" select "File Type Associations" and Click Add

  • fill "Name" (no spaces)

  • fill "File type" with .txt

  • Save

  • Rebuild

After file extension registration the code below works for me

StorageFolder externalDevices = KnownFolders.RemovableDevices;
try
{
    StorageFile storageFile = await externalDevices.GetFileAsync(@"F:\log\my item.txt");
}
catch (Exception e)
{
    // handle exception
}


broadFileSystemAccess is not needed.

· 1 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for your info. It works.

I am using the following:

     private async void ReadWords()
     {

         StorageFile storageFile = await KnownFolders.RemovableDevices.GetFileAsync(@"F:\log\My Item.txt");

         using (StreamReader sr = new StreamReader(await storageFile.OpenStreamForReadAsync()))
         {
             string wordsline = sr.ReadLine() ;
             word0 = wordsline.Split("#")[0]
              
         }

     }
0 Votes 0 · ·
ansalc-1556 avatar image
0 Votes"
ansalc-1556 answered ·

No luck.

In File Type Associations I added .txt as File type and used the name "text".
I have a Packaging project, so, I did it, in case, in both the main project (the only one I have) and the packaging project.

My manifests are:

In the Packaging Project:

<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="inputInjectionBrokered" />
<rescap:Capability Name="broadFileSystemAccess" />
<rescap:Capability Name="runFullTrust" />
<uap:Capability Name="removableStorage"/>
</Capabilities>

In the project:

<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="broadFileSystemAccess" />
<rescap:Capability Name="inputInjectionBrokered" />
<uap:Capability Name="removableStorage"/>
</Capabilities>

The relevant code in the main project is:

private async void Page_Loaded(object sender, RoutedEventArgs e)
{
StorageFolder externalDevices = KnownFolders.RemovableDevices;

         StorageFile storageFile = await externalDevices.GetFileAsync(@"F:\test.txt");

         string storageFileName;

         storageFileName = storageFile.Name;

       



         if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
         {
             await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
         }

         Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
            
         DispatcherTimerSetup();

         Uri url = new Uri("http://xyz");
         WebView1.Navigate(url);
     }

F:\test.txt is a text file that I have saved with Notepad using UTF-8 encoding and contains only the text: "item1&item2&item3"

The code compiles and runs fine, but when I try to evaluate storageFileName I get
storageFileName error CS0103: The name 'storageFileName' does not exist in the current context

· 5 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

If I place the file in the desktop, I get


{"Value does not fall within the expected range."}


0 Votes 0 · ·

When you call the GetFileAsync() method, you just need to pass the file name in it instead of the full path. If you pass the file name, will the same issue occur? In addition, Can you please provide a simple sample about accessing file from SD Card and desktop that can be reproduced for us to test?

0 Votes 0 · ·

If I pass the file name without the pass (GetFileAsync("test.txt"), I get the error:

  •   $exception    {"Value does not fall within the expected range."}    System.ArgumentException
    

What do you mean by providing a simple sample?



0 Votes 0 · ·
Show more comments

When you say "when I try to evaluate storageFileName I get storageFileName error CS0103: The name 'storageFileName' " looks like you are debugging code.

At which line of your method Page_Loaded as posted above is the break point?

If you run the code and method externalDevices.GetFileAsync(@"F:\test.txt"); returns null then you should have a PossibleNullReferenceException at line 5.

If you see instead "error CS0103: The name 'storageFileName' does not exist in the current context" it seems to me that there is something incorrect in your debugging steps.

By the way.. why you wrote this as an answer?

0 Votes 0 · ·
ansalc-1556 avatar image
0 Votes"
ansalc-1556 answered ·

I do try to use Reply mostly. But, like in this reply, the 1000 character limit makes it impossible.

I am beginning to think that my solution is corrupted. (Is that common?)

I've tried the code below on a brand new test solution and it works fine. I just needed, as you say, to do the file type association and give Removable storage access in the manifest (by ticking the box, no need to edit the xaml).

In my other solution, I have also created a new button and tested the same code but still got the same errror.

I have recreated a brand new solution like the original one and it still shows the same error if I place the storage code below in the MainPage Loaded event

However, it works fine in this new solution if I place the storage code below in a button click event.

Is there a problem in placing the code in the MainPage Loaded event?

Many thanks.



     private async void Button_Click(object sender, RoutedEventArgs e)
     {
         StorageFolder externalDevices = KnownFolders.RemovableDevices;

         StorageFile storageFile = await externalDevices.GetFileAsync(@"F:\log\My Item.txt");
            

         using (StreamReader sr = new StreamReader(await storageFile.OpenStreamForReadAsync()))
         {

             string text;

             text = sr.ReadLine()


         }
· Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.