I have a function in the code behind of an ASP.NET webpage that creates a file and then opens it with a javascript command. This works in the IDE - it creates the file, asks me where I want to save the file, I can save it, etc. - but when I install the website and test it out, I get an UnauthorizedAccessException while just trying to create the directory for the file within C:\inetpub\wwwroot.
The frustrating part is that I have a similar function that runs in a service and that creates its directories and files just fine in C:\inetpub\wwwroot.
What would I have to do to get this to work for a webpage?
if(!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
StreamWriter SW = new StreamWriter(fullpath, false, Encoding.Unicode);
SW.WriteLine(/*stuff*/);
SW.Close();
You need to make sure the .NET user has write access by right-clicking on the directory, going to the security tab, and adding the appropriate user and checking the write checkbox.
Depending on your version of .NET/Windows/IIS this can be different, typically it is Network Service or IUSR. If you are running IIS7 make sure to check the Identity under advanced settings of the application pool, as that will be the user that needs the write access, again typically this is Network Service.
You need to grant the ASP.Net user write access to the directory.
just open your text editor( notepad or textpad or anything) using administrative previledges
right click on .exe file and click run as administrator you will be able to do it now
Related
I have an application that allows the user to upload a file (saving it to in a folder located in the wwwroot of the ASPNETCORE application). From here they can make edits to it and then they can choose to export the file as a csv/ xml/ xlsx which downloads the file to the user's 'downloads' folder.
While debugging in Visual Studio this all works fine however when I publish and deploy the application to IIS I am getting the exception
Error saving file C:\windows\system32\config\systemprofile\Downloads(FILE NAME)
Could not find part of the path C:\windows\system32\config\systemprofile\Downloads(FILE NAME)
This is the current way I am getting the downloads folder:
FileInfo file = new FileInfo(Path.Combine(Environment.ExpandEnvironmentVariables(#"%USERPROFILE%\Downloads"), data.Filename + "." + data.FileType));
However I have also tried the solution that Hans Passant has answered to a similar question here. Both solutions worjk fine while debugging locally however as soon as I publish them, this one produces the exception:
Value cannot be null. Parameter name: path1
Which I presume is thrown at this point here when I try and save the file to the user's download folder.
using (var package = new ExcelPackage(file))
{
var workSheet = package.Workbook.Worksheets.Add("ExportSheet");
workSheet.Cells.LoadFromCollection(exports, true);
package.Save();
}
I don't really know how I would be able to reproduce these exceptions seeing as locally using Visual Studio it all works fine.
Has anyone else came across this issue while trying to download a file?
UPDATE: When the application is running on IIS, it seems to be using that as the user profile instead of the actually user, so when it tries to navigate to the Downloads folder, it cannot find it. How can I force it to use the user's profile?
LoadUserProfile is already set to True.
Web applications have no knowledge of the end-user's computer's filesystem!
So using Environment.GetFolderPath or Environment.ExpandEnvironmentVariables in server side code will only reveal the server-side user (i.e. the Windows Service Identity)'s profile directories which is completely separate and distinct from your web-application's actual browser-based users OS user profile.
As a simple thought-experiment: consider a user running a weird alien web-browser on an even more alien operating system (say, iBrowse for the Amiga!) - the concept of a Windows-shell "Downloads" directory just doesn't exist, and yet here they are, browsing your website. What do you expect your code would do in this situation?
To "download" a file to a user, your server-side web-application should serve the raw bytes of the generated file (e.g. using HttpResponse.TransmitFile) with the Content-Disposition: header to provide a hint to the user's browser that they should save the file rather than try to open it in the browser.
We have developed WPF application which allows user to select folder path. WPF application writes files/data into this selected path. When we select "C:\ProgramData" as the path, it creates the file and write the data. But when the path is other than "C:\ProgramData", file is generated but data is not written into the file and it seems a permission issue. Can anybody help us in finding out , how we can assign the same kind of permission to selected folder same as "C:\ProgramData" so that it allows to write data into the file. In conclustion what is the extra permission does "ProgramData" has which is not their for other folders?
Note: it only works properly with ProgramData folder.
Whenever your application is launched with standard user rights, it can write to only those folders to which a standard user can write to. E.g. are:
C:\Users\USERNAME\
C:\ProgramData\
D:\
It will not be able to write to folders like:
C:\
C:\Users\SOME_OTHER_USERNAME\
c:\Windows
C:\Windows\System32 etc
For that you either need to disable UAC or launch the application with administrative permissions.
I would suggest that whenever user selects a folder from your application check if you can create a file/ folder in that location before accepting the path.
solution what i can give is let's user select the path after you get the folder path just check whether you can write data to it , see this code
bool HasAccessToWrite(string path)
{
try
{
using (FileStream fs = File.Create(Path.Combine(path, "Access.txt"), 1, FileOptions.DeleteOnClose))
{
}
return true;
}
catch
{
return false;
}
}
#Ganesh is right but you may go with one of the following options:
Run the installer with admin rights, ask user to select target folder during installation and set the permissions to everyone or required groups of users/roles.
If above is not applicable then configure your application to always run under admin account, in that way it will have access to all folder to write data. To configure run as admin user application manifest as explained here:
Turn off UAC, not a recommended approach though.
I had same issue so, I forced installer to be run under admin rights and asked user to create target folders during installation. Used a custom action to set full rights for everyone user group on the target folder. Since security was not issue for us so, it was ok to allow everyone but consider your environment before using this option.
I have written a win application that works on a network.
In one of its forms user can browse and select file from local computer and add it to a list, so the application copies these files to a folder in My Network Places that no users can access to it but one that i have created already for my application so i have his username and password.Every things works fine up to here.
In this form user can also open a file by select it and press open button, so the file should open in an application that relates to its extension(for example test.xlsx should open in Exel.exe).I have used Process.Start() to do this but for each extension i receive an individual error(for example "Access is denied" for NotePad and "RunTime error" for AdobeReader and "Not enough memory" for Excel).
What is my mistake?
Note : I have used ImpersonatUser to logon that user in my application.
Edit : I have used following code to open the file :
Using(WindowsImpersonationContext impersonateUser = LogonMethod())
{
ProcessStartInfo pInfo = new ProcessStartInfo(filePathWithExtension);
pInfo.Domain = MyDomainName;
pInfo.UseShellExecute = false;
Process.Start(pInfo);
}
Note : My LogonMethod uses LogonUser method of advapi32.dll.
The behavior you are seeing is almost expected.
it looks like you are not launching application directly, but rater using association by file name. I don't believe you'll get application launched under account you want. You can check what account application is run unrder using task manager.
Most application are not tested to run in "run as" context, so they may work correctly or fail randomly.
I could not solve this problem, so i have used another way.I have copied the file to a temp folder and then used Process.Start to open this new file.
I am trying to delete the excel file from a specipic location . but can't deleting. having error :
Access to the path 'C:\mypath\sample.xlsx' is denied.
I write a code as :
protected void imgbtnImport_Click(object sender, ImageClickEventArgs e)
{
try
{
string strApplicationPath = HttpContext.Current.Request.MapPath(HttpContext.Current.Request.ApplicationPath);
string strXLStoredDirectoryPath = strApplicationPath + "/Information Documents/";
DirectoryInfo di = new DirectoryInfo(strXLStoredDirectoryPath);
string fileName = flUpldSelectFile.FileName;
if (!File.Exists(strXLStoredDirectoryPath))
{
Directory.CreateDirectory(strXLStoredDirectoryPath);
di.Attributes = FileAttributes.Normal;
}
string strCreateXLFileDestinationPath = strXLStoredDirectoryPath + fileName;
if (File.Exists(strCreateXLFileDestinationPath))
{
File.Delete(strCreateXLFileDestinationPath);
}
flUpldSelectFile.SaveAs(strCreateXLFileDestinationPath);
di.Attributes = FileAttributes.ReadOnly;
}
catch (Exception)
{
throw;
}
}
please guide.........
-***********************************************************************
Still problem there . it is not resolved . getting UnauthorizedAccessException. as access denied to deleting file. I m tired now . please help; I tried many things..please help
-***********************************************************************
Is may be iffect of VSS ? i am using that
UPDATE:
Part of your issue might be what is saving/creating this file. If you're using a built in "Save" or "SaveAs" feature the underlying file stream might still have a lock on the file. writing your own save logic with a FileStream wrapped in a Using statement will help dispose the stream right when you're done thus allowing you to further manipulate the file within the same context.
if flUpldSelectFile.SaveAs(strCreateXLFileDestinationPath); is the only logic that saves the file then get rid of the built in SaveAs functionality. write your own save logic using a FileStream wrapped in a Using block.
In your example i can't see what flUpldSelectFile is so i am assuming it is a System.Web.UI.WebControls.FileUpload control. Here is an example of rolling your own save logic.
using (FileStream fs = new FileStream(strCreateXLFileDestinationPath, FileMode.Create))
{
byte[] buffer = flUpldSelectFile.FileBytes;
fs.Write(buffer, 0, buffer.Length);
}
As stated previously, use this tool to find out if there is a lock on the file by another process.
ORIGINAL
Pop open this wonderful tool and search for that file to see who/what has it locked
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
(source: microsoft.com)
If your code is working under IIS , Note that ASPNET user doesn't have access to computer files, you should give access to it, that is not recommended, or store you files in the place where ASPNET user have access
see here
Try a combination of these 2 steps:
Set the IIS application pool to run under an account with privileges such as a domain account or local user account (not a default account like local service or local system). Instructions for IIS7.
Turn impersonation on in the web.config file, in the <system.web> section:
<identity impersonate="true"/>
<identity impersonate="true" userName="contoso\Jane" password="password"/>
I think the message is clear, you do not have authorization to delete the file or it is opened by another application. I bet 2$ you can't delete the file manually either.
As others have said, this is because IIS runs your application as a user with restricted access rights. This is a wise security precaution, so that your system is less vulnerable to malicious attacks.
What you need to do is to give the ASPNET user access to the specific folder. You do that from the security tab in the properties of a folder. The user you need to give full control to depends on the version of IIS you are using. In Windows XP it is ASPNET. In Windows Server 2003, 2008 and Windows Vista, 7 it is NETWORK_SERVICE.
See also this question for more details.
Make sure the file isn't opened or
locked by another user/process.
Make sure ASPNET user has access on the file\folder (check the file\folder's property using windows explorer and go to security tab. check if ASPNET user is added there).
One of two things are happening. Either the file is already open, or the permission of the user running IIS does not have the proper permissions.
Either way, this utility ProcMon: Proc Mon
will help you determine the issue. Run ProcMon, kick off your process to try and delete the file. Then go back to procmon. Hit Ctrl-E to turn off the capture, then Ctrl-F to find. Enter the name of the file you're trying to delete. Then once you've found the correct line with the access denied (or similar error) Double click on the the line to get further information. When you click on the Process tab, it will show you the exact user that is trying to delete the file.
So, if it is a file permission issue, you now know the exact user, and can therefore go to the file system right click on the folder that houses the file you are trying to delete, and grant that user permissions to read/write/update that folder.
Second, if the file is locked open instead of a permissions issue, you will have to find out what process is holding open the file. If you are also writing this file in another part of your code, perhaps you are not closing it properly or releasing the object reference.
Have you verified that the file does not have the read-only attribute set?
I don't think we have enough info to be helpful. What is the security context (identity) during the call to Delete? Is the application impersonating the end user? If it is, how are they authenticated? If by Windows / Active Directory, then you'll need to verify that user's access rights to the specific file. If by Forms login, then you should probably not impersonate and verify that the AppPool's security context has the appropriate access rights.
I have an application that is useable by all users (admin or limited) in .NET (C# specifically).
When the application first launches - it creates a few files that it needs in the C:\Documents and Settings\All Users\Documents\ for all subsequent launches.
If the limited user in XP is the FIRST user to launch the application it creates the files fine and both the limited user and administrators can run fine.
However if the Administrator (or I am guessing a different limited user) is the first to launch the application then the limited user is NOT able to run the application.
The two files that it is NOT able to read/write to if created by an Administrator is a Log4Net log file and a SQLite db file.
The SQLite database file is being created with a straitforward .NET File.Copy(sourcepath, destinationpath). The sourcepath is a seed database file installed with the application - so on first run it copies that from the C:\Program Files\app install\seed.db
Is there a way to set the permissions on the file when I copy it? File.SetAccessControl() perhaps? I am not clear on how that works.
The other issue is that the log4Net rolling file appender will not roll the old file and create a new as the old file was created by the admin user when they ran the app.
Any ideas? Ironically this all works perfectly fine in Vista with limited/admin accounts - this is ONLY happening in XP with admin/limited accounts.
I think SetAccessControl is the way to go. Maybe something like this:
// get the existing access controls
FileSecurity fs = File.GetAccessControl(yourFilename);
// add the new rule to the existing settings
fs.AddAccessRule(new FileSystemAccessRule(
#"DOMAIN\Users", // or "BUILTIN\Users", "COMPUTER\AccountName" etc
FileSystemRights.Modify,
AccessControlType.Allow));
// set the updated access controls
File.SetAccessControl(yourFilename, fs);
Note: It's important that you get the existing access control list from the file and then add your new rule to that. If you just create a new access control list from scratch then it will overwrite the existing permissions completely.
Yeah, it's the SetAccessControl method all right, there is a good example here
(the post from satankidneypie)
Good luck