Friday, May 18, 2007

RDP Console Session: Did You Know About It?

I continue to be surprised by how many IT professionals that depend on Remote Desktop to access servers for administration do not know about this:

For Windows 2003 servers, you can use the following:

START | RUN:

mstsc /v:whqs7610 /console

(without the “/console”, it just connects regularly.  With “/console”, you grab the actual console session, as if you were at the monitor and keyboard downstairs in the server room).

Out of the box, Windows Server 2003 provides two regular RDP sessions (for Administrators), plus the ability to connect to the actual console session.  So, in effect, there are now three RDP sessions available for use at the same time.

Here at my client site, it seems that multiple people will jump onto a server and then not logoff when they are done.  The two "free" RDP sessions then become occupied, not allowing anyone else to connect.

But, by connecting to the Console Session itself, you can logoff one (or both) of the regular sessions using the Terminal Services Manager application (Administrative Tools program group), and then reconnect not using the "/console" switch to grab a regular session.  (That is, we try to reserve the use of the Console session for "emergencies").

Wednesday, May 16, 2007

Party with Palermo: Tech Ed Style

I'll be there!

Website:  http://partywith.palermo.cc
June 3rd, 2007 @ 7PM - 11PM

Monday, May 14, 2007

VirtualPC Console Not Displaying

For the past several weeks, I've had a problem with VirtualPC.  Whenever I started the program, I would see it running in the taskbar, but the console itself would not show up on the screen.  Luckily, I could still start all of my VPC images using the context menu of the task item.

Today, I finally looked for a cause, and found it. 

VPC stored it's configuration in the following file:

%APPDATA%\Microsoft\Virtual PC\Options.xml

Within that XML file, I found the following node:


 

<window>
<console>
<height type="integer">246</height>
<left_position type="integer">4294935296</left_position>
<top_position type="integer">4294935296</top_position>
<visible type="boolean">true</visible>
<width type="integer">359</width>
</console>
<new_pc>
<left_position type="integer">449</left_position>
<top_position type="integer">329</top_position>
</new_pc>
<virtual_disk_wizard>
<left_position type="integer">727</left_position>
<top_position type="integer">184</top_position>
</virtual_disk_wizard>
</window>

Interesting to see the values that were being used for "left_position" and "top_position"... 


4,294,935,296 = 0xFFFF8300


Expressed as a 32-bit signed integer, this is the same as -32,000.  Doesn't tell me anything specific, but I found it interesting nonetheless.


Resetting these to 0 fixed the issue.

Monday, May 07, 2007

Day of .NET in Ann Arbor: RECAP

The Day of .NET in Ann Arbor 2007 Edition is over!  Like its predecessor last year, this event turned out to be very well received, and therefore, I think very successful.

The conference was again organized by three .NET user groups in this area: GANG, NWNUG, and AADND.  Specifically, the following people are who performed the day-to-day activities in bringing this event together:

  • John Hopkins (president of GANG): overall chairman of DoDN/AA 2007
  • Jason Follas (president of NWNUG): speaker/session coordinator
  • Darrell Hawley (program chair of AADND): registration coordinator
  • David Baldwin (AADND webmaster): sponsorship/public relations
  • Scott Zischerk (AADND): the DoDN webmaster (and T-Shirt designer)
  • Dave Redding (vice president of AADND): sponsorship
  • Chris Kotsis (secretary of GANG): sponsorship

The day of the event, we had some attendees who volunteered to help out with registration (and ended up missing the first session as a result).  Many thanks go to:

  • Dan Hounshell, Telligent
  • David Patow, Compuware

In all, we're pretty confident that there were actually 205 people in attendance!  This represents less than a 20% dropoff from our registration numbers.  For a free event like this, and for weather being as nice as it was, that is actually a great number (speaking from experience in having organized several events like this). 

However, we were anticipating a greater dropoff rate, and as a result, we ended up a little short on food at lunchtime.  Our sincere apologizes to anyone who might not have gotten any pizza, but we truly were trying to avoid last year's problem of having way too much food (which we even had a hard time trying to give it away to people passing by).  For full disclosure, we were anticipating the need to feed 180 people, not 205, to give you an idea of the challenge that we faced in trying to plan meals.

Another hiccup the day of the event was the fact that the campus facilities deactivated the air conditioning units in order to conserve energy (because WCC is in between semesters).  So, while there was airflow in the rooms, it wasn't necessarily "cool air".  The result was a very sauna-like experience while attending some of the sessions.  Let me just say that this very much took us by surprise as well!

We also considered people's feedback from the prior year, and tried to make little changes to improve on the experience this time around.  One thing that we tried hard to avoid was raffling off 100+ books during the closing.  So, we pre-selected book/software winners based on raffle tickets, and staged a giveaway in the hallway leading to the event. 

This actually worked well, but was not clearly communicated to all of the attendees as to how it worked (i.e., we didn't have enough books for everyone this year, so only the posted numbers were actual winners).  Also, we had unclaimed books when it came time to go into the closing session, so they were boxed up and left in the hallway in case someone came to us after the event to claim a winning prize.  To my surprise, all that was left afterwards were empty boxes, so even remaining valid winners were unable to claim their books.  I just hope that they went to good homes, and won't show up on eBay or Amazon.

Up to this point, I haven't heard anything negative about the Vendor Sessions that we inserted into the lineup.  I'm very much in agreement with the "Code Camp" mentality that our attendees shouldn't be over-marketed to by sponsors.  However, our sponsors are what make this level of event (which truly is a conference and not just a gathering of geeks who have nothing better to do) totally free to the attendees, so we have to show some love to them. 

In the past, I've often received inquiries from sponsors asking if they can have a breakout session to show off their products.  I've always had to deny such requests because I felt that sessions should be somewhat neutral in topic with concern to third-party products.  Otherwise, there might be a sense of mistrust by the attendees as to what the motives of the event organizers might be.

The Vendor Session, though, was the attempt to satisfy both worlds.  This was a dedicated timeslot where only vendors were presenting concurrently with one another.  The goal was to offer value-added sessions, and not just blind marketing, because session audiences would probably consist of current customers, or people who have already started researching the products.  These timeslots were also 1/2 the length of normal sessions, which helped to focus the presentations, and also helped to prevent boredom from developing in the audience.  More than anything else is the fact that there was no pretense involved: you knew going in that the content would be centered around a vendor's product.

The organizers will be having a post-mortem conference call tonight to discuss how we can improve upon this experience for next year's event.  If you happen to have any ideas, we would be glad to hear them!

Monday, April 30, 2007

TechEd 2007

Yup, I'm allowed to go again...

Thursday, April 26, 2007

IntelliSense for App.Config Stopped Working

Ugh!  I've wasted the past hour trying to figure out why I no longer had IntelliSense while hand-editing my App.Config file in Visual Studio 2005.

Among all of the noise from my search results, I found an old newsgroup post stating that the XML Schema file that VS2005 uses for .NET config files is kept at:

C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas\DotnetConfig.xsd

Hmm, I don't have that file.  Could it be that this was an old file used by a beta of VS2005, and that it's just not distributed in RTM?

I IM'd Dustin, and sure enough, he had that file on his machine.  So, something was not playing nice, and actually DELETED it from my machine.  The nerve!

My solution: Download a new one to that directory (there's an improved version here), and wouldn't you know: IntelliSense started working again!

Wednesday, April 25, 2007

Closures in SQL?

Through my daily blog reading, I came across this post making an argument for not using the SQL "IN" clause as a substitute for a JOIN.  I saw something familiar and interesting in one of the examples listed, and will try to demonstrate it here.

The right-hand side of an "IN" clause is simply a set of values.  This can be provided by means of a comma-separated list of literals, or by a SELECT statement.

To demonstrate the syntax, consider the following table:

DayVehicleMiles
MoBike50
TuCar85
WeTruck33
ThBike74
FrCar23

If I wanted only the miles for trips taken by Cars and Bikes, then I could provide those literals as:

SELECT Vehicle, Miles 
FROM TripLog
WHERE Vehicle IN ( 'Car', 'Bike' )


Or, I could store the values within fields of another table, and SELECT them (the caveat is that I can only select a single field in my subquery):


TypeMPGFuel
Car28.1Gasoline
Bike32.4Gasoline
Rocket Ship0.0000000421Hydrazine


SELECT Vehicle, 
Miles
FROM TripLog
WHERE Vehicle IN ( SELECT Type
FROM PreferredVehicle )


The point that the other blogger was trying to make was that you might just want to use a simple INNER JOIN.  But, I'm not here to argue that point.  Instead, I'd like to expand on a path that he just touched on in a counter example.


Suppose that I mistyped the subquery used in the "IN" clause, and used "Vehicle" instead of "Type" for the selected column:


SELECT  Vehicle,
Miles
FROM TripLog
WHERE Vehicle IN ( SELECT Vehicle
FROM PreferredVehicle )


The result is that I would get all rows returned, including the one for "Truck".  This is despite the fact that there is no column in [PreferredVehicle] called "Vehicle", and that "Truck" doesn't appear anywhere in the [PreferredVehicle] table.  Why?


Let's first look at another query that sort of demonstrates what is happening:


SELECT  'Car'
FROM PreferredVehicle


The result is that you'll get one row returned in the resultset for every row in the table, with each returned row containing only the value "Car".  This is because a SELECT FROM query evaluates for every row in the FROM clause (filtered by a WHERE clause, if present). And, since we're only selecting a literal string and no other fields from the table, then the output will however many rows there are in [PreferredVehicle] with each row containing only that string value.  Simple, right?


But how does this explain why all rows were returned when the subquery used a column name that doesn't even exist in the subquery's table?


From the language point of view, the subquery from the "IN" clause is executing within the context of the outer query.  An interesting side effect is that the subquery has access to all of the "locals" in the outer query.  That is, if you think of this executing row by row, then think of the subquery having access to the columns in each row returned by the outer query.  That is, you have a Closure! Sort of... (Since you can think of the subquery as being sort of like an anonymous function defined within another function)


So, if you're still imagining this row-by-row evaluation of the subquery, then you can see how the "Vehicle" from each row in the outer query is simply selected as the output of the subquery -- much like when the literal string was used.  And, because the "Vehicle" from the row of the outer query matches a value in the set returned from the subquery (it actually matches every value in the set that is returned for that row), then that WHERE clause predicate is satisfied, and the row from the outer query is returned. 

"Truck" is in the set ["Truck", "Truck", "Truck"]
"Car" is in the set ["Car", "Car", "Car"], etc, etc. 


As a developer, knowing and exploiting this behavior will likely scare the hell out of your DBA's if and when they perform code reviews.  But, it also allows you to do some "elegant" things in your code.  And some unexpected things, too, if you're not careful.


For example, let's try to select [TripLog] entries for vehicle types where I was able to drive at least one day for under $5.00.  I'll use an amazingly cheap current gasoline price of $2.90 per gallon in this calculation, grabbing the Miles from the [TripLog] row, and the MPG from the [PreferredVehicle] table.


You would think that the following query would do the job of building a set of Vehicle Types that match our criteria, and then using that set as the right-hand side of the "IN" clause.


SELECT  Vehicle, Day
FROM TripLog
WHERE Vehicle IN ( SELECT Type
FROM PreferredVehicle
WHERE ( 2.90 * Miles / MPG ) < 5.00 )


As such, I would expect the query to output the following:


Mo     Bike     50
Tu Car 85
Th Bike 74
Fr Car 23

because both Bike and Car have days where the cost of the trip were under $5.00, so therefore, I would think that all Bike and Car rows should be returned.  Truck is not in [PreferredVehicle], so, it would not be returned.


However, here is the actual output:


Mo     Bike     50
Fr Car 23


Yes, I got the rows where the trip price was under $5.00.  But, the query actually filtered out all rows where the price exceeded $5.00. 


That certainly doesn't seem correct from a set-based point of view, but is very consistent to a Closure-based point of view.  When evaluated row-by-row, the [TripLog] entries with too many miles will fail the "IN" clause test, and will therefore, not be included in the output.


In reality, the results are exactly the same as if we had used an INNER JOIN with a WHERE clause:


SELECT  Day,
Vehicle,
Miles
FROM TripLog AS TL
JOIN PreferredVehicle AS PV
ON TL.Vehicle = PV.Type
WHERE ( 2.90 * TL.Miles / PV.MPG ) < 5.00


But, the execution plans are different.  In fact, despite all of the negative comments said about using INNER JOINs versus IN clauses, the "Closure" version is less than half the cost of the JOIN/WHERE version of the query...  which totally surprised me.


queryplans


Closures in SQL... Who knew!!??!

Monday, April 09, 2007

Level 70

We spent the holiday weekend at my parent's place in Louisville, KY.  Because a certain Dwarf Paladin (a.k.a., my wife) permitted me to play a little more than usual, I was able to finally knock out the last level of WoW-TBC...

70!

You know what? There were no balloons or confetti falling from the sky, no fireworks, no noisemakers, no "Welcome to the 70-Club" tells sent by Blizzard, and not even a "grats" whispered by anyone online (not for a few hours after the fact, at least).  Kind of anti-climactic, eh?

Now I can resume my normal life....  Yeah, right!  This just means that the experience known as EGC (End Game Content) is just beginning.

Monday, April 02, 2007

ZMachine.NET Moved to CodePlex

With the eminent shutdown of GotDotNet, I have created a CodePlex workspace to serve as the home of the ZMachine.NET project:

http://www.codeplex.com/zmachine

With any luck, I'll have a chance soon to breathe some new life into this dormant project (and finally add the V5 support that people keep asking for).

Thursday, March 29, 2007

Impromptu Channel 9 Videos

Scott Hanselman and Rory Blyth going into a random office in Building 42 and letting the camera roll: it could have turned into a disaster, but what happened was that they stumbled into Polita Paulus's office, and discovered the developer who created the ASP.NET GridView and ObjectDataSource controls (as well as BLINQ)!!!

http://channel9.msdn.com/showpost.aspx?postid=295919

(This one's well worth watching: just under 15 minutes)

Of course, about 1/2 way through the video, I was screaming at Scott and Rory to go across the hall and talk to the guy that wrote the XmlDataSource and find out why there's no Namespace support (Scott even brought that up in the video)

Friday, March 16, 2007

It Talks!

Almost two years ago, I threw together an interpreter for the Infocom Z-Machine using C#.  This was actually an exercise that I used while teaching myself the internals of the Z-Machine itself.  I've said it before in this blog, but in my opinion, the single best way for a high-level language developer (like myself) to learn the low-level aspects of a particular machine architecture (be it a Z80, 6802, Atmel AVR, PIC, Z-Machine, etc), is to write an emulator to run the native code bytes.  Once you've gone through that exercise (especially the debugging process), you pretty much know exactly how each opcode works.

I've pulled out this Z-Machine library a couple of times when I wanted to test the capabilities of a particular technology.  For instance, when I wanted to see what SQLCLR could/could not do, I created a stored procedure interface to my library, and was able to play Zork completely on the database server itself (it turns out that you can do a lot using SQLCLR if you wanted to).

Last year, I plopped the source code into a GotDotNet workspace, and pretty much forgot about it.  Until yesterday when James Ashley from the Atlanta area emailed me to let me know about a little project of his that he is working on.

It turns out that James is really into SAPI (much like an INETA speaker from my area, Martin L. Shoemaker), and was able to create a System.Speech-based interface into my Z-Machine library.  What a great demo of the SAPI capabilities of the .NET Framework v3.0 by playing a text adventure game using only your computer's speakers and a microphone!

UPDATE: James' article can be found here: http://www.codeproject.com/useritems/SAPISophia.asp

Thursday, March 15, 2007

Day of .NET Blog Badges

Scott Zischerk, the guy behind the fantastic looking Day of .NET in Ann Arbor website, has created a couple of badges that you can post on your blogs!

Day of .Net May 5, 2007 - I'll be there!

Day of .Net May 5, 2007 - I'll be there!

HTML code is available at: http://www.dayofdotnet.org/badges.aspx

Wednesday, March 14, 2007

Great Bill Gates Story

Lorin Thwaits tells a great story about asking Bill Gates a question this week at the MVP Summit.

I won't spoil it with details, but give it a read!

Tuesday, March 06, 2007

Day of .NET in Ann Arbor: Postponed 1 Week

Due to some previously unforeseen coincidental events taking place on April 28th, we have decided that the Day of .NET in Ann Arbor conference had to be postponed one week.  Otherwise, there would just not be any lodging available within a 40+ mile radius of Ann Arbor.

So, cross off the previously reserved date, and create a new entry in your calendar for MAY 5, 2007. 

Also, if you have the means, then please help to spread the word that the Day of .NET in Ann Arbor conference is now being held on MAY 5, 2007.  All other details remain the same.

Thanks!

Saturday, March 03, 2007

My Programmer Personality

I saw this on Keith's blog, so I had to do it too.... It's kind of like the Myers-Briggs personality test, but for programmers (and not as in depth). (For the curious, my MBTI is INTP...)

From http://www.doolwind.com/index.php?page=11, I am being told:

Your programmer personality type is: DHSB

You're a Doer.
You are very quick at getting tasks done. You believe the outcome is the most important part of a task and the faster you can reach that outcome the better. After all, time is money.

You like coding at a High level.
The world is made up of objects and components, you should create your programs in the same way.

You work best in a Solo situation.
The best way to program is by yourself. There's no communication problems, you know every part of the code allowing you to write the best programs possible.

You are a liBeral programmer.
Programming is a complex task and you should use white space and comments as freely as possible to help simplify the task. We're not writing on paper anymore so we can take up as much room as we need.

Memorabilia

One of my readers (we'll call her Mom, because that's her name) sent me this photo today:



This was the first "PC" in my house growing up, speaking specifically of IBM-compatible machines. My house had always had a computer in one form or another, from TRS-80's to a Commodore VIC-20 and the Commodore 64. This is the machine that took over the main computing needs of the family at the tail end of the C-64 days (my late high school days, if I recall).

Notice the important details though:

  • This 286 had the spiral phone cord-like keyboard cable. They just don't make them like that anymore!
  • The mouse has a definite home in its holder affixed to the case. I don't know how many times today that I wish I had a place to put my mouse when I'm done using it.
  • Speaking of the mouse, I don't know if you can make it out, but there's a mousepad there with gridlines on it. You know, for when you need the highest precision in mouse usage, or so that you can pretend that you're at a CAD workstation or something.
  • Even in the days of this 286, there was a format war going on between 3.5" floppies and 5.25" floppies. Thankfully, this computer could handle both. Imagine if it only had a 3.5" drive: those disks in the cases to the right wouldn't work, and I bet inside of those cases were copies of MS-DOS 4.01. (Do they even sell computers with floppy drives these days?)
  • There's no Windows keys on that keyboard. No sir, they didn't exist back then. I don't even think that we would have seen a pirated copy of Windows 3.1 for a few more years, and by that time, I think that this particular machine was in retirement.
  • There are no speakers because... well, there was no sound card in this thing. And no CD-ROM drive because if they were out, then they probably cost as much as this computer.
  • And, lastly, there's the ever-important beer can lamp that I think my younger brother made in shop class.

Friday, March 02, 2007

Still using Data Dude... Still not "Wow'd"

I'm forcing myself to use VSTEDP for my current project, which involves making a wide variety of changes to an existing database schema in order to support new functionality required by my web application.  Hopefully, I'll have a seemless deployment of the changes into production when the time comes (holding breath).  I mean, that is one of the advertised benefits...

What I like is visibility into any breaking changes.  "Data Dude" does all of the dependency checking for me, and will create errors in the Visual Studio task list if a change breaks other objects.

What I dislike is how painful it is to actually make the changes using VSTEDP itself. 

Come on, guys.  Visual Studio is known for being more than just a text editor.  Microsoft is known for providing great GUI database tools in addition to just "Query Analyzer" functionality.  IMHO, you shouldn't have released "Data Dude" without the same level of database editing support that Visual Studio itself supports against live databases. 

Am I just using the product incorrectly, or coming into it with way too much expectation? 

The only solution that I found was that I could make changes to a live (development) database and then use the schema compare functionality in order to capture the deltas.  This seems to work, and allows me to use tools that I'm already familiary with.  I would just have preferred to do everything against my "one version of the truth" right in the tool itself.  Not to mention that if I were actually in a "team" environment, then this solution does not provide a very solid way to prevent people's changes from stepping on each other.

Wednesday, February 28, 2007

Congratulations Drew!

This is actually old news, I guess, since the email arrived yesterday... But, I've been in training this week, and just checked my work email this evening and saw the notice from Drew Robbins that stated:

Toshinori Robbins was born at 8:07a on 2/27. He weighs in at 7lbs 1oz and
is 20 inches long. Mother and baby are doing well. However, I’m still pale in
the face after leaving the room twice during delivery. ;-)

Congratulations Drew and family!

Monday, February 26, 2007

Podcast: WebDevRadio

I met Michael Kimsal at CodeMash this year, thanks to a casual introduction through Keith Elder.  I didn't know at the time, chiefly because it wasn't specifically mentioned, but Michael has a podcast called "WebDevRadio".

He recently interviewed a few friends of mine, and fellow user group leaders from southwestern Ohio: Jim Holmes and James Avery, authors of Windows Developer Power Tools. 

http://www.webdevradio.com/index.php?id=44

 I'm listening now, and it's actually a great interview (/grin)! 

Friday, February 23, 2007

Finally Using "Data Dude"

Microsoft Visual Studio Team Edition for Database Professionals:

I've had it installed ever since the product RTM, but up to this point, I have resisted using it to actually manage my database projects.  But, today, I decided to bite the bullet and see exactly what it could do for me.

Ever since I saw the first demos at TechEd, I've been a fan of the features of VSTEDP.  Especially appealing to me is having full source control around every single database object, as well as the refactoring capabilities like renaming a table or column and have every reference (i.e., in views and stored procedures) also change to reflect the new name.  I imagine that deploying a schema change will be a delight, but truthfully, I haven't gotten that far yet (this is a real SQL 2000-based project that I'm working on, btw).

In fact, VSTEDP appears to be the first "Team Edition" SKU that adds value to Visual Studio that even a small ISV can take advantage of right out of the box.  I'm not easily impressed by the functionality of the other VSTE SKUs.

Despite all that it is, "Data Dude" apparently does not include all of the functionality that you are used to for managing live databases using Management Studio, or even Visual Studio's Server Explorer for that matter. 

My case-in-point for today's experience is the fact that everything in VSTEDP appears to be SQL-only.  There's no graphical capabilities for editing tables or relationships (Table Designer), etc.  Everything that you do (aside from the Rename Refactoring, as it would appear) results in a DDL script appearing in a code editing window.  Heck, even clicking on a Column name in Schema View doesn't let you edit any of the properties that show up in the Property list.

For what it's worth, I'm not DDL-dumb.  But, by the same token, I've gotten used to using the Table Designer to do my work, since I've been doing this using SEM since SQL 7.  I just shouldn't need to abandon that design paradigm in order to take advantage of "Data Dude's" useful features.