We've got a process currently which causes ASP.NET websites to be redeployed. The code is itself an ASP.NET application. The current method, which has worked for quite a while, is simply to loop over all the files in one folder and copy them over the top of the files in the webroot.
The problem that's arisen is that occasionally files end up being in use and hence can't be copied over. This has in the past been intermittent to the point it didn't matter but on some of our higher traffic sites it happens the majority of the time now.
I'm wondering if anyone has a workaround or alternative approach to this that I haven't thought of. Currently my ideas are:
Simply retry each file until it works. That's going to cause errors for a short time though which isn't really that good.
Deploy to a new folder and update IIS's webroot to the new folder. I'm not sure how to do this short of running the application as an administrator and running batch files, which is very untidy.
Does anyone know what the best way to do this is, or if it's possible to do #2 without running the publishing application as a user who has admin access (Willing to grant it special privileges, but I'd prefer to stop short of administrator)?
Edit
Clarification of infrastructure... We have 2 IIS 7 webservers in an NLB running their webroots off a shared NAS (To be more clear, they're using the exact same webroot on the NAS). We do a lot of deploys, to the point where any approach we can't automate really won't be viable.
What you need to do is temporary stop IIS from processing any incoming requests for that app, so you can copy the new files and then start it again. This will lead to a small downtime for your clients, but unless your website is mission critical, that shouldn't be that big of a problem.
ASP.NET has a feature that targets exactly this scenario. Basically, it boils down to temporarily creating a file named App_Offline.htm in the root of your webapp. Once the file is there, IIS will takedown the worker process for you app and unload any files in use. Once you copy over your files, you can delete the App_Offline.htm file and IIS will happily start churning again.
Note that while that file is there, IIS will serve its content as a response to any requests to your webapp. So be careful what you put in the file. :-)
Another solution is IIS Programmatic Administration.
Then you can copy your new/updated web to an alternative directory then switch the IIS root of your webapp to this alternative directory. Then you don't matter if files are locked in the original root. This a good solution for website availability.
However it requires some permission tuning...
You can do it via ADSI or WMI for IIS 6 or Microsoft.Web.Administration for IIS 7.
About your 2., note that WMI don't require administrator privileges as ADSI do. You can configure rights by objects. Check your WMI console (mmc).
Since you're already load balancing between 2 web servers, you can:
In the load balancer, take web server A offline, so only web server B is in use.
Deploy the updated site to web server A.
(As a bonus, you can do an extra test pass on web server A before it goes into production.)
In the load balancer, take B offline and put A online, so only web server A is in use.
Deploy the updated site to web server B.
(As a bonus, you can do an extra test pass on web server B before it goes into production.)
In the load balancer, put B back online. Now both web servers are upgraded and back in use in production.
List item
You could also try to modify the timestamp of web.config in the root folder before attempting to copy the files. This will unload the application and free used files.
Unless you're manually opening a handle to a file on your web server, IIS won't keep locks on your files.
Try shutting down other services that might be locking your files. Some examples of common services that do just that:
Windows Search
Google Desktop Search
Windows Backup
any other anti-virus or indexing software
We had the same server (2003) and the same problem. Certain dll's were being locked and putting the App_Offline.htm in the website root did jack diddly for us.
Solution:
File permissions!
We were using a web service which runs under the Network Service account or the IIS_WPG account to deploy updates to the web site. Thus it needed write access to all the files. I already knew this, and had already set the permissions on the directory a while ago. But for some strange reason, the necessary permissions were not set on this one problem dll. You should check the permissions not only on the directory, but on the problem file as well.
We gave Network Service and IIS_WPG users read/write access to the entire web root directory and that solved our file in use, file locked, timeout, and access denied issues.
Related
Recently deploying an mvc4 project to a virtual directory on a shared iis6 server, I was able to get the server to allow reading files (a problem stemming partially from extensionless URLs).
I have not however, been able write anything to the database or to txt file logs, since deployment. Speaking to the hosting service I've been able to determine that the user is Network User, that all users (including asp net) have read/write privileges. I've tried moving the log files into a separate Log folder, also to no avail.
the error I'm getting is:
"[UnauthorizedAccessException: Access to the path
'D:\wwwroot\wwwroot1\isphost\psychtech\psychtech.co.il\Testing\Log\LogHttpRequ
ests.txt' is denied.]
Any and all ideas would be appreciated!
The message is pretty clear, the user of the app pool under which run the IIS worker of your site can't access this path to write to the file. The problem might be the same to save to your .mdb.
I suggest you to contact your hoster and ask him about this, it will probably be able to help.
On a side note, you may whant to use a proper database as the file/mdb ones aren't meant for load and concurent acces as it can occur in a web environement. It will also be more scalable, more reliable, more secure and more resilient to failure.
After many hours, the hosting company IT specialist demystified the problem: as I'm deploying an .net 4 application on an iis6 server, the server utilizes a different user, namely: NETWORK SERVICE. Once this service was granted write privileges, the problem was solved.
I believe this is what reporter was hinting at.
A note of caution: this configuration is highly susceptible to SQL Injection, requiring additional safety measures in the code
I am facing a strange issue with my site in IIS 7. I have 10 sites with different sub-domains hosted on IIS 7. I am using .NET framework 3.5 and SQL Server 2008 R2. Three sites I have configured on DefaultAppPool while for others I have created separate application pool for each and configured them with their specific.
I allows user to upload video, after upload completes I used to hint it (a process to make bit rates of video equal for on-line streaming on android) using MP4BOX - a command line interpreter, with server side code.
What issue I am facing is while using DefaultAppPool the MP4BOX works fine but when I configured site to its specific appPool, MP4BOX stops working. I have go through the settings but haven't find any issue. Can anyone help me to overcome this issue.
Awaiting for your valuable response.
Resolved it myself by assigning read/writes permission to the application pool to the directory.
After lots of research I have found that it was happening due to read/write permission of this exe to the specific directory. MP4BOX need to have read/write permission to create video file in the IIS directory. So I have added application pool as a user to the specific directory to which mp4box was accessing for read write.
I have a production website that sits on two servers that used local label files to drive their page labels (request going round robin between the two).
Users need the ability to upload new labels files, but once uploaded on one I need it also updated on the second website - this needs to be immediate. I was trying to use a shared folder on one of the servers, but even if I give it everyone full access i get the error "Exception message: Unable to find label folder at \\MACHINENAME\LabelFiles" when reading from the other server, I've also tried giving full permissions to "IIS AppPool\DefaultAppPool", but get the same issue.
I'm using IIS 7.5 on Windows Server 2008 R2
Question-
Is there a way to share a folder between the two sites?
Is there a better alternative solution?
Thanks
Both the websites should have a virtual folder pointing to the same physical folder, where the users can upload files.
Make sure also that the Anonymous access is disabled
One approach is to map the folder as a drive on each of the production machines, it should then be as simple as refereing to that particular drive letter.
This can be done by navigating to the folder in windows explorer, then clicking Map Network Drive.
I cannot guarantee this will work, buut it might be worth a go.
The IIS AppPool\DefaultAppPool user is a special account that is only local to the machine where it is being used. You cannot access network file shares with that account. You will either need to use the 'Network Service' account or a domain account as the app pool user.
Also, since you are load balancing this site between two servers, you might want to consider using some type of SAN or NAS storage that is shared between the two servers. Otherwise, you will need to come up with some kind of process to synchronize the file share on both servers.
Dear all, i have following code to open a file on click of a button
System.Diagnostics.Process.Start("soffice.exe",filepath);
soffice.exe is to open .odt files & filepath is containing the complete path of the file which i want to open.
This is working perfectly when i m executing the code on my local system, but as i m hosting it on the iis server (5.1), its not taking any action (event not throwing any error too). My filepath is accessing a folder in my project, not outside. Kindly suggest the possible reasons and solutions
In response to your comment above...
First of all, by "web service account" I don't mean web services. I mean the service account on the web server under which the web application runs. This could perhaps be the account of the user logged in to the website, or the default IIS account, etc. The best way to address this would be to fully qualify the path to soffice.exe when calling it, that way you don't have to worry about the PATH environment variable. (Additionally, you don't have to worry as much about another application being run maliciously or by accident and doing something unexpected with unknown permissions.)
Second, there seems to be a critical design flaw in your approach. Even if you do manage to get the application to launch on the server, it's going to launch on the server. Is the resource manager sitting at the actual web server? If not, then opening the file in the application on the server will do him no good whatsoever. If he is sitting at the server, then he's the only person who can use this.
You don't want to open the file on the server. You want to deliver the file to the client. Then if the user (the resource manager in your example) can open the file in soffice.exe on his local machine. If his environment is set up correctly, it should open automatically. (Though the browser will also give him the option to save the file locally and then open it.) Simply linking to the file should suffice. Is there any particular reason why it wouldn't?
If you need to use a form post rather than simply a link in order to deliver the file, you can still stream the file from your server-side code. Here's a previous question discussing how to do that. Basically the process involves clearing the output buffer, setting the headers (content length, content type, suggested file name, etc.), streaming the bytes, and flushing/closing the output buffer.
I've got a webserver where people upload files. What I need to do is take those files and write them to a file share on the Active Directory domain. The problem -- the webserver is not on the domain.
So, how is the best way to do this? I would have thought this would be easy, something along the lines of create a connection with some credentials and do it. But apparently not. The closest I've found is Impersonation with WindowsIdentity.Impersonate, but everything I've read says that is a bad idea in a production environment.
Any ideas? I'm working on a solution that FTPs the files, but that's unsatisfying too, and a fallback plan.
I'm using c# and .net 4.0 in (obviously) a windows environment.
Edit: I should point out that I can't run servers (or services) that access the outside on that domain. The FTPing is a temporary workaround.
I would have another program probably a Windows service pick the files from the web service file location and move them to the active directory directory. I would probably have this process execute from the location where they are being copied to. Make them available in a share on the web server visible only to the process's user and admins.
I think that an FTP solution is better than using a Windows Share; however, I would think a web service of some type would be the best option for an inter-domain file exchange. That said, if you've got it working with WindowsIdentity.Impersonate -- why not use it? What context did you read that it was a bad idea?
Is there any way that you can map this file share as Network Driver. If you can do that, you don't need to manager Security and will be super easy to access these files as if they are local.