I'm attempting to copy a file from the installed location of my Windows 8 app to it's local storage. I've been researching around and trying to do this to no avail. This is what I have come up with so far but I'm not sure where I'm going wrong.
private async void TransferToStorage()
{
try
{
// Get file from appx install folder
Windows.ApplicationModel.Package package = Windows.ApplicationModel.Package.Current;
Windows.Storage.StorageFolder installedLocation = package.InstalledLocation;
StorageFile temp1 = await installedLocation.GetFileAsync("track.xml");
// Read the file
var lines = await FileIO.ReadLinesAsync(temp1);
//Create the file in local storage
StorageFile myStorageFile = await localFolder.CreateFileAsync("track_iso.xml", CreationCollisionOption.ReplaceExisting);
// Write to it
await FileIO.WriteLinesAsync(myStorageFile, lines);
}
catch (Exception)
{
}
}
Any ideas?
Solved it myself. Here is the method for anyone else that encounters this question / problem:
private async void TransferToStorage()
{
// Has the file been copied already?
try
{
await ApplicationData.Current.LocalFolder.GetFileAsync("localfile.xml");
// No exception means it exists
return;
}
catch (System.IO.FileNotFoundException)
{
// The file obviously doesn't exist
}
// Cant await inside catch, but this works anyway
StorageFile stopfile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///installfile.xml"));
await stopfile.CopyAsync(ApplicationData.Current.LocalFolder);
}
No reason to read all the lines and write it to another file. Just use File.Copy.
Related
I have a UWP app that I am deploying as an AppPackage, and I am seeing an off error when I attempt to read/save a file in the LocalState folder. It does not happen everytime, so I am thinking the file is locked during the process at some point. The erroe is
No mapping for the Unicode character exists in the target multi-byte code page.
And the code that throws the error
private const string SETTINGS_FILENAME = "settings.json";
private static readonly StorageFolder _settingsFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
public async static Task<ConfigWrapper> LoadSettings()
{
try
{
StorageFile sf = await _settingsFolder.GetFileAsync(SETTINGS_FILENAME);
if (sf == null) return null;
string content = await FileIO.ReadTextAsync(sf, Windows.Storage.Streams.UnicodeEncoding.Utf8);
return JsonConvert.DeserializeObject<ConfigWrapper>(content);
}
catch (Exception e)
{
DiagnosticsClient.TrackException(e);
return null;
}
}
public async static Task<bool> SaveSettings(ConfigWrapper data)
{
try
{
StorageFile file = await _settingsFolder.CreateFileAsync(SETTINGS_FILENAME, CreationCollisionOption.ReplaceExisting);
string content = JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings { });
await FileIO.WriteTextAsync(file, content, Windows.Storage.Streams.UnicodeEncoding.Utf8);
return true;
}
catch (Exception e)
{
DiagnosticsClient.TrackException(e);
return false;
}
}
I am making sure to save and read the file in UTF-8, so I am not sure why there would be an encoding error. Is there something I need to do (lock the file for instance) when I save/read?
Many applications save data in a proprietary format. The gibberish you provided is probably such.
Such applications often have a way to "write" or "export" or "save as" the data. Look for such.
I a'm running an uwp app on Rasbperry Pi 3 with Windows 10 IoT OS via Visual Studio Remote Machine and Release is selected.
The problem is how to save settings I have made and use the same settings when run same UWP app later.
How is it done? I can read the settings from the text file from
Windows.ApplicationModel.Package.Current.InstalledLocation;
But of course I can't save any changes to the same text file.
Where exactly should I put the text file if I wan't to save changes to text file?
But perhaps I can use this
Windows.Storage.ApplicationData.Current.LocalSettings;
But how do I check if there is no value stored and put instead an default value?
With this I am trying to save these settings it doesn't work.
The point with this is that I can use these same settings when I run the same uwp app again.
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
localSettings.Values["setting1"] = textBlockDelayValue.Text;
localSettings.Values["setting2"] = checkShow;
Where exactly should I put the text file if I wan't to save changes to
text file?
You can put the text file in Windows.Storage.ApplicationData.Current.LocalFolder of the solution and access it with this piece of code:
Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
async void WriteFile()
{
StorageFile sampleFile = await localFolder.CreateFileAsync("test.txt",
CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(sampleFile, "111");
}
async void ReadFile()
{
try
{
StorageFile sampleFile = await localFolder.GetFileAsync("test.txt");
String content = await FileIO.ReadTextAsync(sampleFile);
}
catch (Exception)
{
// Timestamp not found
}
}
But how do I check if there is no value stored and put instead an
default value?
You can read them out like this:
var value1 = ApplicationData.Current.LocalSettings.Values["setting1"];
var value2 = ApplicationData.Current.LocalSettings.Values["setting2"];
I'm making a Windows 10 Universal App and I want the user to pick a folder to save the document files for the App. The path for this folder is saved to ApplicationData.Current.RoamingSettings.Values.
Here's the code:
On first Start:
var folderPicker = new FolderPicker { SuggestedStartLocation = PickerLocationId.ComputerFolder };
StorageFolder folder = await folderPicker.PickSingleFolderAsync();
StorageFolder homeFolder = await folder.CreateFolderAsync("App1 Data", CreationCollisionOption.OpenIfExists);
var save = ApplicationData.Current.RoamingSettings.Values;
save["HomeFolder"] = homeFolder.Path;
When HomeFolder is set:
string dir = save["HomeFolder"].ToString();
try
{
StorageFolder homeFolder = await StorageFolder.GetFolderFromPathAsync(dir);
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
The thrown Exception in the second code sample is:
System.UnauthorizedAccessException: access denied (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
So my question is, how do you use the GetFolderFromPathAsync function correctly?
I checked all strings for the paths, they are all right, even
StorageFolder.GetFolderFromPathAsync(storageFolder.Path);
doesn't work.
Do you know a solution?
Use the StorageFile directly rather than converting to a path.
To store the file returned from the file picker for later use save the StorageFile in the AccessCache classes FutureAccessList or MostRecentlyUsedList. The path doesn't include the spermissions needed to open the file. The StorageFile carries the permissions and grants access to the file.
I discussed this in more detail in my blog entry Skip the path: stick to the StorageFile
I am developing a windows application in 8.1 and I am getting a following error.
my application includes a procedure in which I will be moving a file from local storage to SD card.
My code is as follows
namespace MoveFile
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private async void btnCreateFolder_Click(object sender, RoutedEventArgs e)
{
await ReadFile();
//Error is showing here
**await WriteToFile();
}
public async Task WriteToFile()
{
// Get the text data from the textbox.
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(this.txtSafakCount.Text.ToCharArray());
//I got the error in this line.....showing interopservice exception
** StorageFolder knownFolder = await KnownFolders.RemovableDevices.CreateFolderAsync("bdfbdfb", CreationCollisionOption.ReplaceExisting);
StorageFolder sdCard = (await knownFolder.GetFoldersAsync()).FirstOrDefault();
// Create a new file named DataFile.txt.
var file = await sdCard.CreateFileAsync("kaaaaammmmfewfwmHoJa.txt", CreationCollisionOption.ReplaceExisting);
// Write the data from the textbox.
using (var s = await file.OpenStreamForWriteAsync())
{
s.Write(fileBytes, 0, fileBytes.Length);
}
}
public async Task ReadFile()
{
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
if (local != null)
{
// Get the DataFolder folder.
var dataFolder = await local.GetFolderAsync("DataFolder");
// Get the file.
await dataFolder.CreateFileAsync("DataFile.txt", CreationCollisionOption.ReplaceExisting);
var file = await dataFolder.OpenStreamForReadAsync("DataFile.txt");
// Read the data.
using (StreamReader streamReader = new StreamReader(file))
{
this.txtSafakCount.Text = streamReader.ReadToEnd();
}
}
}
}
}
I want to know why this exception occurred and how it can be resolved.
Thanks in advance.
You are doing it wrong - first you should get SD card, then create folder. As the name KnownFolders.RemovableDevices says devices (not single device) - so you get the first of them as SD card (note that Universal Apps are not only for phones). So the working code can look like this:
// first get the SD card
StorageFolder sdCard = (await KnownFolders.RemovableDevices.GetFoldersAsync()).FirstOrDefault();
// then perform some actions - create folders, files ...
StorageFolder myFolder = await sdCard.CreateFolderAsync("bdfbdfb", CreationCollisionOption.ReplaceExisting);
Note also that you also need to add Capabilities in package.appxmanifest file, and Declarations if you want to use files (File Type Associations).
You will also find more help at MSDN.
I am working on Extraction Code to Extract Zip file, Using C# in winrt.
I am getting File from Local Drive here:
StorageFile file = await KnownFolders.PicturesLibrary.GetFileAsync("dostoyevsky-poor-folk.zip");
Stream zipMemoryStream = await file.OpenStreamForReadAsync();
var folder = ApplicationData.Current.LocalFolder;
// Create zip archive to access compressed files in memory stream
using (ZipArchive zipArchive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read))
{
// For each compressed file...
foreach (ZipArchiveEntry entry in zipArchive.Entries)
{
if (entry.Name == "")
{
// Folder
await CreateRecursiveFolder(folder, entry);
}
else
{
// File
await ExtractFile(folder, entry);
}
}
}
I am Extracting For folder here:
private async Task CreateRecursiveFolder(StorageFolder folder, ZipArchiveEntry entry)
{
var steps = entry.FullName.Split('/').ToList();
steps.RemoveAt(steps.Count() - 1);
foreach (var i in steps)
{
await folder.CreateFolderAsync(i, CreationCollisionOption.OpenIfExists);
folder = await folder.GetFolderAsync(i);
}
}
I am Extracting For File Here:
private async Task ExtractFile(StorageFolder folder, ZipArchiveEntry entry)
{
var steps = entry.FullName.Split('/').ToList();
steps.RemoveAt(steps.Count() - 1);
foreach (var i in steps)
{
folder = await folder.GetFolderAsync(i);
}
using (Stream fileData = entry.Open())
{
StorageFile outputFile = await folder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting);
using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync())
{
await fileData.CopyToAsync(outputFileStream);
await outputFileStream.FlushAsync();
}
}
}
When I try to use this I get this exception: 'System.NullReferenceException' .
The Exception getting line is the Last line of await outputFileStream.FlushAsync();
Some times I am getting same exception when I try to pick file from Local Drive.
Before Getting Exception the Debugger value of await outputFileStream.FlushAsync() looking like this.
Can you Help me out for this.
Thanks
Finally, It is Worked for me. Why because I am getting Null value while extraction Because of the package where I am going to extract files.
I am sure this is the perfect solution to Extract Zip file for windows store apps using c#.
Thanks