This snippet works well if I try to write in a user directory but as soon as I try to write in Program Files, it just executes silently and the file has not been copied (no exception). If I try to copy the file in C:\ or in C:\Windows I catch an UnauthorizedAccessException.
Do you know another way to get the permissions to write in that directory or to make it work another way?
Any help greatly appreciated! Thanks
using(FileStream fs=File.Open(source, FileMode.Open)){ }
try
{
FileIOPermission fp = new FileIOPermission(FileIOPermissionAccess.Write,
AccessControlActions.Change, "C:\\Program Files\\MyPath");
fp.Demand(); //<-- no exception but file is not copied
File.Copy("C:\\Users\\teebot\\Documents\\File.xml","C:\\Program Files\\MyPath\\File.xml",true);
}
catch(SecurityExceptions)
{
throw(s);
}
catch(UnauthorizedAccessException unauthroizedException)
{
throw unauthroizedException;
}
If you are running under Vista then the system just redirects writes to the program files folder, this is done so old program that keep their configuration in the program directory will continue to work when the user is not an Admin (or UAC is enabled).
All you have to do is add a manifest to your program that specify the required access level, then the system assume your program is Vista-aware and turns off all those compatibility patches.
You can see an example of a manifest file on my blog at:
http://www.nbdtech.com/blog/archive/2008/06/16/The-Application-Manifest-Needed-for-XP-and-Vista-Style-File.aspx
(the focus of the post is on getting the right version of the common controls, but the Vista security declarations are also there)
Don't write in the Program Files folder.
That's a big no-no, and will especially cause problems when the day comes where your code runs in Vista or on a machine at a company where users only get standard security rather than admin rights. Use the Application Data folder instead.
Are you running on Vista? If so then you may be running into file system virtualization. This is a feature in 32 bit versions of Vista which allows a normal user to write to protected parts of the file system. It's a shim introduced to reduce the pain of the LUA features of Vista.
The short version is that the operating system will create a virtual file system for certain protected roots (such as program files). When a non-admin attempts to write to it, a copy will be created an editted instead of the original. When your user account attempts to look at the file it will see the edit.s Other user accounts will only see the original.
Longer Version: http://thelazyadmin.com/blogs/thelazyadmin/archive/2007/04/26/file-system-virtualization.aspx
Code access security grants or denies permissions to your code.
It can't be used to override permissions that are granted/denied to the current user.
Related
I am developing a Windows Phone 8 application but am having a lot of issues with file access permission exceptions hindering the approval of my application when ever I try accessing files in the "local" folder (this only happens after the application has been signed by the WP store, not when deployed from Visual Studio). To solve this I have moved all file operations to IsolatedStorage and this seems to have fixed the problems.
I only have one problem left though. My application needs to make use of the file extension system to open external files and this seems to involve the file first being copied to the local folder where after I can then manually copy it into IsolatedStorage. I have no problem in implementing this but it seems that a file access permission exception also occurs once the system tries to copy the external file into the local folder.
The only way I think this can be solved is if I can direct the system to directly copy into IsolatedStorage but I cannot figure how to do this or if it is even possible. It seems as if though the SharedStorageAccessManager can only copy into a StorageFolder instance but I have no idea how to create one that is directed into IsolatedStorage, any ideas?
PS. Do you think that the Microsoft system might be signing my application with some incompetent certificate or something because there is not a hint of trouble when I deploy the application from Visual Studio, it only happens when Microsoft tests it or when I install it from the store using the Beta submission method.
Below is a screenshot of the catched exception being displayed in a messagebox upon trying to open a file from an email:
EDIT:
Just to make it even clearer, I do NOT need assistance in figuring out the normal practice of using a deep link uri to copy an external file into my application directory. I need help in either copying it directly into isolatedstorage or resolving the file access exception.
Listening for a file launch
When your app is launched to handle a particular file type, a deep link URI is used to take the user to your app. Within the URI, the FileTypeAssociation string designates that the source of the URI is a file association and the fileToken parameter contains the file token.
For example, the following code shows a deep link URI from a file association.
/FileTypeAssociation?fileToken=89819279-4fe0-4531-9f57-d633f0949a19
Upon launch, map the incoming deep link URI to an app page that can handle the file
// Get the file token from the URI
// (This is easiest done from a UriMapper that you implement based on UriMapperBase)
// ...
// Get the file name.
string incomingFileName = SharedStorageAccessManager.GetSharedFileName(fileID);
// You will then use the file name you got to copy it into your local folder with
// See: http://msdn.microsoft.com/en-us/library/windowsphone/develop/windows.phone.storage.sharedaccess.sharedstorageaccessmanager.copysharedfileasync(v=vs.105).aspx
SharedStorageAccessManager.CopySharedFileAsync(...)
I've inline the information on how to do this from MSDN http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206987(v=vs.105).aspx
Read that documentation and it should be clear how to use the APIs as well as how to setup your URI mapper.
Good luck :)
Ok I figured it out. The "install" directory is actually restricted access but for some reason the Visual Studio signing process leaves the app with enough permissions to access this folder. The correct procedure of determining a relative directory is not to use "Directory.GetCurrentDirectory()" but rather to use "ApplicationData.Current.LocalFolder". Hope this helps!
I have a code which is similar this:
string file;
using (StreamReader r = new StreamReader("xml.xml"))
{
file = r.ReadToEnd();
}
XElement xml = XElement.Parse(file);
using (XmlWriter w = XmlWriter.Create("xml.xml")) //The point of problem!
{
w.WriteStartDocument();
...;
w.WriteEndDocument();
}
When I try run it like a console application is everything all right. But problems start when I want to use it in an ASP.NET application. At the using line it throws UnauthorizedAccessException exception with a description "access to the path is denied". Why?
You need to check which account your application Pool is using to access your server files/folders, for example, make one code to copy one file to application folder, check all security info, copy and paste on this problem folder, normally use this account "IIS_IURRS" give full control to test only...
If IIS/the web server is configured correctly, an account with a very limited set of permissions is used. As your path points to the application directory, it is very likely that the application pool account is not allowed to write to this location.
If you run the code in a console application, your user's permissions are applied and it is more than likely that you are allowed to write to the output folder of the project as Visual Studio writes the build output there under your account.
I would not recommend to change the application pool account or the permissions of the application folder in the file system - it is a very sensible limitation that limits the amount of trouble an attacker can possibly make.
Therefore I'd recommend to either move the file to a folder that the account can write to without changing permissions or define a special one outside of the application folder hierarchy that the account is given permissions to.
Also keep in mind that multiple users might access the file at the same time, so a database might be a better choice to store the data.
I have had some problems earlier which caused my program to crash in all Windows OS because I did not create a new file/directory for my file. Then I have assured that I have created file/folder before initializing ect. Now my program works in Windows XP but it doesn't work in Windows 7. By saying that it works I mean that it creates a file/folder needed for my program. By not working I mean that the file/folder isn't created in windows 7.
Could this code be the cause of the crash under Windows 7? If so, how could I fix it?
private static string dir = Environment.GetFolderPath
(Environment.SpecialFolder.ProgramFiles) + #"\folder\";
private static string file = dir + #"\Settings.txt";
private string text;
public void CheckFileStatus()
{
if (!Directory.Exists(dir))
{
DirectoryInfo directory = Directory.CreateDirectory(dir);
}
if (!File.Exists(file))
{
using (FileStream fileStream = File.Create(file))
{
}
}
}
The program files directory in Windows 7 can only be written to with elevated privileges. Are you running your code as an administrator? It's also bad practice to write to the program files folder. You should be using the %appdata% folder.
Take a look here to see the various special folders. You will likely want to use either System.Environment.SpecialFolder.ApplicationData or System.Environment.SpecialFolder.CommonApplicationData. This will allow you to write data without needing elevated privileges.
You cannot create folders in Program Files without being having elevated privileges (ie acting as an Administrator) on Windows Vista and Windows 7. There are generally better places to put settings files that should be writable by any user.
Environment.SpecialFolder.ApplicationData or Environment.SpecialFolder.LocalApplicationData is generally the place for user specific application data which is most likely what you want.
The difference being that in a domain, ApplicationData will be placed in your roaming profile and be shared between computers on the domain, while LocalApplicationData is for that very machine only.
For home users or if you don't specifically want the data to be shared between machines, probably LocalApplicationData is better. That way you know it won't cause problems on a domain if you end up writing computer specific data in it.
There is also Environment.SpecialFolder.CommonApplicationData which allows for sharing the same data between all users on the computer, but while that may seem convenient, consider that any user on the machine can then change settings of a program that is later run by you which may cause security implications.
In my .net windows application am using a xml file .
But after installing the application by creating setup, while I am running that 'Access Denied' to that xml file message is shown.
I am using System.IO.File methods for doing file operations.
If any body knows the solution pls share.
Write access to program directory has been more and more restricted (starting with XP/Vista) since that is a secruity risk!
I would suggest to have the "base version" of that file readonly in your program directory...
Upon start of your app you check whether it is present in ApplicationData or LocalApplicationData or CommonApplicationData - (to get the real path at runtime use Environment.GetFolderPath). If it is not there then copy it there - in those locations your application has write access by default with no need for Administrator rights.
Program Files folder has limited access and can be modified by Administrator account. I would suggest you to save your xml file in *C:\Users\YourPCName\AppData\Local\YourAppFolder* .
This way you will be able to access and modify the file
I had this problem once so I used Isolated Storage and that fixed my problem. It may or may not work for you depending on the nature of your situation, but here's a quick tutorial on how to use it:
http://www.codeproject.com/KB/dotnet/IsolatedStorage.aspx
I've had a scout around some answers to similar questions but they haven't really helped me much.
I have an app, into which I've embedded some resources. At launch the app checks to see if the resources exist in the appdata folder and if not copies the template files from the embedded resources to the appdata folder before loading them and then using the ones in the appdata folder as the working copies.
I have a helper class which amongst other things returns the appdata and resources subfolder as follows:
class Folders
{
static public String GetUserFolder()
{
return Application.LocalUserAppDataPath;
}
static public String GetResourcesFolder()
{
// If the resources folder does not exist then create it
String userFolder = GetUserFolder();
String resourcesFolder = userFolder + "\\Resources";
if (!Directory.Exists(resourcesFolder))
{
Directory.CreateDirectory(resourcesFolder);
}
return resourcesFolder;
}
...
So my code calls the GetResourcesFolder method which returns the path (creating the folder in the process if it needs to) checks to see if the file exists and if it doesn't tries to write to it using something like:
String filename = Helpers.IO.Folders.GetResourcesFolder() + "\\data.dat";
FileStream outFile = System.IO.File.OpenWrite(filename);
So I've set the scene and this code is working on all the machines I had in the development office. However a couple of off site colleagues have complained it "crashes" on their machines - in each case an XP machine - but otherwise not a lot of useful information coming back from them - working on trying to get something more informative from them. I have XP machines in the office that it has worked on without problems.
After digging out some really old dev machines that were "archived" a while ago, I've managed to have a crash on two xp (sp2) machines also. On both occasions the crash seems to be related to write permissions and running the app using "Run As..." has resolved the problem and it executes correctly. However once the app has been successfully run once the app no longer crashes, even if I delete the files/folders it created from the appdata folder it will still create the successfully on subsequent executions even if I don't elevate permissions.
The problem I have is that I can now no longer repeat the crash on any dev machines available to me and I don't know how to go about putting the machine back into the state where I can.
Anybody got any ideas on what might be causing the problem, or how I may be able to return the machines to a "virgin" state to be able repeat the crash and help me track it down.
One course of action is to create a Virtual Machine of XP. You can save the state of the machine before install for testing. After your install just revert back to the previous state to test again. There are a few Vendors with free Virtual Machines:
http://www.microsoft.com/windows/virtual-pc/
https://www.virtualbox.org/
As too the related problem itself, I don't know a better way than to install VS on a virtual machine for testing purposes.
+1 to Erik's VM solutions for reporducing the issue.
For tracking down permissions issues consider using ProcMon ( http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx ) - will show enverything you ever wanted (and not :) ) about file/regisstry access made by a process. I'd recommend trying it several times first on machine where you program works fine to get filtering setup for your process and get a sense of what should be happening.