A few days ago I had a bizarre website administration issue. I had written an ASP.Net app that inadvertently locked my assemblies in the /bin directory. Granted the obvious, that assemblies in ASP.Net applications are shadow-copied to the Temporary ASP.Net files folder under the specific version of the framework, but my app was special in that it dynamically loaded and inspected the assemblies in the
actual bin directory.
In designing the app, I had waited to put the inspection of these assemblies in a separate AppDomain, electing to do that when time permits. Because of this, When I loaded the assemblies in the /bin directory, the .Net Framework keeps a lock on those files for the lifetime of the current AppDomain (until it is unloaded). For working on my local machine, this is fine during development. If anything locks, I can simply run an IISRESET command, which will unload all AppDomains for ASP.Net web applications on my server. When migrating these assemblies to my hosted environment, it was a different story.
Using FTP, I pushed up all my new development work, did a small smoke test, tried my pages and voila! She worked! I went back into development and modified my pages so they load all of these assemblies on a separate AppDomain (which can be unloaded through code). I went to push up my new changes and then it hit me...
The assemblies were now locked in the hosted environment!Well, great! Now I can't push up my new changes, or any other changes for that matter, until the AppDomain which runs my app in the hosted environment is unloaded. This means either calling the hosts on the phone and asking them to do an IISRESET for me, which since this is a shared server, they probably won't do because it would knock off other customers for a few seconds, or asking them to reboot the server, which for the same reason, they also probably will not do. Oh, I'm so screwed.
So I got to thinking. I could either wait for one of these two things to happen naturally, which since one of the founding principles of shared/dedicated hosting is 100% uptime, could be never, or I could take matters into my own hands. I figured there had to be a way to release file locks through code. Seems easy enough, right?
My first challenge was to find a method to unlock these files which would only affect ME. I couldn't be responsible for interrupting someone else's site on that server. My solution had to be isolated to my own application. I started writing a little administrative ASPX-only (no codebehind) page which could perform my task.
I tried using System.IO.FileStream to unlock the individual files. Well, that didn't work because the Framework will sense that the files are already locked BEFORE you even try to unlock them, and throws an exception.
So I did a little research. I found a way to unload a web app and return it to a state just like it was the first time it was run. Call HttpRuntime.UnloadAppDomain(). What this does is clears out the Temporary ASP.Net Files folder for your application. The next time a request is made, it reinitializes the app, shadow copying all the assemblies in the /bin directory to the Temporary ASP.Net Files folder. Cool. You would think that would work. It did not! It shadow copied all of the assemblies, but naturally it doesn't touch the actual assemblies in the /bin directory, which means it didn't affect the locks. D'Oh!
I was growing frustrated. My next step was to do something a touch more drastic that wouldn't be isolated to just me. I was going to programmatically perform an IISRESET on the server. I wished there was a way to do an IISRESET just for a particular LM Instance, but alas, there is not. I would be taking down every internet service on that remote machine momentarily. Fuck it. Let's do it. So I wrote some VB code that would start a Process which would run IISRESET. I tried it, it worked on the hosted server. I was actually rather surprised that the user account which ASP.Net was running under on that server actually had permissions to start a process. Gift Horse -- Mouth -- whatever.
I could see IIS coming down and coming back up. Thankfully it only took a few seconds. Must be a powerful machine to perform an entire IISRESET in like 3 seconds. Alright! I reconnected to FTP and tried to upload my latest DLLs and DAMMIT! Still locked. Sumummabitch! I was really pissed now. I couldn't understand why an IISRESET wouldn't release those file locks.
I did a little more research. The basic principle of unlocking a file that your app did not lock is to get its file handle, get the process which has the file handle open, and use the Win32 API method CloseHandle to release the lock. Well since I did not and could not know what the file handle was on the hosted server, I tried a slightly different method that ultimately worked out for me.
I started thinking I would use the Win32 API to get a list of the processes with open file handles on my files and simply kill them. Then it hit me. You're overthinking, stupid! You know which processes are running ASP.Net. The only processes ASP.Net has ever run under are aspnet_wp.exe (ASP.Net 1.0) and w3wp.exe (ASP.Net 1.1 and 2.0). Fuck it! I'll just kill them. At this point after I had done a couple of IISRESETs on the hosted server, I didn't give a shit about interrupting anyone's services anymore. I was too pissed off.
THANK GOD! It worked. Killing those processes on the server released my file locks and I was able to make my updates. So now I kind of have an ultimate IIS administration tool now. I can provide any task I need from a web page, provided the ASP.Net process account is given enough permission. Here Is a sample of my work.
<%@ Page Language="vb" AutoEventWireup="false" Inherits="System.Web.UI.Page" %>
<%@ Import Namespace="System.Diagnostics" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>IIS Override Tool</title>
<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
<meta name=vs_defaultClientScript content="JavaScript">
<meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
</head>
<body MS_POSITIONING="FlowLayout">
<form id="Form1" method="post" runat="server">
<asp:Button ID="Button1" Runat="server" Text="Unload AppDomain" OnClick="Button1_Click" />
<asp:Button ID="Button2" Runat="server" Text="Reset IIS" OnClick="Button2_Click" />
<asp:Button ID="Button3" Runat="server" Text="Kill ASP Worker Process" OnClick="Button3_Click" />
<script language="vb" runat="server">
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
HttpRuntime.UnloadAppDomain()
End Sub
Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim si As New ProcessStartInfo
si.FileName = "iisreset"
si.Arguments = ""
si.UseShellExecute = True
Dim prc As Process = Process.Start(si)
End Sub
Private Sub Button3_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim killer As New ArrayList
For Each p As Process In Diagnostics.Process.GetProcesses()
Dim processName As String = String.Empty
Try
processName = p.ProcessName
Catch ex As Exception
End Try
If (processName <> Nothing) Then
If ((String.Compare(processName, "w3wp", True) = 0) OrElse (String.Compare(processName, "aspnet_wp", True) = 0)) Then
killer.Add(p)
End If
End If
Next
For Each p As Process In killer
p.Kill()
Next
End Sub
</script>
</form>
</body>
</html>
Labels: ASP.Net, Programming, Technology, VB.Net, Web Development
?uestLove from the Roots created this survey, so the least I could do was take it.
| Songs In The Key Of Life (Childhood-Adulthood) |
| Song You Believe Your Parents Conceived You To: | Hank Williams - Are You Ready For Some Football? |
| Song That Best Makes The Soundtrack of Your Childhood Neighborhood Theme: | DJ Jazzy Jeff & The Fresh Prince - Summertime |
| The First Album You Ever Purchased: | 3rd Bass - The Cactus Album |
| The First Single You Ever Purchased: | Dr. Dre f. Snoop Doggy Dogg - Nuthin' But a G Thing |
| Song That Scared You In Your Childhood: | Michael Jackson - Thriller; Not so much the song, but the video |
| The TV Theme of Your Childhood: | Night Court |
| Favorite Song From Sesame Street: | 1, 2, 3...ah!ah!ah! (Is that really a song?) |
| Favorite Song From Mister Rodgers Neighborhood: | Would you like to be my neighbor? |
| Favorite Song From The Electric Company: | Never saw it, but Square One kicked ass! |
| What Were You Banned From Listening To In Your Childhood: | Not a damn thing |
| Rock Song That Rocked Ghetto/Ghetto Song That Rocked The Suburbs (as a kid): | Sir Mix-A-Lot - Baby Got Back, Warrant - Cherry Pie, Naughty By Nature - Hip Hop Hooray |
| Song You First Slow Dragged To: | Heatwave - Always and Forever; Oooh, flashback :) |
| First Cassette You Got For Your First Walkman: | DJ Jazzy Jeff & The Fresh Prince - Parents Just Don't Understand |
| Best Cosby Show Theme: | Bobby McFerrin, of course. With the tropical one a close second. |
| Favorite Soundtrack Of Youth: | Judgement Night: The Motion Picture Soundtrack; My first taste of Rap-Rock |
| Song That Played When You Got In Trouble And Grounded At Home: | Public Enemy - 911 Is A Joke |
| Song That Played When You Thought You Was About To Get Some: | Marvin Gaye - Let's Get It On |
| Song That Played When You Got Some: | Al Green - Let's Stay Together |
| The Theme To Your First Break Up In High School: | Mighty Mighty Bosstones - Where Did You Go? |
| The First Compact Disc You Ever Brought (not Album/Cassette): | Nirvana - Nevermind |
| Album That You Stole From A Friend: | MC Lyte - Eyes On This; sorry Wayne |
| Your Favorite Album You Think Your Friend Stole: | EPMD - Business As Usual; fuckers |
| If Ever In Car Accident....What Song Was Playing?: | Pearl Jam - Black; I avoid that shit like the plague |
| 5 Songs You'd Put On A Mixtape For A Potential Love One: | 311 - Love Song (The Cure Cover);Janet Jackson - That's The Way Love Goes;Robin Thicke - Lost Without U;Aretha Franklin - (You Make Me Feel Like) A Natural Woman;Common - GO |
| Song To Best Describe Your Best Relationship: | Heather Headley - He Is |
| Song To Best Describe Your Worst Breakup: | Three Days Grace - I Hate Everything About You; 'nuff said |
| First Concert You Ever Went To: | The Jacksons, Philadelphia 1985 |
| Magical Concert You Ever Went To: | The Roots, Electric Factory, New Year's Eve 2004; Got some ass from a chick at the show AND (later) this girl walking barefoot down Market Street in the rain at 3AM |
| Worst Concert You Ever Went To: | Free Toy Inside at Sapphire Beach Nightclub; Oh, wait...that was ME! |
| Coolest Celeb Ever Met: | Angelo Moore of Fishbone; didn't even know it was him until like an hour into the conversation |
| Assholish Celeb You Ever Met: | Howard Eskin; dick! (Although he's not really a celebrity then, is he? Just another asshole.) OK, Charles Barkley |
| Godlike Celeb You Ever Met: | George Clinton. "Smoke 'em if ya got 'em" |
| The US Weekly "Oh They Just Like Me!" Celeb You Ever Met: | Jill Scott; She's just so down to Earth, and a little goofy I might add ;) |
| Song So Hype You'd Run Your Moms Over With A Trash Truck Going 100 mph: | Today? Nas - Hip Hop Is Dead. Any other day? The Roots - The Seed 2.0/Melting Pot/Web (Live) |
| Song That Has The Ability To Make You Cry: | Alicia Keys - If I Ain't Got You |
| The One Song That Has The Ability To Make You A Kid Again: | Arrested Development - People Everyday |
| Song You Are Ashamed To Admit You Love: | Fleetwood Mac - Landslide |
| Song/Album That You Have To Gunpoint Others To: | Coldplay - A Rush of Blood to the Head |
| If You Were To Marry Now What Song Would Be Your Wedding Song?: | Bill Withers - Just the Two of Us |
| What Song Best Describes Your Children/Future Children?: | Black Eyed Peas - Where Is The Love? |
| Who Killed Music?: | P. Diddy |
| Who Keeps Music Alive For You?: | James Brown (RIP), The Roots, Common, Mos Def |
| Song Playing Right Now: | King Bongo - El Negro Bembón / Maquinolandera |
Take this survey | Find more surveys Bzoink - The Original Survey Site |
Labels: Music