Does File.Exists not work inside a UWP project? - c#

File.Exists(filePath); works perfectly inside a console application, but when I do the same thing inside uwp it doesn't detect a file.
I have tried to put breakpoints on various methods and stepped into anything that could give me some information about the issue, but I'm getting no information at all no matter what i try.
Code from UWP app:
string path = #"C:\Users\Name\Desktop\image.jpg";
if (File.Exists(path))
{
ProcessFile(path);
}
else if (Directory.Exists(path))
{
ProcessDirectory(path);
}
UWP:
When it hits File.Exists i get a return value of false, and yes i know for a fact the image is where it is.
Console:
When it hits File.Exists i get a return value of true, then goes onto the called method without any issues.
I'm expecting my code to find a File and pass the filePath into my method called "processFile".
Does UWP applications not have access to files outside of its LocalStorage or is it another issue that I'm not seeing?

UWP does not have direct access to files outside of the application folder and application data folder. That are the only two locations accessible via the System.IO APIs.
You can use StorageFile APIs to access more locations if you enable appropriate capabilities - like access to libraries or broadFileSystemAccess or use file/folder pickers. In particular, broadFileSystemAccess allows you to access the whole file system, but your app should have a good reason to do so (otherwise it will not pass the Microsoft Store certification process).
For more info see the Docs.

This is correct. UWP apps are sandboxed and cannot access files outside of LocalStorage in this way.
If you want to open a file on the users file system you have to use FileOpenPicker.PickSingleFileAsync or similar to prompt the user to pick a file, which you'll then be able to work with.
Further reading: Working with Files in UWP applications

Related

Is there anyway that allows me to use System.IO in a UWP application

I'm currently working on a UWP application and one of the things I need to do is write bytes to files using the System.IO class. This is because one of the libraries my application depends on uses the System.IO.File.WriteAllBytes() method.
Using the StorageFolder class isn't quite something that I'm looking to do since a couple of the projects I am making (some are not UWP, some are CLIs) depend on this library I have written and the StorageFolder is only available in UWP.
I've added broadFileSystemAccess as one of the capabilities of my UWP application. However, after reading the documentation carefully I found out that this capability only affects the StorageFolder class and not the System.IO class. In addition, I'm the only person who will be using this application, so I thought that enabling the file access rights in the System Settings (as shown in the image provided) would help. However that did not help at all
Here is the exception message that I am getting
"Access to the path 'C:\\proj\\proj_tig\\Project 112\\bin\\x64\\Debug\\AppX\\Dependencies.zip' is denied."
Is there any possible way to use the System.IO.File.WriteAllBytes() method at all in UWP?
Is there anyway that allows me to use System.IO in a UWP application
For checking the path, and it looks a apps installation folder, unfortunately, the installation folder is read-only, we can't write data into. we suggest you use app' local folder that with full permission, and you could use System.IO namespace to access. For more detail please refer this document.

How to write a list of classes to a file in UWP C#

I have attempted to use the methods on this thread by deadlydog:
How to quickly save/load class instance to file
This works in a console application for writing a list of classes to a file. However when I try migrating it to a UWP project I always get "Access to the path ..... is denied"
According to this thread: broadFileSystemAccess UWP
I am meant to add broadFileSystemAccess capabilities, which I have done.
However, it also says that I need to use StorageFile APIs, not just classic System.IO API.
I believe the current writing method I am using is utilizing the System.IO API but I do not know how to achieve the same goal using StorageFile APIs.
Could someone please point me in the correct direction?
UWP apps are only allowed to write to a small subset of folders on your machine. Using broadFileSystemAccess capability might alleviate it, but it's like using a sledgehammer when you need a screwdriver.
Your application to write data it needs to Windows.Store.ApplicationData.LocalFolder.Path. That folder is writable without any special capabilities.
You can use the System.IO API, just be sure your code doesn't try to access anything outside its StorageFolder. You can get the StorageFolder path at runtime with this code
Windows.ApplicationModel.Package.Current.InstalledLocation.Path
There is also documentation for how to handle IO in UWP here: https://learn.microsoft.com/en-us/windows/uwp/files/quickstart-reading-and-writing-files

Creating/Writing/Zip/Unzip a file in UWP

edit: About the path-problem. I will try to get there later. For now I just need help for zip a file. Could not find a way to do this yet.
Im currently going through a few basics and I don't know what I have to look for to get to where I want to be. So, what are my goals?:
I want to create a name.json file here C:\Users\Username\Desktop
Then I want to compress name.json to an zip file.
I also created another file Testfile.zip on my Desktop. I want to unzip that file.
So far I created a name.json file. But I cannot find a solution on how to create one on the desktop.
I could not find a solution on compressing name.json so far.
public MainPage()
{
this.InitializeComponent();
createJson();
UnzipFile();
}
public async void createJson()
{
string text = "This text";
string json = JsonConvert.SerializeObject(text);
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("name.json");
await FileIO.WriteTextAsync(file, json);
}
public async void UnzipFile()
{
var localFolder = ApplicationData.Current.LocalFolder;
var archive = await localFolder.GetFileAsync("Testfile.zip");
ZipFile.ExtractToDirectory(archive.Path, localFolder.Path);
}
Working with .zip files is possible using System.IO.Compression.ZipArchive and related classes. You are already using ZipFile.ExtractToDirectory which is the right approach here. However, the issue you are facing is rather related to permissions.
UWP apps are sandboxed which means they are not allowed to touch any filesystem location by default. This is to ensure better security and easier uninstallation of apps. This however means you cannot easily create a file on the user's desktop, as your app does not have access there. The only folders your app can freely access are those accessible by ApplicationData.Current and then those it declares access to in application manifest. You can also declare broad filesystem access here to get access to all locations on the PC.
To further complicate this, there are two types of I/O APIs in UWP. The modern StorageFile API which is async enabled, but tad slower, and the classic file I/O APIs in C# which includes ZipFile and ZipArchive. The main disadvantage of the classic APIs is that they always have access only to application folders and you can never access any other system paths, even if you declare broad filesystem access.
However, even without declaring broad filesystem access capability you can manually get access to the folder/file of user's choosing using FolderPicker, FileOpenPicker and FileSavePicker. Using these you can let the user choose the destination where you will save the file or open a file.
Finally - to circumvent the limitation of not being able to use the classic file I/O APIs, you can first unzip the .zip file in a temporary folder inside ApplicationData.Current.LocalFolder and then use the StorageFile.MoveAndReplaceAsync(IStorageFile) or StorageFile.MoveAsync(IStorageFolder) method to move the files to the location the user has chosen using FileSavePicker.
For further info you can check out this blog post with a tutorial on using .zip in UWP.

Access a file that was transferred from PC to Android

I want to transfer a file to an Android device using a USB cable and file explorer, and then access it in my Xamarin.Forms app.
As far as I understand there are two ways to do this (and please correct me if I'm wrong):
Since it's an image file - Just put it anywhere and let some
background task find it and add it to what seems to be a virtual
folder of Images. And then access it there.
A more general solution - browse to that specific folder.
Both solutions rely on using FileInfos etc. but unfortunately the folder structure is much different than I see using windows explorer - instead of Alarms, Android, etc. which I see on windows explorer - is see cache, config, etc. using C#, and access to some like data is not allowed (I get an exception). I also tried finding information on how I would search for all images on the device, but either it's not as simple as I thought it would be, or I'm using the wrong keywords.
The file will be put there by a user, so it cannot be added to the project's resources.
Xamarin has a nice way to navigate the files in android, using Android.OS.Environment.ExternalStorageDirectory.Pathwhich you can concatenate with your directory/filename so you can save/access data.
If you want to open the android dialog box so the user can find a file in its device, you can take a look at: https://developer.xamarin.com/recipes/android/data/files/selecting_a_gallery_image/
Remembering that you need to add the READ_EXTERNAL_STORAGE permission to your android manifest file and check runtime permissions. Runtime permissions can be easily checked with https://github.com/jamesmontemagno/PermissionsPlugin

Write to a File in Monotouch

How would I create and write to a file in a Monotouch iPhone app?
The file should persist between application launches, so I guess it has to be placed somewhere in the App bundle ( documents or resources?).
[Note: My response is pretty thorough because I don't know your level of understanding regarding app bundles or the structure of your iPhone app's sandboxed little world - apologies if I cover things you already know - I prefer to write a little too much than too little, and to add a bit of the why when discussing the how...]
You have a few options (of course). I'm assuming you're already familiar with .Net to some extent and that your question is more about how to do this the iPhone Way.
Every iPhone app (and you'll see the same thing for apps on OS X) is a "bundle" which isn't an executable in the traditional sense, but actually a folder hierarchy inside of which your app binary lives (along with resources, settings, etc.).
Because of how uber-sandboxed iPhone apps are, you don't have access to the shared folders you'd usually be able to use when doing desktop development (having, for example, a common Documents folder that lives under a user's home folder to which applications have access).
Instead, your app has its own folder hierarchy that's like its own personal set of the folders that would typically be shared across apps.
The easiest way to see what your app's folder structure looks like on the phone is to look at the folder the iPhone simulator uses for app installs, settings, blah blah blah. On my machine (I don't recall if this is configurable, but it's probably the same on your system), you can get to the folder by this path:
~/Library/Application Support/iPhone Simulator
Inside of that, there's a User/Applications folder that contains the apps you've installed to the simulator. Drill down into any one of those folders, and you can see the folder structure your app will have access to on the phone.
For storing files that you'd like persisted across app sessions, your app's Documents folder is the spot. It's not your only choice for creating files, but it's the right choice for this job. In addition to your files being properly stored, keeping them in the Documents folder will also get them backed up by iTunes when the user syncs.
With MonoTouch, you can get your app's Documents folder path with Environment.GetFolderPath(Environment.SpecialFolder.Personal);
If you'd like to test it out, this is some extremely simple code that'll write a file called "out.txt" to your app's Documents folder. This code also reads the contents of the file to show it was created - for further verification, go to the simulator's Applications folder, sort the app folders by the date they were modified, drill down into the most recently modified, and look inside its Documents folder - you'll find "out.txt" (you can't find your app's folder by name because, when your app is installed, it gets stuffed inside a folder with a name like "2B3CA854-FADB-4DDC-9732-0E61B3DD8D8C" - sorting the folders by the date they were modified will point you to the most recently modified app, which, in this case, is whatever app contains the following code):
// For this to function, don't forget "using System.IO;"
// If you're just playing around with this to see it work, place it inside
// your AppDelegate's "FinishedLaunching" method in main.cs
string path = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
string filePath = Path.Combine(path, "out.txt");
// File.WriteAllText will create a file and then write text to it. If the
// file already exists, File.WriteAllText will overwrite it.
File.WriteAllText(filePath, "Howdy, world.");
// Now we prove it worked by reading the contents of the file and then
// printing them to the console...
string text = File.ReadAllText(filePath);
Console.WriteLine(text);
So, the only thing here that's really iPhone-specific is knowing that "Environment.SpecialFolder.Personal" maps to your app's Documents folder. Beyond that, it's .Net as usual.
And, again, this was probably overkill, but I wanted to answer sufficiently thoroughly for everybody who sees it.
The following How To from the Xamarin.iOS guide site has a few pointers to where to store your files:
http://docs.xamarin.com/guides/ios/application_fundamentals/working_with_the_file_system/
You can do something like this at runtime:
using (StreamWriter writer = new StreamWriter (Path.Combine (Environment.SpecialFolders.Documents, "yourfilename.ext"))) { }
and that will create the file. To open it for reading, use the same Path.Combine() but with StreamReader.

Categories

Resources