I am currently working on a project using the Windows Runtime and I have run into a roadblock, this was something that was always very easy to do and I feel very frustrated for not getting this right.
I have been sitting for hours and I just cannot seem to get it right. I get the "Access is denied error", also in some variations of my code when I did click on the button, nothing happened. I feel like the answer is staring me right in the face. Here is the code:
private async void btnDtlsSaveChanges(object sender, TappedRoutedEventArgs e)
{
StorageFile del = await Package.Current.InstalledLocation
.GetFileAsync("UserDetails.txt");
await del.DeleteAsync();
StorageFile file = await Package.Current.InstalledLocation.CreateFileAsync
("UserDetails.txt", CreationCollisionOption.OpenIfExists);
using (StreamWriter writer =
new StreamWriter(await file.OpenStreamForWriteAsync()))
{
await writer.WriteLineAsync("Hello World");
}
}
I also tried using ReplaceExisting instead of OpenIfExists:
StorageFile file = await Package.Current.InstalledLocation.CreateFileAsync
("UserDetails.txt", CreationCollisionOption.ReplaceExisting);
using (StreamWriter writer = new StreamWriter(await file.OpenStreamForWriteAsync()))
{
await writer.WriteLineAsync("Hello World");
}
I have tried in several ways, all leading down the same track, and I have looked at every related question on stack overflow, nothing is getting me there.
Any help would be greatly appreciated, thanks in advance.
EDIT: (Solved) Me in my stupidity and the learning of a new technology did not actually realise that there is a difference between the LocalStorage and the actual installed location, thanks to Rob Caplan for guiding me in the right direction.
You get access denied because apps don't have write access to Package.Current.InstalledLocation.
For write access you need to use your application data folders such as Windows.Storage.ApplicationData.Current.LocalFolder
If you want to ship your app with an initial data file and then update the app with user data at runtime you can copy it from InstalledLocation to LocalFolder on first run.
See App data (Windows Runtime apps) and Accessing app data with the Windows Runtime (Windows Runtime apps)
I don't know why you are using await, but the following code should be able to clear the file content for you
using (StreamWriter sw = new StreamWriter("UserDetails.txt", false))
{
sw.WriteLine("Hello world");
}
I used a button for it to test
After Clicking the button the file will be empty.
You need to use using FileMode.Create, It will create a new file or overwrite it.
private void button1_Click(object sender, EventArgs e)
{
using (FileStream NewFileStream = new FileStream(#"C:\Users\Crea\Documents\TCP.txt", FileMode.Create))
{ }
//using (StreamWriter sw = new StreamWriter(#"C:\Users\Crea\Documents\TCP.txt", true))
// {
// sw.WriteLine("Hello");
// }
}
Related
My WPF app crashes whenever I try to click on the write button of my app. The write button is supposed to write a string into a text file and read the string back. I have the string appear on the content section of the write button.
Here is where I think the problem lies.
private void Write_Click(object sender, RoutedEventArgs e)
{
TextWriter writer = new StreamWriter(filelocation);
writer.WriteLine("Welcome to my universe");
TextReader reader = new StreamReader(filelocation);
Write.Content= reader.ReadToEnd();
}
The WPF app crashes with no warnings when I try to build and test it. I have tried removing the other sections of the code, and I have determined that the other parts work fine. How do I stop the WPF app from crashing?
The problem is that you are using the build of the app instead of the debugger to test your code. If you run your code as it is now, you will get an error saying the file you are tying to access is already being used by another process. To fix this you must close the writer before you start the reader with writer.Close();This should fix the issue:
private void Write_Click(object sender, RoutedEventArgs e)
{
TextWriter writer = new StreamWriter(filelocation);
writer.WriteLine("Welcome to my universe");
writer.Close();
TextReader reader = new StreamReader(filelocation);
Write.Content= reader.ReadToEnd();
}
I'm trying to build a small program to monitor my pfirewall.log, but I can't seem to open it.
I found quite many (simple) answers, that all kinda say
// use FilesystemWatcher
// open FileStream
// read from last position to end
// output new lines
The problem here is: The file seems to always be opened by another process already. I guess that's the windows process writing to the file, since it's getting written to all the time, as Notepad++ shows me.
Which means, Notepad++ can for some reason do what I can not: Read the file despite it being opened already.
I initialize my monitor in the constructor:
public FirewallLogMonitor(string path)
{
if (!File.Exists(path))
throw new FileNotFoundException("Logfile not found");
this.file = path;
this.lastPosition = 0;
this.monitor = new FileSystemWatcher(Path.GetDirectoryName(path), Path.GetFileName(path));
this.monitor.NotifyFilter = NotifyFilters.Size;
}
And try to read the file on monitor.Changed event:
private void LogFileChanged(object sender, FileSystemEventArgs e)
{
using (FileStream stream = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (StreamReader reader = new StreamReader(stream))
{
stream.Seek(this.lastPosition, SeekOrigin.Begin);
var newLines = reader.ReadToEnd();
this.lastPosition = stream.Length;
var filteredLines = filterLines(newLines);
if (filteredLines.Count > 0)
NewLinesAvailable(this, filteredLines);
}
}
It always throws the IOException on new FileStream(...) to tell me the file is already in use.
Since Notepad++ does it, there has to be a way I can do it too, right?
**Edit: ** A button does this:
public void StartLogging()
{
this.IsRunning = true;
this.monitor.Changed += LogFileChanged;
this.monitor.EnableRaisingEvents = true;
}
**Edit2: ** This is not a duplicate of FileMode and FileAccess and IOException: The process cannot access the file 'filename' because it is being used by another process, since that one assumes I have control over the writing process. Will try the other suggestions, and report back with results.
If i understand your question you can use the notepad++ itself with a plugin to monitor you need to go to:
plugins -> Document Moniter -> Start to monitor
if you dont have this plugin you can download it here:
http://sourceforge.net/projects/npp-plugins/files/DocMonitor/
When I press a button, I want it to overwrite a file to a specific folder.
I use this code:
private void btnArial_Click(object sender, RoutedEventArgs e)
{
string cssDocument = "body{font-family:\"Arial\";}";
//I want to write file style.css to folder css inside html
string path = Package.Current.InstalledLocation.Path + "\\Html\\css\\style.css";
if (File.Exists(path))
{
StreamWriter writer = new StreamWriter(path);
writer.Write(cssDocument);
writer.Close();
}
changeStyle(new FontFamily("Arial"));
}
When I tested on emulator and actual devide, it worked properly.
But when I submit app to store, it got error - the app exits when I press that button.
The install directory (Package.Current.InstalledLocation) is a read-only location. Unfortunately, due to the way that Visual Studio optimizes development-time deployment, it is set to read-write when the app is deployed from VS. That's why you see a difference in behavior after you submit the app to the store.
If you need to modify a file in your install directory, you must first copy it over to a writeable location - eg. your Local folder.
I prefer using Isolated storage in WP8 to write files and it never fails. Also you can use Windows.Storage apis.
private async void MyButton_Click(object sender, RoutedEventArgs e)
{
string cssDocument = "body{font-family:\"Arial\";}";
// using Windows.Storage
StorageFolder folder = ApplicationData.Current.LocalFolder;
folder = await folder.CreateFolderAsync("HTML", CreationCollisionOption.OpenIfExists);
folder = await folder.CreateFolderAsync("CSS", CreationCollisionOption.OpenIfExists);
StorageFile file = await folder.CreateFileAsync("style.css", CreationCollisionOption.ReplaceExisting);
using (var writer = new StreamWriter(await file.OpenStreamForWriteAsync()))
{
writer.Write(cssDocument);
}
// using using System.IO.IsolatedStorage;
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.DirectoryExists("HTML/CSS"))
store.CreateDirectory("HTML/CSS");
using (var writer = new StreamWriter(store.OpenFile("HTML/CSS/style.css", FileMode.Create)))
{
writer.Write(cssDocument);
}
}
changeStyle(new FontFamily("Arial"));
}
Exactly..
Write the file in Isolated storage. Its easier and pretty straight forward. The files here can be accessed, viewed, modified, removed, replaced in a very clear way. I personally prefer the Isolated Storage.
I am using following code to create a file in isolated storage
mystorage = IsolatedStorageFile.GetUserStoreForApplication();
if (mystorage.FileExists(scanName))
{
mystorage.DeleteFile(scanName);
}
WriteableBitmap wb = new WriteableBitmap(canImage, null);
using (MemoryStream stream = new MemoryStream())
{
wb.SaveJpeg(stream, (int)canImage.Width, (int)canImage.Height, 0, 100);
using (IsolatedStorageFileStream local = new IsolatedStorageFileStream(scanName, FileMode.Create, mystorage))
{
local.Write(stream.GetBuffer(), 0, stream.GetBuffer().Length);
}
}
if (MessageBox.Show("Scan updated successfully") == MessageBoxResult.OK)
{
App.isTransformRequest = false;
NavigationService.Navigate(new Uri("/View/EditDocument.xaml?paramList=" + App.currentName, UriKind.RelativeOrAbsolute));
}
this code works fine. But I want to detect weather the file is completely created or not, and after that only I want to display the success message. The way I am currently working somtimes displays the success message before the complete creation of the file, I want the message to be displayed only after the file is created completely, ie the stream is written completely.
Using the BeginWrite Method of the IsolatedStorageFileStream (msdn) you can regsiter a ActionCallback to continue with the redirection options in your UI.
Please note, if your callback shows a MessageBox in the UI-Thread, you have to sync the ThreadContext using the Dispatcher (msdn)
I've read about a thousand similar posts, and have followed the general advice but am still running into the issue. Here's my scenario:
I'm working on a Windows Phone 8 app that, when the user saves, serializes all of their data into XML then uses CreateFile to store it. The problem that I'm facing is that if a user hits save several times consecutively, IsolatedStorageException:Operation Not Permitted is thrown (I'm guessing that the serialization takes long enough that the file is still being used when I attempt to access it a second time). When save is tapped the second time, is there a way for me to abort the previous action, free up the isolated storage file, and initiate the new save? Or is there a better solution?
Here's the code for my Save method (the exception occurs on the isoStore.CreateFile(filename) line):
using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = isoStore.CreateFile(filename))
{
XmlSerializer xml = new XmlSerializer(GetType());
xml.Serialize(stream, this);
}
}
Any help would be amazing, as I've been stuck here for weeks.
Thanks,
Ben:
You could go with something like this.
private async Task Save(string fileName)
{
Button.IsEnabled = false;
await Task.Run(() =>
{
using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = isoStore.CreateFile(filename))
{
XmlSerializer xml = new XmlSerializer(GetType());
xml.Serialize(stream, this);
}
}
});
Button.IsEnabled = true;
}
Why not disable the 'save' button when clicked then enable it again once the serialization completes?