Reading from SD card

ansalc 436 Reputation points
2020-05-09T17:10:34.347+00:00

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://learn.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

Universal Windows Platform (UWP)
{count} votes

Accepted answer
  1. Daniele 1,996 Reputation points
    2020-05-12T12:06:15.413+00:00

    Here https://learn.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.


2 additional answers

Sort by: Most helpful
  1. ansalc 436 Reputation points
    2020-05-13T16:54:53.827+00:00

    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


  2. ansalc 436 Reputation points
    2020-05-15T14:23:15.923+00:00

    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()
    
    
            }
    
    0 comments No comments