Tuesday, November 09, 2004

Hard drive on the fritz

Problems with my PC, yet again, seems like any time I want to do anything productive, I have to rebuild my computer first... This time it's either the SATA 120GB Western Digital hard-drive or the Promise SATA 150TX2Plus Serial ATA Controller card. I've had them for about 4 months, and haven't suspected anything wrong... Clearly, I have problems with the HD: files appear to be corrupted, and about every other boot XP decides to scan the disk and correct problems with invalid entries in indexes, corrupted attributes, orphaned files. Each time it tries to resolve problems, more files appear to become corrupted. My data drive and OS are installed on the same physical drive, but on different partitions. The problem is spanned across both partitions. Last night, the system became completely unbootable. In Safe Mode, CHKSDK produced the "This volume has one or more unrecoverable problems" error. I reinstalled the OS on the same partition without formatting (I needed some data off that drive) I'll try to back up my data drive, purging old data as I go and then do a full format of the drive. I've also noticed that newer drivers are available for the SATA Controller card, which are digitally signed: the version I'm currently using is not. I left the house this morning with a disk diagnostic running -- it should be done by the time I get home. If the drive checks out fine, then I'm going to blame the SATA controller. The irony of this is -- about two months ago, I gave my mother my perfectly good 40Gb Western Digital DMA/133 drive. Hopefully I can get things back up and running without having to buy an external drive or something.

Sunday, November 07, 2004

Relationship between Page and Page Directives

Another adventure into .net... The other day I had a problem where I wanted to create a property for a page, and have it configurable within the designer. To me, this seemed like it should be fairly easy to do, after all I can create a public property for a user control, and then set it in the designer like an attribute:

 < ... runat="server" property="value"/> 
But you can't simply add a custom value in the page directives:
<%@ Page Language="C#" MyPageProperty="value" %>
... you'll end up with an error. So it got me thinking, what is the relationship between Page and Page Directives, and why do I get this error? Enter Reflector. I've grown quite fond of this utility, and I've found it indispensible for inspecting code. Reflector allows you to crack open the internals of the core .net framework, and examine how Microsoft put the framework together. The best place to start is at the machine.config. It tells us that all requests for aspx pages are piped through the PageHandlerFactory. Using Reflector, we quickly see that the factory's main job is to create the handler and pass it off for execution (though we don't really need Reflector to tell us that, if you're familiar with design patterns -- that is what a Factory does). The actual creation of the handler is performed by the PageParser class, specifically the GetCompiledPageInstance method Looking at the PageParser through Reflector is like a good mystery novel, as it's quite complex, and uses a quite a variety of other classes to perform it's job. Most .net developers understand that the first time a page is requested, the asp.net worker process compiles the page and caches it so that future requests will take less time -- this is accomplished through the PageParser. As it turns out, the directives for the Page are used as settings for the PageParser, they get converted using Regular Expressions into a Dictionary object, then processed through the PageParser's ProcessMainDirective method. As the items in the directive are parsed, they are popped off the Dictionary. Afterwards, the CheckUnknownDirectiveAttributes method inspects the size of the Dictionary, and if it contains values it throws the error. If you're still reading, very good, or if you got excited and tried to create a derived class of the PageParser you've already discovered that all of these methods I've described are marked as internal and cannot be overridden. Few things this inspires me to do: 1) Hunt down and find all dependencies to the PageParser, decompile and create a custom PageHandlerFactory. 2) Take a peek at the ASP.NET 2.0 model and see how this has changed.

submit to reddit

Thursday, November 04, 2004

ASP.NET Applications without Web Projects

Super handy link: this article shows you how to hack Visual Studio's config files and projects so that you can create web projects as class libraries. Although Fritz Onion gives a pretty good overview, you still need to rummage through the config files. For your convienence, here is the contents of my config file: C:\Program Files\Microsoft Visual Studio .NET 2003\VC#\ CSharpProjectItems\LocalProjectItems:

UI{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#233610
Code{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#233820
Data{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#233430
Web{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#233740
Utility{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#233550
Resources{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#236260
..\CSharpAddWebFormWiz.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#223610#2263{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45340WebForm.aspx
..\CSharpAddWebServiceWiz.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#224320#2266{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45210Service.asmx
..\CSharpAddMobileWebFormWiz.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#239825#2399{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45710MobileWebForm.aspx
..\CSharpAddWinFormWiz.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#223710#2264{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45350Form.cs
..\CSharpAddClassWiz.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#224520#2262{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45150Class.cs
..\CSharpAddComponentWiz.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#224630#2265{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45170Component.cs
..\CSharpAddWebDataForm.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#238045#2381{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45590DataForm.aspx
..\CSharpAddUserControlWiz.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#229540#2296{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45320UserControl.cs
..\CSharpAddWinDataForm.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#238045#2382{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45600DataForm.cs
..\CSharpAddDataSet.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#227750#2278{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45220Dataset.xsd
..\NewXMLPage.xml{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#224460#2279{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45240XMLFile.xml
..\CSharpAddXMLSchema.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#227570#2276{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45230XMLSchema.xsd
..\NewCSharpFile.cs{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#226180#2267{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45160CodeFile.cs
..\CSharpAddCustomControlWiz.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#229390#2294{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45270CustomControl.cs
..\NewHTMPage.htm{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2042100#2280{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45280HTMLPage.htm
..\CSFormInheritanceWizard.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2341110#2343{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}4531 Form.cs
..\CSharpAddWebControlWiz.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2297120#2298{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45330WebCustomControl.cs
..\CSControlInheritanceWizard.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2342130#2344{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}4530 UserControl.cs
..\CSharpAddWinServiceWiz.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2291140#2292{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45200Service.cs
..\CSharpAddWebUserControl.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#237855#2379{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45580WebUserControl.ascx
..\CSharpAddMobileWebUserControl.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#240056#2401{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45720MobileWebUserControl.ascx
..\StaticDisco.disco{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2393155#2394{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45250Disco.disco
..\CSharpAddGlobalASAX.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2304160#2305{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45428192Global.asax
..\CSharpAddWebConfig.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2312170#2313{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45458192Web.config
..\TextFile.txt{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2316150#2317{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45360TextFile.txt
..\Frameset.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2241160#2284{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45410Frameset.htm
..\XSLTFile.xslt{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2356170#2357{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}4566 XSLTFile.xslt
..\StyleSheet.css{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2314180#2315{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45440StyleSheet.css
..\NewInstaller.vsz{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2269190#2270{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45180Installer.cs
..\Bitmap.bmp{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2384200#2385{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}4562 Bitmap.bmp
..\Cursor.cur{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2386210#2387{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}4563 Cursor.cur
..\Icon.ico{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2388220#2389{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}4564 Icon.ico
..\Resource.resx{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2390230#2391{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}4565 Resource.resx
..\JScript.js{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2306240#2307{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45570JScript.js
..\VBScript.vbs{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2308250#2309{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45370VBScript.vbs
..\WindowsScriptHost.wsf{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2310260#2311{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}45380WinScript.wsf
..\app.config{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}#2403261#2404{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}46000App.config
Once you've made this hack, you'll be able to add webforms (and other web project items) to your class library. I find it's very useful to configure your new hybrid projects this way:
  1. Create a "Web" folder in your project
  2. Configure the Output Path of your project to build to "Web\bin"
  3. In the debug settings, set Enable ASP.NET Debugging to "True"
  4. Change the Debug Mode of the project to "URL"
  5. Set the Start URL to the name of the local IIS site that this code will execute under.
  6. Add System.Web.dll as a reference to your project.
  7. Create the new site in IIS.

Enjoy!

I've got a few other Visual Studio tweaks that I hope to post soon.

submit to reddit

Saturday, October 30, 2004

"Start"

Wishing that I had a better excuse as to why I haven't already, I decided that it was about time that I started this. I've been planning on building my own site, blog included, for months now but that hasn't really materialized. Perhaps I'll get on that soon, and perhaps this blog will serve as motivation to get that started. So if you happen upon this post months from now and it's still hosted here, please flame me. At any rate, I hope this place will serve as a placeholder for my random thoughts and observations on a variety of topics. What those topics should be, I don't know yet, so I guess they'll define themselves as I go... But I suppose the first post should contain some form of introduction: I'm Bryan. I'm a 30 something, recently happily married computer geek living in Toronto, Ontario. I work for one of Canada's fastest growing interactive digital agencies where I spend most of my days working out the technical details or writing code for mid to large size projects. I'm an avid movie watcher and amateur critic. Since I originally went to school for Music, I guess I could say I'm a retired musicologist, but it would be more accurate to say I dropped out to become a starving artist until I eventually came to my senses and cashed in on my passion and talent in the computer industry. The poignant "Start" title is a reference to an oldie-but-a-goodie favourite of mine -- Soul Coughing's Janine. If you haven't heard it, it was the band's first commercial success, and it seems a suitable starting point. The beginning of the song uses a cold, clear voice of an answering machine that states the command, "Start". What has endured me to this song is the background track: a girl singing a barely audible, open-ended lullaby of no fixed key into an answering machine; her song rambles, punctuated by the beeps of the machine. Two things I have often wondered about this song: 1) what would inspire someone to do this, and 2) what the reaction would be of those who found the recorded messages. I can only imagine that the listener had a series of reactions: initial confusion, recognition, laughter, hysterics, and finally -- inspiration to write a song about it. If the voice on the answering machine tape is Janine, this may explain the lyric, "Janine, Janine, Janine ... I drink you up." While this post may not be the inspiration for commercial success elsewhere (or in case it does, please link back to this post), it represents the blinking light of the answering machine: a world of unknown possibilities ready to unfold itself at the touch of a button.