Monday, February 05, 2007

Expand/Collapse PowerShell Commands

I was listening the Bruce Payette interview on Hanselminutes and my interest really piqued when they were discussing aliases and being able to write really terse scripts.  It got me to thinking.  Wouldn't it be cool to be able to expand all the aliased command names in a script long enough for you to work on the script.  Then, when you are ready to put it back out there, you could collapse all the command names to short aliases.

Here is my first attempt:

   1:  function Expand-Command($Text)
   2:  {
   3:      $a = (alias $Text).Definition
   4:      if( $a.length -gt 0)
   5:      {
   6:          return $a
   7:      }
   8:      else
   9:      {
  10:          return $Text
  11:      }
  12:  }
  13:   
  14:  function Collapse-Command($Text)
  15:  {
  16:      $a = [string](alias | Where-Object { $_.Definition -eq $Text } | Sort-Object { Name.length })
  17:      if( $a.length -gt 0)
  18:      {
  19:          return $a.split(" ")[0]
  20:      }
  21:      else
  22:      {
  23:          return $Text
  24:      }
  25:  }
  26:   
  27:  function Expand-Script($script)
  28:  {    
  29:      $s = ""
  30:      Get-Content $script | ForEach-Object { ([string]$_).Split(" ") | ForEach-Object { $s += (Expand-Command($_) + " ") } }
  31:      return $s
  32:  }
  33:   
  34:  function Collapse-Script($script)
  35:  {
  36:      [string]$s = Get-Content $script
  37:        
  38:      Get-Command | ForEach-Object { $s = ($s -replace $_.Name, [string](Collapse-Command($_.Name))) }
  39:      return $s
  40:  }
  41:   
  42:  Collapse-Script("c:\\Dummy.ps1")
  43:  Expand-Script("c:\\Dummy.ps1")
 



So, what's going on? Let's start with the Collapse functions. The Collapse-Command function(lines 14-25) basically goes through all the aliases looking for the ones that match the command name that was passed in. Then it sorts them by their length and splits out the first available.  This way it will always pass back the shortest  command name.  In the Collapse-Script function(line 34-40), we loop through all the commands and then replace their names with the collapsed names.


The Expand-Command function(lines 1-12) acts pretty much the same as the Collapse-Command function.  The only difference is instead of searching on the alias definition, we search on the alias name.  The Expand-Script function(lines 27-32) acts a little differently than its counterpart.  It loops through all the individual lines and then through all the words, calling the Expand-Command function as it goes.


I tried to think like a PowerShell developer, not a C# developer for this one.  However, I don't think that it turned out very PowerShelly.  It is also ungodly slow.  I welcome any constructive ideas to make it better.   

Wednesday, January 24, 2007

View Office 2007 documents in Office 2003

It's only been three weeks and I have already run into compatibility issues with my version of Office and some document that I would like to open from the web.  Office 2007 uses a new file format labeled the "Open XML Format". 

According to Microsoft:

"The Open XML Formats usher in a new era of openness and transparency for Word, Excel and PowerPoint. Solution developers can take advantage of a host of new integration opportunities to connect documents to important sources of information."

If you are still using Office 2003, however, you will find that the new format isn't very open or transparent to you.  Luckily, Microsoft has published a patch for Office 2003 to make it compatable with Office 2007.  You can download it here: Microsoft Office Compatibility Pack.

My only question,  if Microsoft is so gung-ho on their new format, why didn't I get this pack via Microsoft Update?

Tuesday, January 16, 2007

Fix Visio 2003 VML code for IE7 with Powershell

I have recently been tasked with providing a lot of documentation around the applications that I am working on.  I naturally turned to Visio to help me with my dataflow and physical network diagrams.  I'm using Visio 2003 and have found that this version will export your Visio file and all of its pages as a web site.  By default all of your pages will be converted into VML.  You can also insert hyperlinks into the objects on your diagram that link to other pages.

This produces a really neat web site with built in navigation and search capabilities.  It even works in FireFox, sort of.  FireFox users see a dumbed down version without the search.  I discovered my issue when I tried to use the site in IE7.  Apparently IE7 doesn't like the way the links are built.  I found more information here.  It looks like Office 2007 will fix this. 

There is a short term fix.  You just have to replace the 'href="#"' in all the vml objects to 'style="cursor:pointer;"' for each file that was generated.  In my case, I have over a dozen files.

At the bottom of the article in the comments someone mentions that there is a utility that you can down load and install to perform the fix.  But my machine is still pissed off about the last dinky utility that I installed and only use once in a blue moon.  Powershell can do this, no sweat.  Here's the line that I used.

ls vml_*.htm | % { echo $_.Name; (gc $_.FullName) -replace("href=`"#`"", "style=`"cursor:pointer;`"") | out-File $_.FullName }



First off, I'm getting all the htm files with vml code in them.  Visio conviently labels them as vml.  Then, for each file I write out the name to the console.  You don't have to have this, but I like seeing what files were processed.  The gc command reads the file into a string and the -replace command does the replacing work.  Notice that the escape character in Powershell is "`" not "\".  Finally, the original file is overwritten with the corrected string.

Friday, December 08, 2006

Checking Error table with Powershell

One of our main web applications writes audit and error messages to the SQL database.  I was looking for a faster way to get a quick overview of the last few messages written to the table.  I could save a sql script, but seriously, where's the fun in that?  And besides, it would require me opening up SQL Query Analyzer. However, I do keep a Powershell window open at all times. 

Speaking of Query Analyzer, I had a significant breakthrough to a new level of keyboard zen with it last week.  More on that later. 

Onto the script:

   1:  $count = 50
   2:  if ($args.length -gt 0) { $count = $args[0] }
   3:   
   4:  $conn = new-Object System.Data.SqlClient.SqlConnection
   5:  $conn.ConnectionString = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=MyDatabase;Data Source=MySqlServer"
   6:  $conn.Open()
   7:   
   8:  $cmd = new-Object System.Data.SqlClient.SqlCommand
   9:  $cmd.CommandText = "SELECT TOP $count * FROM tblError ORDER BY ErrorID DESC"
  10:  $cmd.Connection = $conn
  11:   
  12:  $da = new-Object System.Data.SqlClient.SqlDataAdapter($cmd)
  13:  $ds = new-Object System.Data.DataSet "Errors"
  14:  $da.Fill($ds) | out-Null
  15:  $conn.Close()
  16:   
  17:  $ds.Tables[0].Rows | Format-Table -property ErrorID, errorTime, ErrorMessage -wrap -autosize
  18:   
  19:  rv count, conn, cmd, da

The first thing to do is to create a count variable that will be used to determine how many records to pull from the db.  It defaults to 50, but that can be overwritten in line 2 if you pass in a parameter to the script.  Lines 4-15, should look familiar.  They basically use ADO.NET objects to get the records from the db and place them in a DataSet.  Line 17 is responsible for displaying the results in the console.  I use the Format-Table cmdlet to filter out some of the fields and to make them look pretty by autsizing them and causing the cells to wrap their text.


In line 19, a bunch of variables are removed.  Normally, you wouldn't have to worry with this step as the variables will go out of scope as soon as the script finishes.  I did this, incase I ran the script in global scope.  You can accomplish this by inserting a ". " at the beginning of the command line.  In which case all of the variables would remain even after the script is complete.  In my case, I'm removing all the variables except the dataset.  That way, I can continue to manipulate the object and if I want to refresh it, I just re-run the script.

Friday, December 01, 2006

Wargames Influenced Powershell Hack

As a child, I love the movie WarGames.  Looking back though, it does seem kind of corny and maybe even improbable.  No matter, I still think its a great movie.  The movie introduces concepts that we still deal with today.  Things like system security, artificial intelligence and the concept of futility.  You prabably know that I love lists, so here are my favorite things about the movie.

The five greatest things about WarGames the movie:

5. That scene where Matthew Broderick phreaked a pay phone by sticking a pull tab from a soda can in the receiver.  Through the eyes of a kid, this was awesome.

4. The extensive use of the acoustically coupled modem to hack the Government's most secure network.

3. The 8 inch floppy drive.  Which at it's prime could hold 1200 kb.

2. Barry Corbin.

1. The cool terminal that would talk to you, a.k.a. Joshua.

Its the terminal that inspired my personallized use of this hack.  Below is an excerpt from my Powershell profile.  You may recognize some of the code from a previous post.

function say($script)
{
$v = New-Object -ComObject "SAPI.spvoice"
$r = $v.Speak($script)
rv v
}

#Say Hello
$Greeting = "Hello " + $env:Username + ". Shall we play a game?"
write $Greeting
say $Greeting
rv Greeting

The first thing I do is create a function named "say".  Inside the function I create a instance of the SAPI.spvoice COM object.  SAPI is the Text to Speech API that is installed with Windows XP by default.  You can administer it by going into your control panel and opening the Speech option.  The spvoice object allows you to pass in some text and it will convert it into audible speech and send it out to your speakers.  So the "say" function takes some text and speaks it.  Note that I took the time to use "rv" to remove the variable.  Don't need to hold on to that COM object longer than I need to.


Next you see where I get the user name of the person logged on and print out a greeting right before I speak it.  I've seen some articles on using this technology in ASP.NET applications.  Think of the fun you could have.

Thursday, November 16, 2006

Omitting the Byte Order Mark while saving XML Document

Have you every opened up an XML file in note pad and noticed those little gobbly gook characters preceding the XML declaration?  Well my friend you have encountered the ever elusive Byte Order Mark, or BOM for short.  I prefer Byte Order Mark because BOM sounds dirty, kind of like scrum.  Eck, dirty. 

The Byte Order Mark is basically three characters that are added to the beginning of xml files to denote their encoding.  I know... I know...  You can declare the encoding in the xml declaration.  That's what it is there for, right?  To declare stuff. 

Well, that is only partly true.  When an XML parser reads an XML file, the W3C defines the following three rules to decides how the document should be read:

  1. If there is a Byte Order Mark the Byte Order Mark defines the file encoding.
  2. If there is no Byte Order Mark, then the encoding attribute in the XML declaration is definitive.
  3. If there are neither of these, then assume the XML document is UTF-8 encoded.

I think that I remember reading an article once that claimed the Byte Order Mark was born out of Windows NT, but I can't find it now.  Either way, you are bound to come across some service somewhere that doesn't like it, probably because the service thinks that it is dirty.  All strings in .NET are encoded to UTF-16 by default. If you build and XmlDocument and save it, it will be UTF-16 encoded.  And by default, there will be a silly little Byte Order Mark.  Visual Studio, like most current xml editors, won't show it to you, but its there. 

Here's how I prevent the Byte Order Mark from appearing in my generated xml files.

public void WriteXmlFile(XmlDocument xdoc)
{
System.Text.Encoding enc = new UTF8Encoding(false);
XmlWriter w = new XmlTextWriter("NewFile.xml", enc);
xdoc.Save(w);
w.Close();
}




When I create the UTF8Encoding object, I pass in false for the encodingShouldEmitUTF8Identifier parameter.  This will omit the Byte Order Mark from the NewFile.xml file. 

Tuesday, November 07, 2006

Parsing CSV files with PowerShell

So there I was, looking at a Caliber requirement, basically a Word document, with a table of values that needed to get into a table in our SQL database.  We were still in development and there was no entry form in the application for the requirement writers to enter the values.  Faced with the prospect of having to manually build a sql script to insert all these values, I desperately called out to Necessity.  You know that Necessity is the mother of invention.  She carries a big purse full of invention, with which she immediately hit me over the head.  She told me that I already had Powershell, mumbled something about the boy that cried wolf and stormed out.  Powershell, eh?  The following is an abbreviated description of what I did to generate my sql script. My insert statement was much larger.

First, I copied the word table into excel, including the headers, and saved the file as a CSV file. The format looked something like this:

State, City, Type

GA, Atlanta, AB

GA, Albany, A

Now for the Powershell.  Check out this bad boy:

Import-Csv Test.csv | % { "INSERT INTO refTestTable (State, City, Type) VALUES ('$_.State', '$_.City', '$_.Type')"}  >> "Test.sql"

After opening up the new Test.sql file, I got this:

INSERT INTO refTestTable (State, City, Type) VALUES ('GA', 'Atlanta', 'AB')
INSERT INTO refTestTable (State, City, Type) VALUES ('GA', 'Albany', 'A')



Not bad for one line of code.  Powershell's Import-Csv command loops through all the records in the CSV file and generates objects.  Then for each object we build a sql string and insert the object's properties.  Notice how the properties were dynamically generated so all you had to do was call them?  Finally, I outputted the resulting string to a text file.  Using this method I was able to generate and run the sql script in less than 10 minutes. 


Monday, November 06, 2006

My first blog from Live Writer

This is my first blog post that I have generated in Windows Live Writer Beta.  Until now, I have used the online editor.  The fat client sports a cool WYSIWYG editor and a lot of great accelerator keys.  Publishing is a snap and seems to take less time compared with the web editor.

The team has provided an SDK and encourages the development of plugins.  There is a page dedicated to these here.  I found a neat one that helps insert code snippets.  Insert Code for Windows Live Writer supports C#, HTML, MSH, JavaScript, Visual Basic and TSQL.  I wish that there was a way to assign accelerator keys to the plugins.  For now, I'll just have to go through the menu.

Friday, November 03, 2006

Portable App Week - FastStone Capture

We've come to end of Portable Apps Week and I'm a little sad. But all good things must come to an end. For my last app of the week, I'm going back to FastStone and their Faststone Capture utility. Capture is a screen capture utility that lets you easily capture anything on the screen including windows, objects, full screen, rectangle regions, freehand regions, and scrolling windows. It comes with an editor that allows for cropping, adding text, highlighting and drawing. Not bad for 1.2MB. It's what I've been using to generate the images for all of this week's previous posts.

I know what you're thinking. How does this compare with Snagit. Well, it isn't quite as full featured as Snagit. It doesn't do text capture, menu capture or video capture. It does allow for freehand capture regions. I'm not sure if Snagit has that or not. FastStone Capture has a much smaller footprint than Snagit. Hmmm, what else? Did I mention that it was free?

Here is a capture I did freehand. It is supposed to be an octogon.

Thursday, November 02, 2006

Portable App Week - FastStone Image Viewer

When someone asks me to help them with their website, I have to remind them that I'm a developer, not a graphic artist. As a developer I strive to make pretty things, but I have no formal artistic training. I had a really good friend that was a professional graphic artist. His firm did work for Coke and Six Flags. I probably could have learned a lot from him, had my girlfriend at time not dumped me and ran off and married him.

Happy place, go to your happy place.

I am a big fan of the gimp. It's open sourced, free, powerful and difficult to learn. It's also really big and takes a long time to load. Since I spend most of my time editing pictures of the kids, removing red-eye and cropping, I don't always need the power of the gimp. So I was excited to find FastStone's ImageViewer.

"FastStone Image Viewer is a fast, stable, user-friendly image browser, converter and editor. It has a nice array of features that include image viewing, management, comparison, red-eye removal, emailing, resizing, cropping and color adjustments. Its innovative but intuitive full-screen mode provides quick access to EXIF information, thumbnail browser and major functionalities via hidden toolbars that pop up when your mouse touch the four edges of the screen. Other features include a high quality magnifier and a musical slideshow with 150+ transitional effects, as well as lossless JPEG transitions, drop shadow effects, image annotation, scanner support, histogram and much more. It supports all major graphic formats (BMP, JPEG, JPEG 2000, animated GIF, PNG, PCX, TIFF, WMF, ICO and TGA) and popular digital camera RAW formats (CRW, CR2, NEF, PEF, RAF, MRW, ORF, SRF and DNG)."


It's practically microscopic(3MB) compared to the gimp(40MB) and its fast. The full screen mode is really cool and intuitive, once you get the hang of it. There are a ton of shortcut keys that make browsing a little easier. Red eye removal and rotation are a snap. The cropping feature is cool because it allows for you to set the crop size to monitor resolutions. Great for getting a picture of my daughter in her bumble-bee costume for my wallpaper. It comes with dual monitor support, so you can do full screen on one monitor and look at the image viewer on the other. It will even let me link to an external program, if I want to edit the image in something more powerful.

And don't forget, this is a portable app. There are no ties to the registry. So next time you take your USB drive over to your parent's house to show them the pictures you just took of the grandkids, you'll have a great image viewer to view them in.

Wednesday, November 01, 2006

Portable Apps Week - FolderSize

It's an all to familiar proplem. Your favorite drive (HDD, USB, etc.) has filled up and you need to make some space. So you go into explorer and pull up your drive. Explorer shows you a list of folders and now its up to you to figure out which one is taking up the most space. This means a lot of right clicking. Enter FolderSize from RoteBetaSoftware. What a great play on words.

Folder size gives you a graphical representation of the folder sizes. Take a look at my ruby installation. You'll quickly figure out that the 'lib' folder is far and away the largest folder in the directory. You can even click directly on one of the bars in the graph to drill down into sub folders. Its a neat little utility (333kb) that comes in handy from time to time.

Tuesday, October 31, 2006

Portable App Week - WinAudit

Today's portable application comes to us from Parmavex Services. It took me a while to figure this company out. If I understand it right they have two main functions. They provide network services, software development, web hosting and IT services. And also, they supply spare parts for construction plant equipment. Kind of like a Barber shop that sells socks.
Despite their questionable lack of business direction, they have put out a pretty cool free-ware utility called WinAudit. WinAudit scans your machine and gathers up all the information it can find into a neat html report. Here is the description off the web site.


"The programme reports on virtually every aspect of computer inventory and configuration. Results are displayed in web-page format, categorised for ease of viewing and text searching. Whether your interest is in software compliance, hardware inventory, technical support, security or just plain curiosity, WinAudit has it all. The programme has advanced features such as service tag detection, hard-drive failure diagnosis, network port to process mapping, network connection speed, system availability statistics as well as Windows® update and firewall settings."


And when they say every aspect, they really mean it. It even read the serial number off my motherboard. You can save the results to an html file, a pdf, a chm, several flavors of text and XML. I wish I had this when I was still doing network support. It will come in handy the next time I'm troubleshooting on someone else's machine.

Monday, October 30, 2006

Portable Apps Week - Smart Undelete

I've been really keen on the idea of portable applications lately and last weekend I picked up a few more for my USB drive. So, I'm declaring a portable app week here at Mack the # implement. Let's get started with the only application that actually cost me any money.

I was tidying up some folders on my desktop at home, got a little 'Shift+Delete' happy, and accidentally deleted all the digital pictures from my son's first trip to the Georgia Aquarium. This is a bad place to be. My mind began calculating the odds that my wife would just forget that the pictures ever existed. Of course, NASA would have a hard time coming up with that number. Then it hit me, they aren't really gone. They're just marked as deleted.

After a quick search (on another machine), I found several recovery tools. I finally opted for Smart Soft's Smart Undelete. It was cheap, had a small footprint(<1mb) and could be used from a USB drive. It also has a 100% money back guarantee.

The UI is simple and easy to use. Just tell it where to scan. It also gives you the option to only scan for certain file types. In my case, .jpg files. I was able to get everything back. I even justified to expense to my wife by explaining how I could use it the next time one of our many relatives deletes something important. Yeah... that's the ticket. ;)

Monday, October 02, 2006

Pausing a PowerShell Script

I was having an issue while running my watir scripts where if I ran a script that saved information to the database on two or more machines at the exact same time, failure was sure to follow. This is really annoying and not likely to happen in the real world. However, in the alternate universe where I do my testing, this happens all the time. Alternate universes are cool.

We now have a lot of Watir scripts, and it is really tedious to run them individually. So I wrote a script that calls each one sequentially using PowerShell . With my new batch script, I am able to kick off all the Watir scripts from all of my test boxes at the same time and walk away while the website gets put through its paces. This works great until New York and DC try to save changes to the same story at the same time. One of the watir scripts will fail. Usually New York wins. Stupid New York.

I'm sure that there is a great solution, which involves messing with the database, but I don't have that kind of time, or patience or attention span. For the time being, I just wanted to put a pause in the execution of my PowerShell script that waited for me to press enter to continue. So here you go:

Code of Power:


[System.Console]::ReadLine()

Awesome!

Wednesday, September 27, 2006

How to generate a connection string

1 The other day I found myself trying to write my own connection string to a System DSN I had just set up. That was stupid and silly and I know that now. Seriously, who remembers the syntax for creating a connection string? No one. Why? Because we don't need to create these things every day. And also, it is stupid and silly.

So I donned the ceremonial robe and beseeched the great google for help. Of course, I was presented with a mountain of information on connection strings. But then it pulled out a large chest that looked like something right out of a pirate movie. I think this was because it happened to be International Talk Like a Pirate Day. The great google loves this stuff.

It spoke these words to me, "Avast! These examples be good, but ye have the noggin of a bilge rat. Perhaps ye be in need of some voodoo, ...some Windows voodoo." And it pulled a scroll from the chest and handed it to me with a twisted ferret look in its eyes.

Hmmm... voodoo, eh? Sounds iffy. But then again, not all windows voodoo is bad. There have been books dedicated to the subject. And I think we have all been in situations where we would gladly rub our computer monitors down with a fried drumstick from KFC while chanting the names of the 12 dwarves in reverse alphabetical order, if it would just keep IE from spewing random "Operation aborted" errors at our users. But that is another blog post. I wasn't that desperate, yet. I opened up the scroll, read the instructions and said to the great google, "This may be the grog talking, but I like sheh way you sthink." What follows are simple steps to get windows to generate a connection string that even a bilge rat could perform after a couple mugs of grog.

  1. Create a new file, the name doesn't matter, and give it a .udl extension.
  2. Double click on your new file. This will bring up the Data Link Properties dialog
  3. Select the "Use connection string" option and then click the "Build..." button.
  4. Your connection string will show up in the connection string text field. You can also access it by opening up your udl file in a text editor.

Thursday, September 14, 2006

Mouseless Firefox

1I just got back from vacation and I guess I left my mind on the beach, because I forgot to pick up my mouse on the way out the door. No biggy, I still have my laptop's touch pad and I don't really use the mouse much anyway. I was even able to pick up a new short cut key, just because I had to.

In Query Analyzer:
Shift+F6 - Switch between panes.

I think this is a good time to talk about some "mouseless" features and extensions that I have found very useful in Firefox. Here are some of my least known/most favorite shortcut keys for Firefox:

F6/Shift+F6 - Cycle through the frames on a page.
F7 - Enable/Disable caret browsing. The caret browsing is great for selecting and copying text.

One of my favorite Firefox add-ons is Mouseless Browsing. It takes some getting used to, but now I don't know what I would do without it. This extension enables browsing in Firefox using only the numpad keys. The extension puts a number next to each control or link on the page. All you have to do is type in the number and hit enter to browse to that link or control. You can even hold down the alt key while entering the number to open the link in a new tab. The numbers do mess with the formatting on the page, but it is really easy to turn them on or off. Just use the period key on the numpad.

Friday, September 08, 2006

Portable Apps are cool!

I'll be going on vacation next week to the beach and then to visit some family. That means I'll probably spend some time on their computer. Now, I like my little utilities that I use from day to day, and I would like to use them but I don't want to take the time to install them. I remembered that Hansleman was looking for a portable browser and it got me searching for other portable applications.

What is a portable application? Here is the definition from the PortableApps web site:http://portableapps.com/

A portable app is a computer program that you can carry around with you on a portable device and use on any Windows computer. When your USB flash drive, portable hard drive, iPod or other portable device is plugged in, you have access to your software and personal data just as you would on your own PC. And when you unplug, none of your personal data is left behind.

So, what kinds of portable applications are out there? About everything you could want and then some.

Luckily for me I had just picked up a shiny new Verbatim 512MB USB Flash Drive. It was just over ten bucks at Office Max. Its light and feels a lot sturdier than my last one. Here is a list of some of the apps that I have installed on my USB drive.

SysInternals:
Go to SysInternals while you still can and at the very least get:
Process Explorer
FileMon
RegMon
Autoruns
TCPView

Internet Stuff:
Browsar - Private browsing in IE. http://www.browzar.com
TorPark - Ultra private browsing in FireFox. http://torpark.nfshost.com/
Gaim Portable - IM Client. http://portableapps.com/apps/internet/gaim_portable

File Stuff:
7-Zip portable - Have you ever been stuck without a way to open up a zip file? http://portableapps.com/apps/utilities/7-zip_portable
ClamWin Portable - Portable virus scanner. http://portableapps.com/apps/utilities/clamwin_portable
FileZilla - FTP utility. http://filezilla.sourceforge.net/
Foxit Reader - Smaller and faster than Acrobat reader for pdfs. http://www.foxitsoftware.com/pdf/rd_intro.php

Just for fun:
Sudoku Portable http://portableapps.com/apps/games/sudoku_portable

Unclassified but cool:
PStart - PStart can be configured to start up when you plug in your USB drive. I creates an icon in your systray that acts like a start menu for your drive. Giving you quick access to the applications in a menu.

All these utilities only added up to 77MB. I wonder what it would take to get everything that we need to do our jobs as developers onto a 1GB USB drive. We wouldn't have to worry about dragging around laptops as long as we had a clean XP install to plug our drive's into. You wouldn't even require an internet connection for some of the apps. 1
I'll be going on vacation next week to the beach and then to visit some family. That means I'll probably spend some time on their computer. Now, I like my little utilities that I use from day to day, and I would like to use them but I don't want to take the time to install them. I remembered that Hansleman was looking for a portable browser and it got me searching for other portable applications.

What is a portable application? Here is the definition from the PortableApps web site:

A portable app is a computer program that you can carry around with you on a portable device and use on any Windows computer. When your USB flash drive, portable hard drive, iPod or other portable device is plugged in, you have access to your software and personal data just as you would on your own PC. And when you unplug, none of your personal data is left behind.

So, what kinds of portable applications are out there? About everything you could want and then some.

Luckily for me I had just picked up a shiny new Verbatim 512MB USB Flash Drive. It was just over ten bucks at Office Max. Its light and feels a lot sturdier than my last one. Here is a list of some of the apps that I have installed on my USB drive.

SysInternals:
Go to SysInternals while you still can and at the very least get:
Process Explorer
FileMon
RegMon
Autoruns
TCPView

Internet Stuff:
Browsar - Private browsing in IE.
TorPark - Ultra private browsing in FireFox.
Gaim Portable - IM Client.

File Stuff:
7-Zip Portable - Have you ever been stuck without a way to open up a zip file?
ClamWin Portable - Portable virus scanner.
FileZilla - FTP utility.
Foxit Reader - Smaller and faster than Acrobat reader for pdfs.

Just for fun:
Sudoku Portable

Unclassified but cool:
PStart - PStart can be configured to start up when you plug in your USB drive. I creates an icon in your systray that acts like a start menu for your drive. Giving you quick access to the applications in a menu.

All these utilities only added up to 77MB. I wonder what it would take to get everything that we need to do our jobs as developers onto a 1GB USB drive. We wouldn't have to worry about dragging around laptops as long as we had a clean XP install to plug our drive's into. You wouldn't even require an internet connection for some of the apps.

Thursday, September 07, 2006

Decode ViewState with PowerShell

We have been screwing around with ViewState lately, trying to resolve some issues and shrink down the size. In the process, we've downloaded several utilities to decode the viewstate. However, even these were failing to decode if the Viewstate was over a certain size or if it had non-native datatypes. Since we didn't have access to the source code, we couldn't fix the problems with the utilities. So yesterday, at approximately 3:57 pm, I thought to myself, "Gee, how hard could it be to write my own decoder?" But who wants to create a new VS project for a dinky little utility that you may never use again. Time for a PowerShell Script. It's one file with no compiling necessary.

This script reads the contents of a text file containing the viewstate in question. Then it decodes it, replaces the non-printable characters with pipe symbols and writes the results to another text file. You could easily rewrite this to pass in the viewstate string as a parameter to the script, if you wanted to. You're the kind of person who isn't afraid to paste a +50kb string into your command line of choice. Get down with your bad self!

A note on the non-printable characters: As of .NET 2.0, the viewstate is now delimited with non-printable characters. To learn more read Fritz Onion's blog on the subject.

Now, onto the script:

# Get the file from the arguments and read it into the x
$x = Get-Content $Args[0]

# Parse the string into a byte array
$byteArray = [System.Convert]::FromBase64String($x)

# Create a new encoding object
$enc = New-Object System.Text.ASCIIEncoding

# We need a charArray with the same length as the byteArray. I am having a
# hard time finding out how to create an strongly typed empty array of a given
# length in powershell. If you know how, please let me know. For now I just
# make charArray a copy of byteArray that will be overwritten later.
[System.Char[]]$charArray = $byteArray

# Do the decoding.
$enc.GetDecoder().GetChars($byteArray, 0, $byteArray.Length, $charArray, 0)

# Build the result string.
$charArray | ForEach-Object { $result += $_ }

# This is a neat regex to replace all the non-printing characters with something else.
# Then the result is written out to ViewStateDecoded.txt.
$result -replace "[\x01-\x1F]+", "|" | Out-File ViewStateDecoded.txt

I could probably get this down to 5 lines of code or less, but it more readable this way.

Wednesday, September 06, 2006

Set Window Title in PowerShell

1 It's been a month since my last post, and I'm sure that you were thinking I was dead. Not quite, just really busy. Here's a little time saving tip that I implemented last week in PowerShell. I was working on several issues and had multiple PowerShell windows open. Its kind of hard to find the instance of PowerShell that you are looking for while alt+tabbing through TaskSwitchXP. TaskSwitch even has a preview window, which helps as long as your window isn't minimized. The problem was that I had 3-4 PowerShell windows all titled "Windows PowerShell".

Wouldn't it be great if I could change the window title to something more meaningful? No sweat, PowerShell gives you access to the window through the $Host variable. The command looks like this "$Host.UI.RawUI.WindowTitle = 'My New Title'". Of course, I'll never be able to remember this and it does seem like a lot of typing. So I added the following function and alias statement to my profile.

function Set-WindowTitle($title)
{
$Host.UI.RawUI.WindowTitle = $title
}

set-alias swt Set-WindowTitle

Notice that I tried to mimic the verb-noun convention used by the rest of the PowerShell commands. Now, to set the title I can type in "swt 'My New Title'".

Wednesday, August 09, 2006

RDoc Documentation for Watir

In my dealings with Watir, I have been overlooking a very useful reference tool. The kind Watir developers have conveniently compiled class documentation with RDoc. RDoc is the Ruby version of NDoc (R.I.P.) This is great for when you want to see what the IE object really does. You can access this documentation here.

Your Install Dir\Watir\doc\rdoc\index.htm