paduan
Posts: 5
Joined: Mon Aug 24, 2015 4:15 pm

Reading from a file using c#

Wed Aug 26, 2015 11:05 am

Hi guys... I wonder if anyone can help?

I'm just getting started on playing about with programming in C# on Windows 10 Iot on the RPi 2 and I'm trying to open a simple text file and display its contents on a textbox control.

I've hit a roadblock.

I've not managed to access arbitrary files on the SD card (i.e the C drive).

This is the code I'm using...

Code: Select all

private  void button_Click(object sender, RoutedEventArgs e)
        {
            // Load the text block from file
         
            string filename = @"Assets\test.txt";

            StreamReader streamReader = new StreamReader(new FileStream(filename, FileMode.Open));
            string returnedtext = streamReader.ReadToEnd();

            textBlock.Text = returnedtext;
            
            streamReader.Dispose();
        }
It compiles ok. The problem is, I get an access denied error as soon as I try to run it - regardless of the path of the file - it's showing as Assets\test.txt in the example above, but it fails if I put in c:\test.txt as well.

What am I doing wrong? Has anyone successfully managed to open a file for reading/writing?

Thanks in advance for the help!

User avatar
jark
Posts: 17
Joined: Fri Aug 21, 2015 8:52 am
Contact: Website

Re: Reading from a file using c#

Wed Aug 26, 2015 11:15 am

Hi paduan,

In my WindowsUniversalWebserver project I manage to access files in my local namespace.

Have a look here: https://github.com/Jark/UniversalWebSer ... ler.cs#L31

So your code rewritten to use that method would be (untested):

Code: Select all

var filename = @"Assets\test.txt";
var file = await StorageFile.GetFileFromPathAsync(filename);
var inputStream = await file.OpenSequentialReadAsync();

string fileContents;
using (var streamReader = new StreamReader(inputStream.AsStreamForRead()))
{
    fileContents = await streamReader.ReadToEndAsync();    
}

textBlock.Text = fileContents;
And you also see that I'm using the stream reader in a using block, always try to use resources that are disposable, otherwise if an error occurs in between the open and dispose your resource might get locked/you might leak memory.

paduan
Posts: 5
Joined: Mon Aug 24, 2015 4:15 pm

Re: Reading from a file using c#

Wed Aug 26, 2015 11:38 am

Thanks... that fragment compiles nicely but still fails - the debug output suggests file access failure - I get the feeling the app might not be allowed to access the file system somehow.

Is there some setting I need to set somewhere that will allow the app to access files?

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Reading from a file using c#

Wed Aug 26, 2015 12:02 pm

https://channel9.msdn.com/Series/A-Deve ... dows-10/09

The options for file access in IoT Applications do not allow for general file access in the way you seem to want, only to a limited sandbox file system within it.

The way you would normally get to the wider file system is through the 'file picker' APIs but....

https://ms-iot.github.io/content/en-US/ ... leApis.htm

Windows.Storage.Pickers.FileOpenPicker
Windows.Storage.Pickers.FileSavePicker
Windows.Storage.Pickers.FolderPicker

are listed in the 'not available at this time'!
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

User avatar
jark
Posts: 17
Joined: Fri Aug 21, 2015 8:52 am
Contact: Website

Re: Reading from a file using c#

Wed Aug 26, 2015 12:08 pm

Something that would be good to try is:

Add a file into the root of your application with Build Action: Content, Copy to Output Directory: Always

Use the following to get a filepath:

Code: Select all

var path = System.IO.Path.Combine(Package.Current.InstalledLocation.Path, "<path to file>");
And see if you can load that file in and take it from there.

There might be very well be some capabilities or permissions you might need to read files in the root of the filesystem, but I have got no experience with that.

UndergroundFun
Posts: 44
Joined: Wed Jun 17, 2015 12:57 pm

Re: Reading from a file using c#

Wed Aug 26, 2015 12:56 pm

Has anyone actually seen a specific reference to what context an application runs under? I assume it's the local DefaultAccount, but that is just an assumption.

You could try assigning permissions just like you would normally since it sounds like that just doesn't have permissions to the path.

paduan
Posts: 5
Joined: Mon Aug 24, 2015 4:15 pm

Re: Reading from a file using c#

Wed Aug 26, 2015 1:02 pm

One would have thought that an app would have read permission to its own Assets folder, especially seeing as that's where the splash logos are loaded from...

If I wasn't already bald, I'd be tearing my hair out with this one!

User avatar
jark
Posts: 17
Joined: Fri Aug 21, 2015 8:52 am
Contact: Website

Re: Reading from a file using c#

Wed Aug 26, 2015 1:11 pm

@paduan have you tried using the filename with the code snippet provided? I remember having an issue with relative paths when I was testing my web server implementation on the PI.

UndergroundFun
Posts: 44
Joined: Wed Jun 17, 2015 12:57 pm

Re: Reading from a file using c#

Wed Aug 26, 2015 1:15 pm

paduan wrote:One would have thought that an app would have read permission to its own Assets folder, especially seeing as that's where the splash logos are loaded from...

If I wasn't already bald, I'd be tearing my hair out with this one!
One might think so, but mapping the drive in windows explorer, then looking at the security the default account isn't necessarily even listed. Might need to be explicitly added.

Easy enough to try setting it there as well. But of course not knowing for sure which account it's running under makes it a bit of a grope in the dark.

User avatar
jark
Posts: 17
Joined: Fri Aug 21, 2015 8:52 am
Contact: Website

Re: Reading from a file using c#

Wed Aug 26, 2015 1:33 pm

UndergroundFun wrote:
paduan wrote:One would have thought that an app would have read permission to its own Assets folder, especially seeing as that's where the splash logos are loaded from...

If I wasn't already bald, I'd be tearing my hair out with this one!
One might think so, but mapping the drive in windows explorer, then looking at the security the default account isn't necessarily even listed. Might need to be explicitly added.

Easy enough to try setting it there as well. But of course not knowing for sure which account it's running under makes it a bit of a grope in the dark.
What does it say for the user account if you check the effective permissions under Security tab->Advanced->Effective Permissions tab? Out of experience I can tell that the app definitely has got access to files in its own directory. Like I mentioned above, it's most likely a path issue, like if you use relative paths in IIS you will actually get relative paths to c:\windows\system32 instead of relative to your application.

paduan
Posts: 5
Joined: Mon Aug 24, 2015 4:15 pm

Re: Reading from a file using c#

Wed Aug 26, 2015 1:43 pm

jark wrote:@paduan have you tried using the filename with the code snippet provided? I remember having an issue with relative paths when I was testing my web server implementation on the PI.

Hurrah! It works!

I will name my first born after you! :D

paduan
Posts: 5
Joined: Mon Aug 24, 2015 4:15 pm

Re: Reading from a file using c#

Wed Aug 26, 2015 1:50 pm

In case anyone is interested, here is the entire code for this particular xaml page... Do with it as you see fit!

I had to add in the Windows.ApplicationModel namespace to make it compile, but that bit was easy!

The XAML for the page is simply a textbox, a button to load it with the text and another button to return to a previous page. I doubt anyone wants the actual XAML code for that!

Code: Select all

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Storage;
using System.Text;
using Windows.ApplicationModel;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace HelloWorld
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class ThirdPage : Page
    {
        public ThirdPage()
        {
            this.InitializeComponent();                      
        }

        private async void button_Click(object sender, RoutedEventArgs e)
        {
            // Load the text block with text from a file
            

            var filename = System.IO.Path.Combine(Package.Current.InstalledLocation.Path, "test.txt"); 
            var file = await StorageFile.GetFileFromPathAsync(filename);
            var inputStream = await file.OpenSequentialReadAsync();

 
            string fileContents;
            using (var streamReader = new StreamReader(inputStream.AsStreamForRead()))
            {
                fileContents = await streamReader.ReadToEndAsync();
            }

            textBlock.Text = fileContents;
            
        }


        private void button1_Click(object sender, RoutedEventArgs e)
        {
            // Go back to the calling page (the main page)
            this.Frame.Navigate(typeof(MainPage));

        }
    }
}

ricl
Posts: 657
Joined: Wed Aug 26, 2015 11:55 am

Re: Reading from a file using c#

Wed Aug 26, 2015 2:38 pm

With that code you should note that you only have ReadOnly file permissions on files in the the Assets folder. If you need ReadWrite permissions on a then you must be in the Local/Roaming/Temp folders.

See

https://channel9.msdn.com/Series/A-Deve ... dows-10/09
ricl : F/gamma = ma : Law ii(a) : https://climatedatablog.wordpress.com/2016/01/02/an-energy-challenge-2016/ #AnEnergyChallenge2016

UndergroundFun
Posts: 44
Joined: Wed Jun 17, 2015 12:57 pm

Re: Reading from a file using c#

Wed Aug 26, 2015 3:19 pm

jark wrote:
UndergroundFun wrote:
paduan wrote:One would have thought that an app would have read permission to its own Assets folder, especially seeing as that's where the splash logos are loaded from...

If I wasn't already bald, I'd be tearing my hair out with this one!
One might think so, but mapping the drive in windows explorer, then looking at the security the default account isn't necessarily even listed. Might need to be explicitly added.

Easy enough to try setting it there as well. But of course not knowing for sure which account it's running under makes it a bit of a grope in the dark.
What does it say for the user account if you check the effective permissions under Security tab->Advanced->Effective Permissions tab? Out of experience I can tell that the app definitely has got access to files in its own directory. Like I mentioned above, it's most likely a path issue, like if you use relative paths in IIS you will actually get relative paths to c:\windows\system32 instead of relative to your application.
I confirmed that the DefaultAccount user is a member of the local Users group, and that group has access to the application root folder. But not the parent folder.

Something certainly good to know in case you need to do something outside the application path in the file system.

User avatar
jark
Posts: 17
Joined: Fri Aug 21, 2015 8:52 am
Contact: Website

Re: Reading from a file using c#

Wed Aug 26, 2015 9:10 pm

paduan wrote:
jark wrote:@paduan have you tried using the filename with the code snippet provided? I remember having an issue with relative paths when I was testing my web server implementation on the PI.

Hurrah! It works!

I will name my first born after you! :D
Glad you got it to work :)

Return to “Windows 10 for IoT”