I have a Silverlight web application(4.0) with a select file open dialog, however I get this error when the user selects a file : "File operation not permitted Access to path '' is denied"
When I try to debug it then I get this security exception "Dialogs must be user-initiated."
Is there a way around this? Has anyone has tried doing this in Silverlight?
Here is my code so far which hasn't worked:
OpenFileDialog dlg = new OpenFileDialog
{
Multiselect = false,
Filter = "All files|*.*"
};
bool? userClickedOK = dlg.ShowDialog();
if (userClickedOK == true)
{
textBox1.Text = dlg.File.FullName;
}
Because of security related restrictions you cannot open file dialogs in Silverlight directly. You can only open dialogs from inside an event handler like mouse click.
In silverlight 4, you cannot acces the FullName property, this is the cause of exception: "File operation not permitted Access to path is denied"
I trien utmost but cannot find a way to get full file path of selected file without making your application OOB.
While debugging a silverlight project, if you place a break point anywhere before the dlg.ShowDialog(), in case of your code this will raise the exception: "Dialogs must be user-initiated"
Simple way to avoid this exception is to place your break point after ShowDialog() line.
As far as I know you are not allowed to access user files if you don't have elevated permissions.
You can't get the full name of a file. And in all cases, why would you need it? There is no reason to know where the user stores her files.
If you want to read a file, use Stream property of the uploaded file instead.
I was having the same issue, after reading a lot about this problem that you cannot access dlg.File.FullName
Instead you can use this
dlg.File.Name
by doing this your exception will be removed
The error also occurs if you try to access CreationTime from a FileInfo.
Related
I have a problem where if you set the filename in the dialog box to a sub directory within the initial directory you set it to and then clicking 'Save', the dialog window doesn't actually save the file but opens the sub directory which I could still interact with.
For example If I set the initial directory for the dialog to 'C:\MainDir' and that directory consists of SubDir1, SubDir2, then in the save file dialog I could see that I am in the initial directory with two sub directories. If I set the filename to SubDir1 (no extension) in the dialog, and then I hit 'Save', what happens is instead of saving the file as 'filename.extension' the dialog opens the directory specified by the file name.
Here's what I currently have:
SaveFileDialog dlg = new SaveFileDialog();
dlg.DefaultExt = ext;
dlg.AddExtension = true;
dlg.FileName = filename;
dlg.Filter = filter;
dlg.FileOk += OnFileDialogOk;
dlg.InitialDirectory = dir;
bool? dlgRes = dlg.ShowDialog();
Is this something that can be easily fixed?
Quick Answer: No.
You cannot override the default save method of Windows OS.
What you can do is perhaps to verify whether the filename you wanted to use (in this instance, SubDir) exists already as a directory. If it does, then you would need to change that name, as that will only manifest the behavior you've already seen.
Side Note: Just imagine you have a very important folder which contains critical files, and Windows would let you save a file that is named with that directory. That is a disaster waiting to happen.
The only ways I can think of doing this are a bit extreme:
You could roll your own dialog
You could modify the functionality of the standard dialog
The answers found here: Customizing OpenFileDialog could help with that.
I guess I should also note that while it may seem helpful to accommodate this kind of input and automatically append the extension, it'll be counter-intuitive to many users who will expect the default behaviour.
In short, I'd probably think twice about this.
I'm using OpenFileDialog (.Net Framework 4, Windows 10) and I've noticed that it will allow the user to specify a URL as the file name (e.g., http://somewebsite/picture.jpg). This is very useful for my application, so I don't intend to disable it. The way it works is downloading the file into the user's temp directory and returning the temporary file name in the dialog's Filename property. This is nice, except for the fact that the user starts to build up garbage in his/her temp directory.
I would like to tell when a file was downloaded by the OpenFileDialog class (as opposed to a previously existing file), so I can clean up by deleting the file after use. I could check if the file's directory is the temp directory, but that's not very good since the user might have downloaded the file him/herself.
I've tried intercepting the FileOK event and inspect the Filename property to see if it is an HTTP/FTP URI, but despite what the documentation says ("Occurs when the user selects a file name by either clicking the Open button of the OpenFileDialog") it is fired after the file is downloaded, so I don't get access to the URL: the Filename property already has the temporary file name.
EDIT: This is an example of what I'like to do:
Dim dlgOpenFile As New System.Windows.Forms.OpenFileDialog
If dlgOpenFile.ShowDialog(Me) <> Windows.Forms.DialogResult.OK Then Return
''//do some stuff with dlgOpenFile.Filename
If dlgOpenFile.WasAWebResource Then
Dim finfo = New IO.FileInfo(dlgOpenFile.Filename)
finfo.Delete()
End If
In this example, I've imagined a property to dlgOpenFile "WasAWebResource" that would tell me if the file was downloaded or originally local. If it's the first case, I'll delete it.
There's no obvious way to do this, but as a workaround, how about checking where the file lives? It looks like by default this dialog downloads files to the users Temporary Internet Files directory, so you could introduce some code that looks something like this:
FileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
string temporaryInternetFilesDir = Environment.GetFolderPath(System.Environment.SpecialFolder.InternetCache);
if (!string.IsNullOrEmpty(temporaryInternetFilesDir) &&
dialog.FileName.StartsWith(temporaryInternetFilesDir, StringComparison.InvariantCultureIgnoreCase))
{
// the file is in the Temporary Internet Files directory, very good chance it has been downloaded...
}
}
According to this msdn article one of the sources for InitialDirectory property used in FileDialog is:
A path that was previously used in the program, perhaps retained from the last directory or file operation.
...
So if you selected your first file from folder x, the next time you try to select a file it will open up the FileDialog with with folder x selected (saving you having to navigate there).
Playing around with notepad this seems to carry across opening a file, saving a file, opening a file and even when printing with "Microsoft XPS Document Writer" which brings up it's own dialog.
So my question is where is this value stored between dialogs? I would like to be able to see what it is and potentially change it? The specific area i would like to change it is in the "Microsoft XPS Document Writer" printer which brings up it's own dialog. So it's not as simple as just setting the initalDirectory Value.
It's stored in the registry, somewhere in HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\ (LastVisitedPidlMRU).
You should take a look at this link:
MRU locations are what you are looking at!
Here's a way for accessing it:
var openFileDialog1 = new OpenFileDialog();
string path = openFileDialog1.InitialDirectory;
// you can change path if you want
openFileDialog1.InitialDirectory = path;
// after you are donw you can display you dialog
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
// do something
}
Another way is to use Directory.SetCurrentDirectory method which sets the application's current working directory
And from Microsoft website, it is stored at this location in the registry:
//The MRU lists for Windows Explorer-style dialog boxes are stored by file type for each user in the following registry key:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSaveMRU
hope this helps
Description:
The code below is the simplest code I could write which causes the failure. I've also tried: putting the CreateFile and MoveFile in different using statements, putting them in different xaml pages, moving the file into a subdirectory with a new filename, moving it into a subdirectory with the same filename. They all throw the same exception. CopyFile throws the same exception in all circumstances.
Question is--what incredibly simple thing am I not accounting for?
Open a new Silverlight for Windows Phone 7 project targeting Windows Phone 7.1.
Open App.xaml.cs.
Paste the following lines of code into Application_Launching:
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
isf.CreateFile("hello.txt");
isf.MoveFile("hello.txt", "hi.txt");
}
Click start debugging, targeting emulator or device.
Expected: creates a file named "hello.txt", then (effectively) renames "hello.txt" to "hi.txt".
Actual: throws exception below.
System.IO.IsolatedStorage.IsolatedStorageException was unhandled
Message=An error occurred while accessing IsolatedStorage.
StackTrace:
at System.IO.IsolatedStorage.IsolatedStorageFile.MoveFile(String sourceFileName, String destinationFileName)
at PhoneApp4.App.Application_Launching(Object sender, LaunchingEventArgs e)
at Microsoft.Phone.Shell.PhoneApplicationService.FireLaunching()
at Microsoft.Phone.Execution.NativeEmInterop.FireOnLaunching()
You should call Close after you create the file.
IsolatedStorageFileStream helloFile = store.CreateFile("hello.txt");
helloFile.Close();
isf.MoveFile("hello.txt", "hi.txt");
I was just having the same issue, but the solution is simple:
The target file must not exists, delete it before the moving. Make sure the target file is not open anywhere before deleting.
The source file must not be open anywhere.
if (_isolatedStorage.FileExists(targetPath))
{
_isolatedStorage.DeleteFile(targetPath);
}
_isolatedStorage.MoveFile(sourcePath, targetPath);
Perfectly execute this piece of code
var file = await ApplicationData.Current.LocalFolder.GetFileAsync(oldName);
await file.RenameAsync(newName);
MBen, your answer is not correct. Calling Close on the file does not fix this error. I am seeing the exact same error as well even though I call "Close" before MoveFile.
edit Ok just figured out the problem I was having - if you try to call MoveFile when the destinationFile already exists, it throws an Exception. You have to delete the destinationFile first before moving your sourceFile to it.
I have a FileUpload control (FileUpload1) on my web form, as well as a "Sumbit" button, a label, and a hidden field that contains a UserID. I have the following code in the button's click event:
string path = Server.MapPath("~/userfiles/");
if (FileUpload.HasFile)
{
try
{
FileUpload1.SaveAs(path + UserID.Value + "/image.jpg");
}
catch
{
Label1.Text = "* unable to upload file";
Label1.Visible = true;
}
}
It works great if I upload an actual file. However, if I type a non-existent filename (for example, "c:\a.jpg", which does not exist on my computer) into the FileUpload's textbox, and click the Sumbit button, HasFile still returns true. Furthermore, SaveAs() does not throw any exceptions, and it is a void function that returns no value indicating success or failure. How do I tell whether a file was actually uploaded?
Just check to see if it exists.
if(File.Exists(myFile)){
//it was uploaded.
}
You could check FileUpload.PostedFile.ContentLength property
You could check if the file exists using File.Exists before calling SaveAs.
Hmmm....
Not sure I understand. First, in your code, FileUpload.HasFile won't compile. If should be FileUpload1.HasFile.
When I correct this, and run your code, this line returns false if the file does not exist...
You can check if file exists after uploading using File.Exists(path); The file object is part of System.IO.
This is not about your actual question, but you should validate any user input, especially if you want users to upload files to a virtual folder on your webserver. You should at least check whether the content type of the file is the one you expect, or - even better, filter (resize) the image using the classes available in the .NET framework.
If you don't do so users may share arbitrary content via your site or place malicious files (e.g. images containing script which might get executed by certain web browsers) on your server.
With additional validation you will also be able to validate if there has actually been content sent.
AND: A really severe vulnerability opens up when you build the save path by concatenating input from a form field (I assume UserID.Value is the POST parameter you mention?). This allows users to decide where to store the content on your server, and, even worse, be able to overwrite existing files!!!