I have a windows service run with local system account
What my program does is :
if (File.Exists(outputPath))
{
File.Delete(outputPath);
}
File.Move(archivePath, outputPath);
Relevant folder is application folder of iis where its application pool's identity is ApplicationPoolIdentity located under c:\MyAppFolder.
My windows service does its few times a day, and my clients checks if any new version exists every 5 minutes(0,5,10,15...) and download that file.
Time to time, file is somehow get "locked" on filesystem then
iis gives 401 error
File cannot be deleted
My first question how can I repro this situation?
One patch is done by colleagues is:
var fs = File.GetAccessControl(outputPath);
fs.SetAccessRuleProtection(false, false);
File.SetAccessControl(outputPath, fs);
Although this patch, it seems error occured again,
I may apply, this solution as well.
Are those solutions are enough or necessary?
Again my first question is important "repro issue" and understand why this happens.
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.
This question already has answers here:
HTTP Error 503, the service is unavailable
(40 answers)
Closed last year.
I published my Web Api (framework 4.5) in this path:
C:\inetpub\wwwroot\MyWebAPI
In my IIS, I converted this folder to an app
When i try to access this URL http://localhost/MyWebAPI/api/client/1 the message appears:
Service Unavailable
HTTP Error 503. The service is unavailable.
Why is this?
Update
My App Pool is set to be "STOP". When I turn it on, it goes back to "STOP"
I found the solution
Click on Application Pools under the tree with your machine name,
on the right side, click click on Advanced Settings,
in Process Model change the "Load User Profile" to false
Start your application and restart your IIS
The error will surely change, in my case the error changed to this one
"Config Error: This configuration section cannot be used at this path.
This happens when the section is locked at a parent level. Locking is
either by default (overrideModeDefault="Deny"), or set explicitly by a
location tag with overrideMode="Deny" or the legacy
allowOverride="false"."
I have found the solution for this other problem here
Config Error: This configuration section cannot be used at this path
This is a fairly old thread, but I stumbled across it with the same issue. For me, the resolution was to reset the App Pool user. I was starting the site, but the app pool would just stop. No logs, nothing. I recently had to change my windows password and the app pool user (me) was using the old password :-)
(note my website continued to work for a few days with the old password until I did an iisreset which is when the problem started)
You might stop App pool, start it and error will be gone.
Run the following commands in PowerShell in administrator mode.
Stop-Service -Force WAS
Remove-Item -Recurse -Force C:\inetpub\temp\appPools\*
If the above command not working, delete files manually.
Start-Service W3SVC
I know this has been asked before many times, but I have browsed tens of similar questions without help.
This error is showed when my asp.net 4.0 application tries to access a folder on my local drive, doing this:
XmlTextReader confReader = new XmlTextReader (filename);
while (confReader.Read()) // <- error line
{
// do something
}
In my web.config I have <Identity Impersonate="true">. For the folder I have assigned full-access to:
everyone
IIS APPPOOL\<custom apppoolname>
NETWORK SERVICE
Debugging the application, I can put up a watch which evaluates this call right before the incriminated line:
System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
the call shows the current user is IIS APPPOOL\<custom apppoolname>.
I'm on Windows 7 64bit with Sp1. I know it's probably something stupid but I have already spent an awful amount of time on this.
Edit:
The problem was in the variable "filename", which pointed to the right folder, but for a configuration problem the filename was missing (i.e. the content was "c:\data\" instead of "c:\data\file.xml"). The Asp.net error was actually confusing, since I had all the right permissions to access that folder. DJKRAZE pointed me to the right direction.
Here is what I would suggest checking
where are you declaring filename..?
Does the file even exist..?
do you have rights to that folder..? have you tried running VS as Admin..? do you have Virtual Directory setup for the web app..sounds like you have a few things configured improperly as well but can't really tell based on the code for starters this line System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
should yield your domain\\username or compuername\\username
Glad that FileName was all it was
IIS requires the path to a folder in the server machine has rights for Anonymous user login to access.
Make sure the user Anonymous has the rights to access the folder.
I have a C# application, and I need to dump some output to a log file during operation. I am wanting to give the user the option of where to locate the log file, but by the client request it needs to default to the current application location, which is normally /Program Files/.
When I deploy my application on a Win7/Vista machine, though, the application does not write the log file unless I run the program as an Administrator. At the same time, it seems to be silently handling the case where it cannot write the file, as I am currently handling all exceptions being thrown during the file creation and writing process.
I am currently trying to detect lack of write permission by both:
A) Creating a DirectorySecurity object by calling "Directory.GetAccessControl()" and
B) Checking security priviledges with the "SecurityManager.IsGranted(permissions)" method,
but A does not throw an exception when I expect it to, and B returns true every time.
I have seen numerous posts related to this topic, but they all give the solution of just writing to Application.UserAppDataFolder or some variation of it. My client has specifically asked to default to the current Application path, so I need to at least find a way to gracefully warn them when writing the log file is going to silently fail.
Note: My current code works find on Windows XP (since there are no UAC, I assume). Basically all I need to know is why all my calls are telling me that writing the file is going fine, when the file is never created at all unless I am running as Admin.
Thanks!
Windows Vista and 7 will write files to the Program Files directory just fine.
Well, not really, but the program thinks it's just fine. In reality, the file is written to the current user's VirtualStore directory; that is, in %userprofile%\AppData\Local\VirtualStore\Program Files
You can include a manifest file to disable this behavior for your application to get the results you expect.
You can force the os to run your app as Admin.
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
There are three ways your app can run - elevated, deliberately not elevated (manifest saying asInvoker), or accidentally not elevated (no manifest). Elevated apps will be able to write to Program Files. Deliberately not elevated apps will get access denied. Accidentally not elevated apps will succeed but the file will be written elsewhere. This last case is what's happening to you. It didn't silently fail. You just don't know where the files are. See http://www.gregcons.com/KateBlog/FindingFilesYoureSureYouWrote.aspx for screenshots.
Therefore if the users insist on the current directory, you should add a manifest requesting asInvoker. You will then get AccessDenied and they will see the error message. I think they are odd for wanting this. Ask them if they are ok with one extra click to find them: if so, keep your app using virtualization (I really disapprove) by having no manifest and then train them to click the Compatibility Files button.
My preference: write elsewhere and manifest to asInvoker. My second choice: stick with current directory, no manifest, train them to find virtualized files. My third choice: stick with current directory, manifest to asInvoker, users see error messages when log files are not written, but logs are lost.
I am experiencing the same problem. I have an xml file that i am writing to...When I install the app(C sharp) and try to run the application am getting an exception due to write permission. When I change the file permission (give read permission to users) it is working ok..
The ultimate test for whether you have the rights to write a file is to open it for writing.
I.e.
try
{
File.Open(path, FileMode.OpenOrCreate);
...
}
catch(SecurityException)
{
... it failed for security reasons
}
catch(Exception)
{
... it failed for other reasons
}
Besides Stefan P.'s suggestion to elevate the app to run as admin, you could also modify the installation folder permission on install to to add the Users group to have write access. Then the application would work as well.
Moving the log file location would be the best option though.
I have a webservice on one of my websites which restarts the websites app pool.
The problem Im getting is the IIS7 app pool keeps stopping with the following warning and then error:
Warning:
A process serving application pool 'appPoolNameHere' exceeded time limits during shut down.
Error:
Application pool 'appPoolNameHere' is being automatically disabled due to a series of failures in the process(es) serving that application pool.
The code I am using to do this is:
try
{
var serverManager = new ServerManager();
var currentPoolName = SettingsManager.AppPoolName;
if (!string.IsNullOrEmpty(currentPoolName))
serverManager.ApplicationPools[currentPoolName].Recycle();
HttpRuntime.Close();
}
catch (Exception ex)
{
var exceptionManager = ExceptionManagerFactory.GetExceptionManager();
exceptionManager.LogException(ExceptionManager.Severities.Critical, ex,
"App Pool restart failed");
}
I am not getting any exceptions being thrown here, but the app pool is stopping, this doesnt happen all the time and is very hard to replicate, I have tried several different things even just hitting the hell out of that service and sometimes its fine other times it dies.
Is there anything I can do to fix this?
The reason I have to restart it is due to an external config file to the webconfig which deals with the url redirects which is updated from the admin system.
Thanks for any help with this.
Well I seem to have sorted (not fixed) the issue, with some tape and sticky-back-plastic.
The solution
Changed app pool setting: Rapid-Fail Protection to false
This stops IIS from killing the app pool after several failed requests to it.
I also added in retry system, so if the recycle request fails it waits for 10secs and tries again, it will do this 5 times before giving up and sending out an exception notice.
This has fixed the problem, and everything seems to be working well again, although something about this screams this is wrong!! at me.
Only if IIS would monitor other files in a website and restart the app pool when it saw a change.
I didn't work with Microsoft.Web.Administration namespace, but what about unloading application domain and sending request to your website so that to start application again?
Good example (2nd point) by Peter Bromberg how to do this.
Update.
Reading error stack
System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
at Microsoft.Web.Administration.Interop.IAppHostMethodInstance.Execute()
I thought of most common reason: insufficient rights. All administrative actions require administrative rights. When code above is executed, which user account is impersonated? IUSR? Switch to any admin for that block and it should work without exception.