Scott Hanselman

Upgrading to a Canon Pixma MP500 Multifunction Inkjet Priner

May 16, '06 Comments [5] Posted in Reviews
Sponsored By

We awoke today to find that our trusty Canon S300 Printer had died. It was a great crappy little $50 printer that we had just used up. Noisy, but with great output, cheap ink and fantastic photos if you use good paper.

I shopped around BestBuy today and finally decided on the Canon Pixma MP500. It's got everything we wanted and way more.

  • Duplex Printing - Total bonus and a great feature.
  • Color Copier - Big on the WAF, this lets my wife Mo easily make copies without using the PC.
  • Scanner - Very simple TWAIN drivers let me dump my old and flakey Canoscan N650U.
  • Two paper trays - Feels like the office. I can put photo paper in one and regular in the others
  • Borderless 4x6 or 5x7 Photo Printing - Amazing quality from my Casio 7.2M Camera.
  • 2.5" Color LCD - Didn't think I'd like this, but it's actually pretty useful and shows details about how much ink is left.
  • PDFs - You can scan directly to PDF, which'll be useful for documents. It is literally one-button as it auto-names files and puts them in My Documents. I actually prefer this kind of "Just Do It" UI. I my write an app to help though...
  • Quiet Mode - You can give it a time of day (I said from 9pm to 7am) to run extra quiet while printing. Slows down to make it happen.
  • Memory card slots - These actually mount as disk drivers, but unlike cheapo memory card adapters, the drives only exist while the memory card is in the slot. It's always lame to have empty drives E: through L: that I don't use, but take up space in My Computer. Seems like a small detail, but it's a good think.
  • IR Support - Print directly from Camera Cell phones
  • Digital Camera Support - Prints from USB Digital Cameras

Bad stuff:

  • I was totally unable to run the included CD-ROM's setup, as it crashed when I pressed install. However, I was able to download just the drivers and not the craplets and it worked fine.

In retrospect (a short 1 hour later) I probably should have purchased the Canon Pixma MP800 since it's only $25 more on Amazon, and has 512 nozzles instead of 320 on the MP500, but really, who can tell the difference? Not I. All in all, we're thrilled.

One other note, no matter what printer you end up getting, no printer is complete without a copy of FinePrint. You can advanced and editable print-preview for all applications and printer-independent sizing/tiling. If you want to print 4-to-a-page duplex, no problem.  If you print a web page and see that it's 2 pages, but the second page is half empty, just delete it, visually, before it gets to the printer. What a great way to save paper.

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

Making Junctions/ReparsePoints visible in PowerShell

May 12, '06 Comments [1] Posted in PowerShell | XML
Sponsored By

CmdjunctionI'm not sure if this the right way to do this, and I'm sure someone more clever will speak up but...I use a lot of junctions/reparsepoints in my development here, and I was used to seeing them called out when I typed "dir" from cmd.exe.

(Notice in the screenshot from cmd.exe that the "foo" directory is actually marked <junction>)

In PowerShell when you type Dir, you're getting an Array of System.IO.FileInfo/System.IO.DirectoryInfo objects that are displayed using some default formatting. That default Formatting is a combination of two things, a Type definition and a View definition.

First, there's no "Mode" property on a DirectoryInfo, so how is one being shown? In PowerShell you can "tack on" new properties with Script. This isn't derivation, as it's type extension. Adding to functionality, type-wide (within the context of PowerShell) for any .NET type. So, in C:\program files\Windows PowerShell\v1.0\ there's a file called types.ps1xml that has this little bit of info:

  <Type>
        <Name>System.IO.DirectoryInfo</Name>
        <Members>
            <ScriptProperty>
                <Name>Mode</Name>
                <GetScriptBlock>
                     here's where the magic happens...
                </GetScriptBlock>
            </ScriptProperty>
        </Members>
    </Type>

So, I created a personal My.Types.Ps1.xml file in my PSConfiguration folder that looked like this, where 1024 is the value of the [int]([System.IO.FileAttributes]::ReparsePoint) enum and "-band" is "bitwise and."

<Types>
   <Type>
        <Name>System.IO.DirectoryInfo</Name>
        <Members>
            <ScriptProperty>
                <Name>ExtMode</Name>
                <GetScriptBlock>
                    $catr = "";
                    if ( $this.Attributes -band 1024 ) { $catr += "j" } else { $catr += "-" };
                    if ( $this.Attributes -band 16 ) { $catr += "d" } else { $catr += "z" };
                    if ( $this.Attributes -band 32 ) { $catr += "a" } else { $catr += "-" } ;
                    if ( $this.Attributes -band 1 )  { $catr += "r" } else { $catr += "-" } ;
                    if ( $this.Attributes -band 2 )  { $catr += "h" } else { $catr += "-" } ;
                    if ( $this.Attributes -band 4 )  { $catr += "s" } else { $catr += "-" } ;
                    $catr
                </GetScriptBlock>
            </ScriptProperty>
        </Members>
    </Type>
    <Type>
        <Name>System.IO.FileInfo</Name>
        <Members>
            <ScriptProperty>
                <Name>ExtMode</Name>
                <GetScriptBlock>
                    # Added the extra "-" to make sure things line up when FileInfos and DirectoryInfos are listed together
                    $catr = "-"; 
                    if ( $this.Attributes -band 16 ) { $catr += "d" } else { $catr += "-" } ;
                    if ( $this.Attributes -band 32 ) { $catr += "a" } else { $catr += "-" } ;
                    if ( $this.Attributes -band 1 )  { $catr += "r" } else { $catr += "-" } ;
                    if ( $this.Attributes -band 2 )  { $catr += "h" } else { $catr += "-" } ;
                    if ( $this.Attributes -band 4 )  { $catr += "s" } else { $catr += "-" } ;
                    $catr
                </GetScriptBlock>
            </ScriptProperty>
          </Members>
     </Type>
</Types>

Then in my Microsoft.PowerShell_profile.ps1 (the file that gets executed every time I start a PowerShell) I added:

$profileTypes = $profile | split-path | join-path -childPath "My.Types.ps1xml"
Update-TypeData $profileTypes

Now, I'm not sure how to get dir (alias get-childitem) to use MY ExtMode rather than its own, but I think I'd need to override the default View Definition. It's a little tricky with these scoped XML files, because I originally named my new property "Mode" and was chastised for my efforts:

Microsoft.PowerShell, C:\Documents and Settings\shanselm\My Documents\PSConfigu
ration\My.Types.ps1xml(39) : Error in type "System.IO.FileInfo": Member "Mode"
is already present.

So, I named it "ExtMode." We shall see if there's a better way, until then, this function worked.

function edir
{
 dir | select ExtMode, LastWriteTime, Length, Name
}

and got me this output. Notice the "j" now in the ExtMode column.

Psedir

If I can't override dir's default view, I probably could also have removed the alias for "dir" and replaced it with my own:

if (test-path alias:\dir) { remove-item -force alias:\dir }
set-alias dir edir

but edir is fine for me now.

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

Forcing an update of a cached JavaScript file in IIS

May 12, '06 Comments [12] Posted in ASP.NET | DasBlog | Javascript
Sponsored By

JavascriptcachingThis might seem obvious to some folks, but to others it's not, so it's worth mentioning. Regardless, it's a good example of a "white box" attitude. Don't assume. Always assert your assumptions with good tests.

A client wanted to know how to 'force' a client to update some javascript that the browser had cached. The easy answer is "change the file."

Here's what happens with a single HTML file and a single JavaScript file, running locally on my machine. The main directory is set to "Expire Immediately" via IIS's properties dialog. That means "keep it fresh."

Underneath the main directory is a directory called /js that is set to expire in 7 days, as seen at right.

Here's an abridged HTTP Header view (via ieHttpHeaders) after hitting the page for the first time ever important stuff in bold.

GET /javascriptcachingtest/default.htm HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1)

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
X-Powered-By: ASP.NET
Cache-Control: no-cache
Expires: Fri, 12 May 2006 19:03:59 GMT
Date: Fri, 12 May 2006 19:03:59 GMT
Content-Type: text/html
Last-Modified: Fri, 12 May 2006 18:53:33 GMT
ETag: "b01be5ef575c61:df3"
Content-Length: 115

GET /javascriptcachingtest/js/test.js HTTP/1.1
Referer:
http://localhost/javascriptcachingtest/default.htm
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1)
Connection: Keep-Alive

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
X-Powered-By: ASP.NET
Cache-Control: max-age=604800
Expires: Fri, 19 May 2006 19:03:59 GMT
Date: Fri, 12 May 2006 19:03:59 GMT
Content-Type: application/x-javascript
Last-Modified: Fri, 12 May 2006 18:54:28 GMT
ETag: "50b1c1d4f775c61:df3"
Content-Length: 151

Note that both files were returned with HTTP 200 OK and the Javascript file had a Last-Modified header returned and an Expires date a week in the future. Now I'll hit F5 to refresh.

GET /javascriptcachingtest/default.htm HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1)

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
X-Powered-By: ASP.NET
Cache-Control: no-cache
Expires: Fri, 12 May 2006 19:11:30 GMT
Date: Fri, 12 May 2006 19:11:30 GMT
Content-Type: text/html
Last-Modified: Fri, 12 May 2006 18:53:33 GMT
ETag: "b01be5ef575c61:df3"
Content-Length: 115

GET /javascriptcachingtest/js/test.js HTTP/1.1
Referer:
http://localhost/javascriptcachingtest/default.htm
If-Modified-Since: Fri, 12 May 2006 19:03:59 GMT
If-None-Match: W/"50b1c1d4f775c61:df3"
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1)
Host: localhost
Connection: Keep-Alive

HTTP/1.1 304 Not Modified
Server: Microsoft-IIS/5.1
Date: Fri, 19 May 2006 19:03:59 GMT
X-Powered-By: ASP.NET
Cache-Control: max-age=604800
Expires: Fri, 19 May 2006 19:03:59 GMT
ETag: "50b1c1d4f775c61:df3"
Content-Length: 0

JavascripttouchNote that the JavaScript file wasn't return (Content-Length: 0), the ETag is the same, and instead a 304 Not Modified was returned. This is the essense of client side caching and is something you should be exploiting (Sadly, fewer folks than you think do this) to get good throughput, efficiency and save on bandwidth costs.

Now, I'll "touch" the file - change it's modified date using the touch.exe I've got in my c:\utils folder (from http://unxutils.sourceforge.net/). Of course, there are other ways to do this, but you get the idea.

We've touched the file, so we'll hit F5 again to refresh:

GET /javascriptcachingtest/default.htm HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1)

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
X-Powered-By: ASP.NET
Cache-Control: no-cache
Expires: Fri, 12 May 2006 19:11:30 GMT
Date: Fri, 12 May 2006 19:11:30 GMT
Content-Type: text/html
Last-Modified: Fri, 12 May 2006 18:53:33 GMT
ETag: "b01be5ef575c61:df3"
Content-Length: 115

GET /javascriptcachingtest/js/test.js HTTP/1.1
Accept: */*
Referer:
http://localhost/javascriptcachingtest/default.htm
Accept-Language: en-us
Accept-Encoding: gzip, deflate
If-Modified-Since: Fri, 12 May 2006 19:03:59 GMT
If-None-Match: "50b1c1d4f775c61:df3"
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1)
Host: localhost
Connection: Keep-Alive

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
X-Powered-By: ASP.NET
Cache-Control: max-age=604800
Expires: Fri, 19 May 2006 19:11:30 GMT
Date: Fri, 12 May 2006 19:11:30 GMT
Content-Type: application/x-javascript
Last-Modified: Fri, 12 May 2006 19:11:29 GMT
ETag: W/"804647dff775c61:df3"
Content-Length: 151

Notice that the browser asks for the JavaScript not only "by name" but also by date, and by ETag, a mostly unique identifier. The IIS server responds with an HTTP 200 OK, returning the freshly changed (in IIS's mind) file along with a new ETag and a new Last-Modified date.

As an aside, DasBlog does a pretty good job in its RSS Syndication Code of programmatically managing If-Modified-Since behavior. Remember that ASP.NET's <%OutputCache%> is SERVER-SIDE. It's not what we've just seen here. If you want this kind of behavior in your ASP.NET code, you'll need to do it manually in code. I'll post examples of that later.

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

Getting Things Done with SpeedFiler

May 11, '06 Comments [4] Posted in Reviews | Tools
Sponsored By

SpeedFilerOmar's turned me on to SpeedFiler, and I'm loving it.  I've talked about my personal system of organization before and my use of Getting Things Done.

In a nutshell, your Inbox is just that, your INbox. Not your "hold everything" box. If it's IN your INbox then it hasn't been processed. The basic processing rules are Do it, Drop it, Delegate it, or Defer it.

Everything else gets filed away for reference, and that's where SpeedFiler comes in. As with all useful niche utilities it is nicely priced at $19.95 (finally a company that understands pricing, unlike some.)

Outlook doesn't support "tagging" of Email messages (categories are a possibility, but they aren't very easy to set or search) so we have this big hierarchy of folders that typically run around in and drag-and-drop messages. Filing stuff isn't very quick if you're trying to bang through your inbox and get it down to zero messages.

MyoutlookfoldersSpeedFiler grabs Shift-Ctrl-V when a message is selected and pops up a dialog with the focus set to receive keyboard input immediately. So if I get a message that I want to blog about, I type:

Shift-Ctrl-V, @bl, Enter

and it's filed. As you're typing it looks up in the the list of folders an offers a list of folders that match you search string.

It's also got an unobtrusive toolbar that has dynamic buttons that change to show the names of the folders you've recently filed things to. That reduces filing to common areas down to one click.

There's a "Go To Folder" text box that you just type the name, or partial name, of a folder and hit enter and you're there.

I put an @sign at the beginning of a number of folders to make them group together. In the "pure" GTD world those are supposed to be "context" that I work in, like @home and @office, so I'm breaking the rules a bit. These contexts are more mental than physical but they work for me.

Some small complaints are there's a pause when Outlook starts up when SpeedFiler enumerates the folders. My folders don't change that much, not more than a few times a week, so if the program would just store the hierarchy in alternate storage and start up with that cached information, it could use a background thread to "catch up" later.

Itzy, the author of SpeedFilter has a blog called Email Overloaded.

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.