Scott Hanselman

UltraMagnifier

January 26, '04 Comments [1] Posted in Programming
Sponsored By

I'm a huge fan of Zoomin, and have promoted it before on my site and I use it ALL THE TIME in Presentations.  Bryan Ressler sent me a link to his UltraMagnifier .

Some features:

  • 1, 2, 4, 8, 16, or 32-times magnification
  • Full multiple-monitor support
  • Gridding of pixels (to facilitate counting pixels or checking alignment) in white, black, gray, or any user-defined color
  • Update on a timer, on mouse movement, freeze, and timed-freeze modes
  • Pixel-color display with choice of display formats (and color swatch)
  • Save magnified image as BMP or PNG
  • Copy magnified image to clipboard
  • Printing with Print Preview
  • Window features such as Stick to Screen Edges, Stay on Top

It's got everything that Zoomin has, and more!  Very nice.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Moving life into CVS and DocumentLocator and the Authoritative Source

January 26, '04 Comments [3] Posted in Africa | Bugs | Tools
Sponsored By

I need an Authoritative Source

You know I picked up a TabletPC recently.  I will probably attend the North Africa Developer Conference in Morocco this year and I wanted to bring my TabletPC rather than my Corporate Laptop.  It's a lot lighter (6 lbs vs. 11 lbs) and the batteries last forever (at least 6 hours versus barely 2).  It is a 1.5 GHz box, while my Corporate Evo N800w is a 2 Ghz.  We'll see if that really makes a difference.

Anyway, I sat down and prepared to move all my presentations and demos and C:/Utils over to the laptop.  It's about 2 gigs of Powerpoints, demos, code, and goodness.  If you've seen one of my presentations when I'm particularly hopped up on Diet Coke, you know I use most of it! :)  So, I made a C:\demos folder and started a copy. 

Then, I stopped.  What the heck am I doing?  If I copy this stuff straight, I'll have demos/presentations/code on three machines (my desktop as well).  Every once in a while I make an important change to a PowerPoint, or find a major bug in some demo. 

So, I said, it's time to move some of my life into An Authoritative Source (ne: Source Control).  Less for the version control and more to define and authoritative source for information that I can pull from.

Tangent: My Contacts

I recently installed Plaxo in an attempt to bring some semblance of organization to my information-life.  It provides, for all intents, a location for all your contacts that can sync to Outlook or Outlook Express on other machines.  It provides:

  • Conflict Resolution and Synchronization - Changes made by me/Changes made by others
  • Storage - I can install it on a new machine and bring my contacts down immediately.
  • File System Independance - I can bring it down into multiple clients without concern over file system (or application)
And that's exactly the kind of problems that need solving for my presentations and demos.
Back to the Story:
 
I have used Source Safe since before it was owned by Microsoft (Remember One Tree Software) and I've used various *nix source control systems.  But, I hate it.  Between Data Corruption and the general malaise I feel when I use it, it wasn't an option for my personal data.  Not to mention the whole "make writable" nonsense.   I'd prefer my personal files be writable be default, thank you very much.
 
I really dig what the SourceGear Guys are doing with Vault, but I'm a little nervous putting my data in a Database.  It's kind of hard to restore a single row (file) from a SQL Server Database, and it feels a little more opaque that I'm confortable with.  So, while I might use them for development, I needed a system that was more flexible. 
 
I've come up with two, one for code, and one for everything else.
 
My chosen solutions:
 
1. CVS
 
I'm keeping my source code (largely text-based) in CVS.  For the client, TortoiseCVS also use a namespace extension and intregrate directly into Explorer.  They've recently updated Tortoise to 1.6 and it's more stable and very easy to use.  I installed the free CVS NT Service and had it up and storing source in 30 minutes.
 
Pros: Also, it's file system based and easy to backup and can be accessed from multiple clients, including a Web Client and Tortoise.  Tortoise provides a very seemless experience and is my preferred way to work with code. 
 
Cons: CVS is too complicated for my wife to use and offers many advanced features like tagging and branching that are very "Source Code specific" IMHO.  For that, it's perfect for my code.   It does mean storing all your code in a "sandbox" that is a copy of what's on the repository.  It's non-trivial for the novice to setup things like Check-In notifications and it doesn't support any kind of full text indexing.  It doesn't automatically add files to the repository when you save them to a folder. 
 
Basically, it's a nice source control system that I will use, but it's not a Document Management System.
 
2. Document Locator
 
If you haven't tried DocumentLocator yet, do.  If you aren't ready to download a trial, checkout their awesome Flash demos.  This just might be the product for me.  It also stores data in SQL Server, but it's not trying to be a Source Control System (even though it is that, and lots more).
 
Pros: It includes a namespace extension for Explorer that makes your document repository show up next to My Computer.  You can open and save files from any Windows app directly into the Repository.  I have started using it for all my "My Documents" type files.  It supports versioning, has hooks into SCC (the Source Control APIs for Visual Studio) and most importantly it's EASY.  It also replaces dtSearch with Full-Text Indexing of all files, including scanned/OCRed TIFFs and PDFs.  I've long wanted to start scanning more documents and bills into my system, but I don't want to just dump a bunch of JPEG files into a folder.  DocumentLocator has some sweet scanning integration and scans, OCRs and imports your documents into the repository.  It supports a totally extensible schema and arbitrary tags that are also searchable.  It also supports notifying people of changes and additions and will also suck documents directly out of Outlook and into the repository if the document meets a specific filter.
 
Cons:  Backing up a single file while it's still inside the repository is still a challege, but I just back the whole SQL Server up anyway.  And if you don't have SQL Server, just use MSDE and you can still store up to 2 gigs of files.
 
 
Both CVS and DocumentLocator act as an authoritative source for my data.  I run the services side-by-side on my home server and pull from them as I please.  I've got all my source CVS'ed and running on my TabletPC now, and I'll my documents and presentations full-text-searchable in Document Locator.  Whew.  That's a good weekend's work.  Now it's time to watch Bernie Mac.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

BSOD SPOT-ted?

January 24, '04 Comments [1] Posted in Musings
Sponsored By

Mike Gunderloy emailed me this picture that a reader had sent along about a problem with a SPOT Watch.  I haven't had this problem...yet. ;)

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

ASP.NET, Caching, and Cartesian Products

January 22, '04 Comments [4] Posted in ASP.NET | XML
Sponsored By

I'm a HUGE believer in caching and unfolding data.  If you have a little extra RAM on your Web Servers, take advantage of it and cache.  When caching on the Web Server, the form of the data you cache should "look" as much like the data the end user would see.  In other words, if you have VERY normalized data in the database, but the HTML that will eventually be rendered to the user is a very unfolded, flat version of that data, then the data you cache should look more like the latter than the former.

When Patrick Cauldwell, Joe Tillotson, and Javan Smith worked on 800.com and Gear.com during the boom (800.com was bought by Circuit City and Gear.com was bought by Overstock.com) we built a series of multi-level caches that unfolded (de-normalized) the closer they got to the point of rendering, until we finally cached rendered HTML.

For sites that follow a regular navigation scheme (often that scheme is described by an XML file or in a Database...you know, nav.config, etc...we've all written one) the HTML of the headers, footers and navigation UI element (trees, pulldowns, tabs) should be cached if they are shared between more than one user.  Meaning, that if every user has a unique navigation, of course the ASP.NET Cache object isn't the place for them. 

In a site I'm working on now, there are (names changed to protect the innocent) Gold and Silver users.  Gold users see one set of navigation tabs, Silvers see another.  Additionally Gold and Silver users can be enrolled in additional programs, like Plan-A and Plan-B.  Whether a user is enrolled in Plan-A or Plan-B is not related to their membership in the Gold and Silver groups.

Additionally, the navigation tabs are drawn based on the current page (in Request.RawUrl).  Some navigation schemes that I am no longer a fan of are those that include techniques like Page.aspx?nav=tab1&subnav=subtab4&somethingsecret=somethingsilly.  I prefer to use liberal use of Url Rewriting and "simulated pages," like changing sitename/book.aspx?isbn=123 to sitename/123.book, etc.

For this site, we are just using page names and indicating in a navigation config XML file what tabs belong with what page.  For example:

<NAVIGATION>
   <ROLE name="Gold">
      <MENUITEM name="Accounts">
         <SUBMENUITEM name="Balances">
              <PAGE role="Plan-A">balances.aspx</PAGE>
              <PAGE>transfers.aspx</PAGE>
              <PAGE role="Plan-B">somethingelse.aspx</PAGE>
          </SUBMENUITEM>
       </MENUITEM>
    </ROLE>
</NAVIGATION>


...yada, yada, yada.  Of course, it's much more complex that this.  Each page also includes context sensitive help, user customizable links from a dropdown and a list of links that are related to the page their are on that the user may find interesting.  All of these are inter-related, making the XML file fairly normalized and complicating things.  When the file is finally deserialized, a series of hashtables and lookuptables are cached in memory for efficiency and used when rendering the menu.  The menu can render itself as a series of Tabs and SubTabs or a Tree, or whatever. 

The header/renderer is an ASCX file that asks the "NavigationService" for the details of the current navigation scheme, based on Context, in this case HttpContext.  A series of tests are done, checking .NET's role-based security for the user's roles.  Gold and Silver are mutually exclusive and Plan-A an Plan-B are not. 

That means that given n pages, x mutually exclusive roles and y non-mutually-exclusive roles, there can be:

n * x * 2y combinations of rendered headers

like:

balances.aspx : Gold
balances.aspx : Silver
balances.aspx : Gold : Plan-A
balances.aspx : Silver : Plan-A
balances.aspx : Gold : Plan-B
balances.aspx : Silver : Plan-B
balances.aspx : Gold : Plan-A : Plan-B
balances.aspx : Silver : Plan-A : Plan-B

and on and on.  So, if you look at the 1*2*4=8 strings above, you can imagine them as keys in a HashTable.  We can cache Header two different ways (actually dozens, but let's make it simple):

1. As Control objects in the Control Tree during the OnLoad.  If we see the same key again (the same page is visited with the same roles) we grab the Control objects from the HashTable, add them to the Control Tree.  Then the Control Tree will be turned into HTML in OnRender. 

Cons: This would take some more memory than caching just the HTML; it takes more CPU to Render the Controls every page view. 

Pros: If the Creation of the Control Tree that represents the navigation is expensive (more~ than ~50% of the totaly time it takes to fetch, build and render) then it's an easy change to implement if you're already building the navigation with HtmlControls in the code-behind.

2. Using the <%OutputCache%>directive with the VaryByCustom parameter like this:  <%OutputCache VaryByParam="None" VaryByCustom="PageAndRolesKey" Duration="180" %>.  Then, in the Global.asax you override GetVaryByCustomString, which will be automatically called by the Pages.   That's your opportunity to provide a KEY.  Not the HTML to cache, but rather the KEY by which to cache the rendered HTML.

override public String GetVaryByCustomString(HttpContext current, String arg)
{
   switch(arg)
   {
      case "PageAndRolesKey": return GeneratePageAndRolesKey(current);
   }
}

In this example, the GeneratePageAndRolesKey() function we'd look at the current page and current roles and build a key like: "balances.aspx : Silver : Plan-A."

The rendered HTML is then stored in the Cache using the Key returned.  If the page is visited again, based on the key, the rendered HTML is retrieved from the Cache and all the slow generation code is bypassed. 

To help me visualize and conceptualize, I like to say that there is one instance of a rendered header for each possible key. 

Pros: Easy to type, easy to implement incorrectly. :)

Cons: Possibly hard to conceive of the cartesian explosion of 'flags.'  It's always useful to write out the equation and a table of key combinations.  The OutputCache directive caches the entire UserControl (ASCX) so you can't just cache a small portion of the UserControl.  The UserControl is the 'atom.'  You CAN, however, have multiple UserControls and cache each differently.  Be aware though that that can cause another combinatoric explosion if you're not careful.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

MVP = SPAM?

January 21, '04 Comments [10] Posted in ASP.NET | XML
Sponsored By

Wow, the MVP Announcements are out.   Lots of nice folks and friends have become members of what I call the "Microsoft House of Representatives" or more commonly known as the Microsoft Most Valuable Professional (MVP) Program. 

Here's what Microsoft says about MVPs:

  • Recognized: Microsoft MVPs are acknowledged by peers and also by Microsoft for their active participation in Microsoft technical communities around the globe.
  • Credible: Microsoft MVPs have demonstrated practical expertise providing the highest quality information and content.
  • Accessible: Microsoft MVPs are active technical community leaders sharing their experience with peers.

Recognized?  Yes, I'd know DonXml if I was behind him in line. (Which I was in NYC recently going into a dive bar)

Credible? Yes, Sam Gentile knows C#, my friends.

Accessible? Jeff Julian and John Bristowe are on MSN Messenger enough to be considered officially accessible.

I was poking around my never read SPAM folder, which contained 1002 emails this evening and found this:

"It is with great excitement that I can inform you that you have been awarded as a MVP in ASP.NET for your community contributions in the past year."

Well, holy crap and happy birthday! Good thing I'm not the MVP for Outlook, because Outlook said this good news was SPAM.

Thanks to whoever nominated me.  As a fiscally conservative ASP.NET developer, I promise to vote my conscience during the caucuses. :)

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.