Wednesday, December 22, 2004
Some handy registry hacks
I found this handy link on Dave Wanta's blog regarding registry hacks. I especially love the command line autocomplete registry hack.
I've recently adopted Subversion as my primary version control system, and have found that the command line is the best and only way to go. Having autocomplete at the command line is extremely handy.
Thursday, December 02, 2004
Buying a house in Toronto - Part IV
Wow, part IV, like it's "A New Hope" or something...
So with offer in the works, our agents worked furiously trying to contact the seller's agent and to setup a face-to-face presentation of the offer. The idea is that it's harder to laugh in someone's face than it is to a piece of paper.
Once the offer is set into place, if accepted, we only have five days to get everything sorted out: financing, insurance, lawyers, house inspection, etc. So we spent most of the day trying to get a jump on all that paper work.
Our agents managed to co-ordinate a face-to-face meeting for around 7:30... so the plan was to meet a nearby restaurant, sign some more formalized documents (a zillion times times four), and then have dinner while they negotiated. However, when we arrived at the restaurant, the seller couldn't contact his wife in time, and she went somewhere with their kids for a few hours. Since they both owned the house, they both needed to be there. She wasn't expected home until around 9:30. All this meant was that our pins-and-needles tension would only be dragged out longer than we expected. We had dinner, went home and sat by the phone and waited.
Around 10pm, the phone rang. There were a couple things that had to be hammered out, ranging from the price to the alarm system. They had come down a little bit in the price, which was expected. Interestingly, they were waiting to sell the house before they started looking for a new home -- so they wanted additional time on the closing date. As first time house buyers, this was to our advantage.
Now the ball was in our court; we only had an hour to decide. We could come up as much as they had come down, and that could go two ways: we would probably have another round of back-n-forth, or it would piss 'em off and they'd refuse our counter-offer. If we could pick the right psychological number, they'd be more inclined.
We came up to the lower half of the halfway point, pushed the closing date out.... and waited for our agents to call us back.
Around 11:30, the phone rang again, the offer had been accepted. According to our agents, the husband wanted to sell the house and his wife didn't. They hadn't begun to look for a house yet, and were waiting to see if they could sell the house before Christmas. As soon as the offer was accepted, she went white as a ghost and began to ball her eyes out.
The only thing left was the house-inspection...
Buying a house in Toronto - Part III
As we returned to the city from our weekend getaway, we decided to take another route and do a drive by on the semi to get a better feel for the surrounding neighbourhood. Turns out, there were several more houses for sale in the general area.
When our Agent called us the following afternoon, they had already looked at eight other homes that were listed. "Zero for Eight" -- all weren't even worth looking at. So we gave our agent the list of additional homes we looked at, and they went to work trying to set up appointments. Since the houses were in the same neighbourhood, we'd start at the semi and go from there.
The asking price for the semi was higher than the farm house, but after taking a long second look, Lori didn't want to look any further. Although slightly smaller in size, it would not require any rennovations whatsoever and it had a spacious garage connected to a shared laneway.
So we stopped, and decided to find a place to talk about it. We somehow found ourselves at the scummiest coffee shop in the seediest area. The working girls and drug dealers turned tricks while we sat inside and talked. We found out later that a new shopping mall with a more reputable coffee shop had plenty of room only a few blocks in the other direction. Oddly enough it didn't bother us.
After some long discussions, my reservations with the place were put to bed, and we decided to put in an offer. It's funny how my negatives about the house seemed to disappear when we spoke of putting the offer in nearly 18K below their asking price.
In Toronto, most of the houses sell well over the asking price, and that's mainly because of bidding wars, etc. However, this time of year is the best time to look mainly because no one wants to look / move / sell during Christmas, and in some cases, the market drops dead around Christmas and starts to pick up again around February. Once February rolls around, the prices start to inflate dramatically. So it was now or never.
We put together the offer, listing all the items that would be included and excluded in the house, and any addtional conditions we could think of. Then we had to initial the documents in about a zillion places. We took a risk and decided to make our offer below asking price, and so that the seller wouldn't get pissed off, we took the appliances out of the offer.
... we were sold, but the question on would the seller agree to our conditions?
Wednesday, December 01, 2004
Buying a house in Toronto - Part II
After a few weeks of driving around and getting a feel for price ranges for neighbourhoods, we called up the Agents we worked with last year. They're a husband and wife sales team, great people, and parents of a friend at work.
The tag team duo works well because they split up in the mornings to cover more ground. By mid-afternoon, they've narrowed the search down to a few good candidates.
There's a whole range of emotions that you go through with each house, and each one is wildly different. On the outside, some look like solid homes with lots of potential, but the inside fill you with terror that they'll collapse at any second. But the personal favourite are the houses that have that 15 degree slant to them, and the brand new kitchen they've installed to distract you from the slant has been custom fit on that angle.
What we didn't expect, was that we would find a house we liked on the first night out. In fact, it was the second house we looked at. It was a detached three bedroom with formal dining and living rooms and finished basement, built in 1913. It had amazing character, completely rennovated to retain the original charm of the home and within our price range. Only drawback: it was a bit further north than we were accustomed to, in a neighbourhood we weren't crazy about, and no parking.
Everything we looked at after that, was compared to this home. We went back for a second look, and aside from the neighborhood, we were sold.
Another house, a few blocks south, was the complete opposite in character and charm. It was probably 65 years old but the owner worked in construction. He had spent the last 13 years rebuilding the house from the inside out, and had furnished it with top of line everything. On top of having a laneway in the back, he had build a two car garage with ten foot ceilings-- an oddity in the Toronto market. The craziest part of the house was the fact that the current owner's tastes were ... how to put it... ok, awful. The house was uncomfortablely crammed with tasteless junk, almost garish, and it made it difficult to see the value in the home.
A few days later, convinced we were interested in the old farm house, we took the Friday off and spent the morning driving around in the neighbourhood. There's lots of construction in the neighbourhood, new condos and townhomes going in -- the neighbourhood is sure to change over the next five years, but still, we weren't convinced. Lori wants to have kids, and she couldn't picture herself taking the stroller out by herself.
We were out of town for the weekend, and gave us some time to think about it. The more we thought about it, the old farm house would eventually need work, and somethings just weren't going to change....
... could we trade the warm detached farm house filled with books and landscaped perrenial gardens for the garrishly decorated semi (complete with disco ball) and two car garage?
Buying a house in Toronto - Part I
Last year, after the initial fuss of our engagement had settled down, Lori and I decided to buy a house. As house prices are high, the price tag of a wedding and a house purchase seemed prohibitive, so we thought we might buy a house and throw the wedding there.
It didn't take long for our optimism to fade, and we quickly became very discouraged. Discouraged doesn't come close to describing how messed up buying a house in the city actually is.
So the dilemma is: do you buy a house in the city and pay through the nose; or do you save your money and buy a house outside of the city and spend all your free time commuting. Personally, I enjoy sleep too much to have to get up early to take commuter trains, and I love the fact that TTC allows me to come and go from work to home as I please.
Buying a house in the downtown area borders on madness. The houses you can afford either have three kitchens in them and require major renovation to make the space livable, or they are so small that it would be a complete change in lifestyle. Finding a balance between them is difficult, and often is a matter of timing more than anything.
The problem Lori and I currently have, is that the neighbourhood and apartment we're currently in is amazing. Well, at least we think it's amazing -- we may look back years from now and have a good laugh at it. In short though, we're in an $800K home in a $800K neighbourhood. Anything that we move to will be a step down: two bedrooms, two dens, two bathrooms, large spacious kitchen, large master bedroom, patio, backyard, private parking, all utilities included and about 100 feet from transit.
We really wanted to buy a home in our neighbourhood, so postponing the purchase allowed us to save a bit more for a down payment.
So, a few weeks ago we started up the house hunt again. This time, we spent a couple weekends driving around, trying to get a feel for the surrounding neighbourhoods. We saw lots of listings in our area, and we looked them up on MLS, but quickly discovered that even the smallest dumps in our area were beyond our price range, and if we could afford it, we'd be burying ourselves so far under that our lifestyle would exist to support the house.
We made a trip out to the east end of the city, which is popular for first time home buyers. The east end of the city is completely foreign to us, and to make matters worse we were driving around the east-end on a weekend that the Don Valley Parkway was closed for maintenance. We spent nearly an hour on Queen St East, and got a really good whiff of the garbage processing plant. Unfortunately for the east end, we resolved that we were not east end people, despite how pleasant everyone makes it sound.
We decided to focus our search in the west end of the city, just outside of the downtown core. We expanded our search area to our surrounding neighbourhoods, compromising on the location for price.
.....
Tuesday, November 09, 2004
Halo 2 and FireFox released today...
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.
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:
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:
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
- Create a "Web" folder in your project
- Configure the Output Path of your project to build to "Web\bin"
- In the debug settings, set Enable ASP.NET Debugging to "True"
- Change the Debug Mode of the project to "URL"
- Set the Start URL to the name of the local IIS site that this code will execute under.
- Add System.Web.dll as a reference to your project.
- Create the new site in IIS.
Enjoy!
I've got a few other Visual Studio tweaks that I hope to post soon.
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.