Creation of a File - c#

I have created simple UWP application, where I simply want to store serialized data to a file, which can be accessed later (when user reopens the application after a while).
The place, where I want to store the file is the current installed location and my serialization code looks like following:
private void SerializeData()
{
XmlSerializer ser = new XmlSerializer(typeof(ObservableCollection<MyTask>));
Windows.Storage.StorageFolder installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
using (var writer = new StreamWriter(File.Open(Path.Combine(installedLocation.Path,sFileName), FileMode.OpenOrCreate)))
{
try
{
ser.Serialize(writer, sData);
}
catch (Exception ex) { }
}
}
This is MyTask model:
public class MyTask:ViewModelBase
{
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
OnPropertyChanged("Name");
}
}
}
The error that I've been getting is UnauthorizedAccessException. I remember that when I was creating my regular Windows 7 apps under WPF, I had no problem with permission. This is my first UWP app, and therefore I might have forgotten to do something with permissions.
The questions is - is it possible to store simple file in installed directory, or do I need to store all my data files under some Shared location?

Package.InstalledLocation is a place where your app is installed and it's read-only - so you cannot write files there. Use ApplicationData.LocalFolder instead - this is the folder where your app should store local data. For more info how to store (and where), please take a look at MSDN.

Apps can access certain file system locations by default. Apps can also access additional locations through the file picker, or by declaring capabilities.
The locations that all apps can access
When you create a new app, you can access the following file system locations by default:
Application install directory. The folder where your app is installed on the user’s system.
There are two primary ways to access files and folders in your app’s install directory:
You can retrieve a StorageFolder that represents your app's install directory, like this:
Windows.Storage.StorageFolder installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
You can retrieve a file directly from your app's install directory by using an app URI, like this:
using Windows.Storage;
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync("ms-appx:///file.txt");
The app's install directory is a read-only location. You can’t gain access to the install directory through the file picker.
Application data locations. The folders where your app can store data. These folders (local, roaming and temporary) are created when your app is installed.
There are two primary ways to access files and folders from your app’s data locations:
Use ApplicationData properties to retrieve an app data folder.
For example, you can use ApplicationData.LocalFolder to retrieve a StorageFolder that represents your app's local folder like this:
using Windows.Storage;
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
you can retrieve a file directly from your app's local folder by using an app URI, like this:
using Windows.Storage;
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync("ms-appdata:///local/file.txt");
User’s Downloads folder:
using Windows.Storage;
StorageFile newFile = await DownloadsFolder.CreateFileAsync("file.txt");
and much much more ... for further reference goto dev.windows.com and you will get a ton of resources.

Related

Create file during mstest - System.UnauthorizedAccessException

I have a UWP C# app, with a unit testing project. In these unit test, I want to be able to write to a text file in order to make something like snapshots in Jest.
Directory.GetCurrentDirectory() returns C:\path\to\project\bin\x64\Debug\AppX, so I made a folder in the project directory and am navigating to it, then attempting to create a file there.
[TestMethod]
public void Test()
{
var folder = Path.Combine(Directory.GetCurrentDirectory(), "../../../../Snapshots");
string data = "example data";
string filename = Path.Combine(folder, "Test.snap");
File.WriteAllText(filename, json);
}
However, this test produces a System.UnauthorizedAccessException. I went into the folder in windows and gave Everyone read/write permissions, but that didn't make any difference.
I don't want to have to run Visual Studio as an administrator. Is this possible?
I use Path.GetTempPath() to create temporary directories and files in unit tests that require physical disk access. The unit tests can run from an unknown context/location, so I found using the temp directory as a guaranteed way to create disposable files.
[TestMethod]
public void Test()
{
var folder = Path.Combine(Path.GetTempPath(), "Snapshots");
string data = "example data";
string filename = Path.Combine(folder, "Test.snap");
File.WriteAllText(filename, json);
}
Please have a look at Rob's blog here:
https://blogs.msdn.microsoft.com/wsdevsol/2012/12/04/skip-the-path-stick-to-the-storagefile/
Here is the answer from Rob:
Windows Store apps run sandboxed and have very limited access to the
file system. For the most part, they can directly access only their
install folder and their application data folder. They do not have
permission to access the file system elsewhere (see File access and
permissions for more details).
Access to other locations is available only through a broker process.
This broker process runs with the user’s full privileges, and it can
use these privileges on the app’s behalf for locations the app has
requested via capabilities, locations requested by the user via file
pickers, etc. The StorageItem encapsulates this brokerage procedure so
the app doesn’t need to deal with it directly."
In a UWP app we do not recommend path anymore. There are permission problems so broker is required when access some paths. I'm not familar with Unit Test. But if you are still using UWP function you should consider using StorageFile related API instead.
How about checking if you gave permissions to the right folder?
var folder = Path.Combine(Directory.GetCurrentDirectory(), "../../../../Snapshots");
string data = "example data";
// this variable will contain the actual folder; add a watch
// or bookmark it to check it
var actualPath = Path.GetFullPath(folder);
string filename = Path.Combine(folder, "Test.snap");
File.WriteAllText(filename, data);
Just in case, add the line below too (before File.WriteAllText); perhaps your file already exists as, I don't know, read-only:
File.SetAttributes(filename, FileAttributes.Temporary);

PCLStorage FileSystem is only available in Android, not iOS

I'm writing a cross platform application in xamarin, for Android and iOS, and I need to save some text files to local storage. I'm using PCLstorage, but whenever I mouse over any PCLStorage code, it says "MyApplication.Android: available, MyApplication.iOS not available". How can I use PCLStorage to store files on both platforms? Or is there another way I can do this? Here's an example of some of my code:
public async Task CreateRealFileAsync(string filename, string filebody)
{
// get hold of the file system
IFolder rootFolder = FileSystem.Current.LocalStorage;
// create a folder, if one does not exist already
IFolder folder = await rootFolder.CreateFolderAsync("DadAppFiles", CreationCollisionOption.OpenIfExists);
// create a file, overwriting any existing file
IFile file = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
// populate the file with some text
await file.WriteAllTextAsync(filebody);
}

Is it possible to save a file to an exact, specific location? (Windows 8.1 Universal App C#)

What I need to do:
Save an image file to an exact, specific location when the app is run (Let's say "Z:\test\photo.jpeg").
Additional wanted functionality:
1) Overwrite the file ''Z:\test\photo.jpeg' if it already exists.
2) Skip the write, if the folder 'Z:\test\' doesn't exist.
What I've already tried:
using Windows.Media.Capture.UI;
using Windows.Storage;
CameraCaptureUI camera = new CameraCaptureUI();
StorageFile photo = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo != null)
{
var targetFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("photo.jpeg", CreationCollisionOption.ReplaceExisting);
if (targetFile != null)
{
await targetFile.DeleteAsync();
await photo.MoveAndReplaceAsync(targetFile);
}
}
Question:
Is there a way to get the variable 'targetFile' to point to a particular location, eg. "Z:\test\photo.jpeg"?
I don't want to use local app data folder, pictures folder, or anything like that. It needs to be this particular location.
Univeral Apps are sandboxed and can only access their on storage folders.
You can grant access to other files using FileOpenPicker or FolderPicker, but you won't have control about what file the user picks for you to write into.
This means you have to make your user pick that exact file for you to store at, otherwise your app can't access that location.
Here's an overview on accessible file locations for UWP apps on MSDN.

Path.GetTempPath() not available in Windows Store Apps

I am trying to get the temp directory by using:
string tempFolder = System.IO.Path.GetTempPath();
However that method does not exist. I can see all the other methods in intelliSense though.
Why is that method not available. Is there another way to get the temp folder location in a Windows Store app?
Create the temporary file in your ApplicatonData storage. You will have to generate your own filename with a guid or timestamp.
Windows.Storage.StorageFolder temporaryFolder = ApplicationData.Current.TemporaryFolder;
StorageFile sampleFile = await temporaryFolder.CreateFileAsync("dataFile.txt", CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(sampleFile, formatter.Format(DateTime.Now));
A Windows Store App is sandboxed, so you are expected to read and write to folders inside your sandboxed application folder. You won't be able to write to the traditional temp folder C:\Windows\TEMP, as you probably want, and yeah you are out of luck. There are a few other locations outside of your application folder that you have access to, but in most cases your access is limited.
The KnownFolders class is how you access the following locations.
CameraRoll
DocumentsLibrary
HomeGroup
MediaServerDevices
MusicLibrary
PicturesLibrary
Playlists
RemovableDevices
SavedPictures
VideosLibrary
KnownFolders class on MSDN

Read text files with windows store apps

I am working with Visual Studio ultimate 2013 and using windows store apps.
My visual studio project folder "History"(name of the current project) is located in D:Academic folder.
I have created text file in the History project folder.
And I want to print the details in text file to a text block.
This code works.
According to this, the location of the text file is created in Local Folder.
public History()
{
this.InitializeComponent();
StorageFolder = ApplicationData.Current.LocalFolder;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
ReadText();
}
async void ReadText()
{
StorageFile file = await StorageFolder.GetFileAsync(filename);
ghij.Text = await FileIO.ReadTextAsync(file)
}
private void Write_click(object sender, RoutedEventArgs e)
{
WriteText();
cdef.Text = "";
}
async void WriteText()
{
StorageFile file = await StorageFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(file, cdef.Text);
}
In my case I don't want to create and write a file,but to READ an already created file which is located in D:\Academic:\History folder.
So how can I change the path to access the text file.
Please help.
Windows store apps don't have full access to the file system. You can give them access however to specific places like the Documents through the so called capabilities. You can also save and restore content from local storage.
You don't have direct access in Windows Store Apps. FilePicker class would serve you most of the time to open a file but if you want a programmatic access to a file then you need to declare appropriate capabilities in your package manifest.
And yes you want to access documents library, in that case you have to declare documents library capability in your package manifest.
From MSDN :
The file picker provides a robust UI mechanism that enables users to open files for use with an app. Declare the documentsLibrary capability only when you cannot use the file picker.
NOTE : Documents library only gives access to file formats filtered by the types declared in the manifest.
For eg. For example, if a DOC reader app declared a .doc file type association, it can open .doc files in Documents, but not other types of files.
You can't use the Documents library in a Windows Phone Store app.
You can't publish a Windows Phone Store app that specifies the documentsLibrary capability to the Windows Phone Store. The Store blocks the publishing of the app.
You can refer MSDN Arcticle on Manifest capabilties.

Categories