Scott Hanselman

Hanselminutes Podcast 25 - Scott's .NET Blogroll (for July 2006 at least)

July 18, 2006 Comment on this post [5] Posted in Podcast | PowerShell | ASP.NET | XML | Bugs | Tools
Sponsored By

HanselminutesMy twenty-fifth Podcast is up. This episode is a discussion of a few of my favorite blogs. I had a HUGE list and ended up having to really chop it down in order to make it fit within our (my) time limit. Remember, Hanselminute tries not to waste your time!

We're listed in the iTunes Podcast Directory, so I encourage you to subscribe with a single click (two in Firefox) with the button below. For those of you on slower connections there are lo-fi and torrent-based versions as well.

This show was FULL of links, so here they are again. They are also always on the show site. Do also remember the archives are always up and they have PDF Transcripts, a little known feature.

Links from the Show

Sam Gentile (g08) Jeff Atwood (goj)
Hanzi Smatter (gou)
Dare Obasanjo (g09)
Mike Gunderloy (gok)
M.C. Hammer (gov)
Greg Hughes (goa)
Phil Haack (gol)
Kevin Smith (gow)
casey chesnut (gob)
Chris Sells (gom)
Overheard in the Office (goy)
Polymorphic Podcast (god)
Fritz Onion (gon)
Make Blog (goz)
Scott Guthrie (goe)
ASP.NET Blogs (goo)
Developing for Developers (gp2)
Presentation Zen (gof)
Channel 9 Videos (gop)
Joel Spolsky (gp3)
Raymond Chen (gog)
Michael Kaplan (gor)
Junfeng Zhang (gp4)
Debugging Tess (goh)
Wesner Moise (gos)
Powershell Blog (gp5)
Roy Osherove (goi)
The Daily WTF (got)
 BCL Team Blog 

Subscribe to my Podcast in iTunes

NEW COUPON CODE EXCLUSIVELY FOR HANSELMINUTES LISTENERS: The folks at XCeed are giving Hanselminutes listeners that is Coupon Code "hm-20-20." It'll work on their online shop or over the phone. This is an amazing deal, and I encourage you to check our their stuff. The coupon is good for 20% off any component or suite, with or without subscription, for 1 developer all the way up to a site license.

Our sponsors are XCeed, CodeSmith Tools, PeterBlum and the .NET Dev Journal. There's a $100 off CodeSmith coupon for Hanselminutes listeners - it's coupon code HM100. Spread the word, now's the time to buy.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

  • The basic MP3 feed is here, and the iPod friendly one is here. There's a number of other ways you can get it (streaming, straight download, etc) that are all up on the site just below the fold. I use iTunes, myself, to listen to most podcasts, but I also use FeedDemon and it's built in support.
  • Note that for now, because of bandwidth constraints, the feeds always have just the current show. If you want to get an old show (and because many Podcasting Clients aren't smart enough to not download the file more than once) you can always find them at http://www.hanselminutes.com.
  • I have, and will, also include the enclosures to this feed you're reading, so if you're already subscribed to ComputerZen and you're not interested in cluttering your life with another feed, you have the choice to get the 'cast as well.
  • If there's a topic you'd like to hear, perhaps one that is better spoken than presented on a blog, or a great tool you can't live without, contact me and I'll get it in the queue!

Enjoy. Who knows what'll happen in the next show?

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 bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Professional ASP.NET 2.0 Special Edition coming in September

July 18, 2006 Comment on this post [1] Posted in ASP.NET | Learning .NET | Internationalization | XML
Sponsored By

The secret's out. A 'special edition' (updated second edition) of Professional ASP.NET 2.0 is coming out in September.

It's a freaking beast. If you didn't get the book when it came out last year, now's the time to pre-order this one...

What's the difference between the first one and the Special Edition? About 300 pages of new content. It's about 1650 pages now, enough to beat someone up, if you use the Hardcover. And the Hardcover is only $37.79 to preorder the last time I checked at Amazon. Although, you could hurt someone with the Wrox Box.

Bill Evjen lead the charge on much of this new content, with Devin and I adding missing and/or new content in dozens of places throughout the book. There's an excerpt of the new section on the FileUpload Server Control up at Wrox.com.

Here's a brief list of what's updated and new in this new edition.

FOUR completely new chapters:

  • Introduction to the Provider Model
  • Extending the Provider Model
  • Localization
  • Instrumentation

TWO new appendixes:

  • Migrating ASP.NET 1.x Projects
  • Using Atlas

...and dozens of additions throughout all the existing chapters, including:

  • Class Designers and Open Test Bench
  • Build providers
  • A More Complex Callback Example
  • Uploading multiple files from the same page
  • As an example, in Chapter 11, DataBinding in ASP.NET 2.0 these changes:
    • Added SqlDataSource Configuration Wizard to add optimistic concurrency
    • Added SqlDataSource Events, Using the SqlDataSource with Oracle, AccessDataSource Control
    • Added GridView events that fire when the data binding occurs
    • Added Using the TemplateField Column in the GridView Control
    • Added Using the TemplateField's EditItemTemplate
    • Added Expressions and Expression Builder
  • Using Oracle as Your Database with ASP.NET 2.0
  • Added Generating Custom XML from SQL 2005

That's the list up through about the first 1/2 of the book...there's a pile more...

And there's an added DVD which is the Visual Studio 2005 Professional 180 day trial, and there's an added CD which contains more than 1000 pages of selected chapters from other Wrox .NET 2.0, ASP.NET 2.0, VB 2005, C# 2005, and SQL Server books.

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 bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Scott Hanselman: Developer Productivity Tools Video Part 2

July 18, 2006 Comment on this post [4] Posted in Reviews | PowerShell | XmlSerializer | TechEd | Speaking | Web Services | Tools
Sponsored By

Wroxvideo2When I was at TechEd I visited the Beantown.net INETA User Group and gave a (fairly ad-hoc) talk on Developer Productivity Tools. Jim Minatel loaned me his microphone and a copy of Camtasia and we recorded the talk. Thanks Jim!

It was a great crowd, a lot of fun. We had a number of "off the cuff" discussions about random stuff so I hope it doesn't take away from the gist of the talk.

The complete presentation was around 1 hour 45 minutes, so for online, Jim has split it into 4 segments. This week's segment is #2 and is available now and is about 20 minutes long. If you watch it in your browser, I recommend you double click on Windows Media Player to make the video go full screen. You can also download the full video.

It covers:

  • 00:00 Title
  • 00:15 Scott's introduction (repeated from the first video segment)
  • 00:40 XmlSerializer
  • 8:40 Interlude: SlickRun and Google
  • 9:10 Back to XmlSerializer
  • 10:40 SlickRun
  • 12:20 Explorer2 and Launching apps with Google Desktop Search
  • 13:20 Far - A Windows application like DOS Norton Commander
  • 14:35 Why Scott has so much stuff on his desktop
  • 16:40 Junctions and reparse points
  • 19:30 Closing credits

The remaining two segments for following weeks will cover roughly:

  • Week 3: Windows PowerShell - 33 minutes
  • Week 4: Active Words, Code Rush, SOAP Scope, XML doc viewer - 23 minutes

Here's a few notes about the video quality from Jim:

1. Why can't I fast forward or skip ahead through the video while it's streaming? Answer: We're running these off of a standard IIS server, not a Windows Media Server. IIS supports streaming, but not indexed playback during streaming to allow skipping ahead. If you want to do that, just download the whole video and all of the forwarding and timeline controls will be available in Windows Media Player.

2. Why isn't the video quality better? Is Camtasia to blame? No, Camtasia rocks. The raw videos I'm getting in Camtasia format are 100% clear, as if you were looking right at the presenter's monitor. The problem I've discovered is with the Windows Media Encoder. It just isn't well suited to on-screen presentation videos like this. The blurring and color blotching seems worst in Scott Hanselman's videos and I think I know why. When I watch the raw presentation, he's flying back and forth between open windows, background tools that pop up, and his desktop. It's just faster switching between very varied images than the encoder can seem to keep up with. I've twidled all the settings and got the best I can for now without doubling or tripling the file sizes. The other option would be to post an alternate version in Camtasia format and a link to download their playback codec [Scott: or a large FLV]. Because WMV is universal for my .NET developer audience, that has to be my common choice though.

There's also some other good screencasts up at Wrox. The growing list of videos is available at wrox.com. The first few videos in the series are:

I hope you enjoy them.

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 bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Portland Code Camp 2006 contracts and expands

July 18, 2006 Comment on this post [6] Posted in PowerShell | ASP.NET | Ruby | Speaking | Subversion | Web Services | Gaming
Sponsored By

CodeCamp has contracted to a single day, Saturday July 22nd, which should work nicely for folks who thought about going but didn't want to give up their weekend. However, the agenda is almost baked and it's looking amazing.

We've also got TWO Xbox 360s to give away. Two.

Additionally, in the evening at 5pm, there's a big BBQ Dinner and Party featuring the live music of rock/punk/funk/nerd band Mars Retrieval Unit. There's also a Frisbee Golf course! How could you NOT register for CodeCamp today

Check out this list of luminous folks from the NW who are speaking at CodeCamp this weekend! Register for FREE here.

CodeCamp 2006 Final Agenda

8:00am to 8:30am Registration
8:40am to 9:00am Opening Session
9:15am to 10:30am ASP.NET Architecture: Core ASP.NET
Rick Strahl
All
The .NET Compact Framework - An Introduction
Rory Blyth
Intermediate
Introduction to Ruby on Rails
Lucas Carlson
All
Mono for Cross-Platform .NET Development
Patrick Reilly
Beginner
.NET Refactoring
Wayne Allen
Intermediate
Automated Regression Hunts
Janis Johnson
All
Introducing Windows Workflow Foundation
Paul Mehner
Intermediate
PowerShell - A New Shell for a New Century
Scott Hanselman
All
10:45am to 12:15pm Using AJAX with ASP.NET
Ben Strackany
Intermediate
Diving Deeper: Windows Mobile and Data Access
Rory Blyth
Intermediate
An Exercise in Meta-Programming with Rails
Lucas Carlson
Intermediate
.NET Coding Standards & Best Practices
David McCarter
All
Web Testing with Team System
Jeff Levinson
All
End to End Automated Build Process
William Howell
Intermediate
Windows Workflow Foundation: Building Workflows
Manoj Agarwal
Intermediate
Web Service Software Factory Unleashed!
Chris Tavares
All
12:15pm to 1:15pm Lunch (provided)
1:15pm to 2:30pm Dealing with Long Running Requests in ASP.NET
Rick Strahl
All
Distributed File Sys via Steganography in VB.NET
Howard Hoy
Intermediate
IronRuby
Wilco Bauwer
Advanced
Adding a Plugin to Eclipse: Windows and Linux
Ted Kubaska
Beginner
Test Driven Development with Team System
Jeff Levinson
All
Better Requirements Definition with Use Cases
Ashu Potnis
All
XSLT You Can Use
Stuart Celarier
Beginner
Amazon's Simple Storage Service
Mike Culver
Intermediate
2:45pm to 4:00pm Using Cross-Domain AJAX Today
Lucas Carlson
Intermediate
Poker Bots for Fun and Profit!
Jeff Berkowitz
All
Unlock the Power of the WMI!
David McCarter
All
Practical Tips for the ASP.NET Developer
Walt Ritscher
Intermediate
Understanding Subversion
Stuart Celarier
Beginner
Dependency Injections for Healthier Unit Tests
Malcolm Anderson
Beginner
An Introduction to WCF for the Complete Beginner
Rory Blyth
Intermediate
Build an InfoPath/Web Services Solution
Don Shults
Intermediate
4:15pm to 5:30pm Taking ATLAS for a Ride
Rick Strahl
All
Game Maker for Kids (or just the kid in you)
Chris Brooks
Beginner
Atom, HTTP, and XMPP
Patrick Logan
Intermediate
Creating SQL Server Database Objects in .NET
Rob Boek
All
Team Edition for Database Professionals
Jeff Levinson
All
CodePlex - Online Open Source Development
Jonathan Wanagel
All
DotNetNuke Explored
Kelly White
Intermediate
Tell me your Distributed App Cares and Woes
Chris Sells
All
5:30pm to 9:30pm Barbeque Dinner and Camp Fiesta
live music - prizes, giveaways, and contests - folf tournament - lawn sports

 

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 bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

ScriptBlock and Runspace Remoting in PowerShell

July 15, 2006 Comment on this post [2] Posted in PowerShell | XmlSerializer | Web Services | Bugs
Sponsored By

When I first saw grokked PowerShell I wanted to be able to issue commands remotely. There's some great stuff going on with PowerShellRemoting over at GotDotNet, but that's remoting of the User Interface.

I want to be able to issue commands to many different machines in a distributed fashion.

After some pair programming with Brian Windheim, we set up a Windows Service that would get a string of commands and return a string that was the output o those commands. I could then issue remote commands, but the result at the client was just strings. I was in PowerShell but I'd just made the equivalent of PSEXEC for PowerShell...so basically I'd gotten nowhere.

Ideally I'd like to have behavior like this (but I don't):

using (Runspace myRunSpace = RunspaceFactory.CreateRunspace("COMPUTERNAME"))

{

    myRunSpace.Open();
}

But a Runspace is local and inproc. I don't see a really obvious and straightforward way to do this, considering that there's LOTS of internal and private stuff going on within PowerShell.

I liked that the string in, string out remoting stuff worked fine, but really I want to get Objects back from the remote machine. So, I started using Reflection to poke around inside System.Management.Automation.Serializer, but that got evil quickly. Truly evil.

Then I had an epiphany and remember the Export-CliXml cmdlet. It is the public cmdlet that uses the serializer I was trying to get to. It isn't the XmlSerializer. It's a serialized graph of objects with a rich enough description of those objects that the client doesn't necessarily need the CLR types. If reflection had a serialization format, it might look like this format.

Now, if I take the commands I was issuing to the remote "invoker" and export the result of the pipeline to this function XML format, I've just discovered my remoting server's wire format.

This RunspaceInvoker type is hosted in a Windows Service, but it could be in any Remoting hosting process. I'll likely move it inside IIS for security reasons. The app.config for my service looks like this:

<?xml version="1.0"  encoding="utf-8" ?>

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

  <system.runtime.remoting>

    <customErrors mode="Off"/>

    <application>

      <channels>

        <channel ref="http" port="8081"/>

      </channels>

      <service>

        <wellknown mode="SingleCall"

                   type="Hanselman.RemoteRunspace.RunspaceInvoker,
                   Hanselman.RemoteRunspace
" objectUri="remoterunspace.rem"/>

      </service>

    </application>

  </system.runtime.remoting>

</configuration>

Note the objectUri and port. We'll need those in a second. There's an installer class that I run using installutil.exe. I set the identity of the Windows Service and it starts up with net start RemoteRunspaceService.

This is the RunspaceInvoker (not the best name):

 public class RunspaceInvoker : MarshalByRefObject

 {

    public RunspaceInvoker(){}

 

    public string InvokeScriptBlock(string scriptString)

    {

        using (Runspace myRunSpace = RunspaceFactory.CreateRunspace())

        {

            myRunSpace.Open();

 

            string tempFileName = System.IO.Path.GetTempFileName();

            string newCommand = scriptString +
                " | export-clixml " + "\"" + tempFileName + "\"";

            Pipeline cmd = myRunSpace.CreatePipeline(newCommand);

 

            Collection<PSObject> objectRetVal = cmd.Invoke();

 

            myRunSpace.Close();

 

            string retVal = System.IO.File.ReadAllText(tempFileName);

            System.IO.File.Delete(tempFileName);

            return retVal;

        }

    }

 }

A command for the remote service comes into the scriptString parameter. For example we might pass in dir c:\temp as the string, or a whole long pipeline. We create a Runspace, open it and append "| export-clixml" and put the results in a tempFileName.

THOUGHT: It's a bummer I can't put the results in a variable or get it out of the Pipeline, but I think I understand why they force me to write the CLI-XML to a file. They are smuggling the information out of the system. It's the Heisenberg Uncertainly Principle of PowerShell. If you observe something, you change it. Writing the results to a file is a trapdoor that doesn't affect the output of the pipeline. I could be wrong though.

Anyway, this doesn't need to be performant. I write it to a temp file, read the file in and delete it right away away. Then I return the serialized CLI-XML to the caller.The client portion is two parts. I probably should make a custom cmdlet, but I didn't really see a need. Perhaps someone can offer me a reason why.

For simplicity I first made this RunspaceProxy. Remember, this is the class that the client uses to invoke the command remotely.

    public class RunspaceProxy

    {

        public RunspaceProxy()

        {

            HttpChannel chan = new HttpChannel();

            if (ChannelServices.GetChannel("http") != null)

            {

                ChannelServices.RegisterChannel(chan, false);

            }

        }

 

        public Collection<PSObject> Execute(string command, string remoteurl)

        {

            RunspaceInvoker proxy = (RunspaceInvoker)Activator.GetObject(
                   typeof(RunspaceInvoker), remoteurl);

            string stringRetVal = proxy.InvokeScriptBlock(command);

 

            using (Runspace myRunSpace = RunspaceFactory.CreateRunspace())

            {

                myRunSpace.Open();

                string tempFileName = System.IO.Path.GetTempFileName();

                System.IO.File.WriteAllText(tempFileName, stringRetVal);

                Pipeline cmd = myRunSpace.CreatePipeline(
                    "import-clixml " + "\"" + tempFileName + "\"");

                Collection<PSObject> retVal = cmd.Invoke();

                System.IO.File.Delete(tempFileName);

                return retVal;

            }

        }

    }

I'm using the HTTP channel for debugging and ease of use with TcpTrace. The command to be executed comes in along with the remoteUrl. We make a RunspaceInvoker (the class we talked about a second ago) on the remote machine and it does the work via a call to InvokeScriptBlock. The CLI-XML comes back over the wire and now I have to make a tempfile on the client. Then, in order to 'deserialize' - a better word would be re-hydrate - the Collection of PSObjects, I make a local Runspace and call import-clixml and poof, a Collection<PSObject> is returned to the client. I delete the file immediately.

Why is returning real PSObjects so important when I had strings working? Because now I can select, sort, and where my way around these PSObjects as if they were local - because they are. They are real and substantial. This will allow us to write scripts that blur the line between the local admin and remote admin.

Now, all this has been C# so far, when does the PowerShell come in? Also, since I've worked so hard (well, not that hard) to get the return values integrated cleanly with PowerShell, what's a good way to get the remote calling of scripts integrated cleanly?

My first try I made a function RemoteInvoke() that took a command string. It worked, but felt tacky. Then I remembered how Jeffrey Snover said to look to Type Extensions when adding functionality rather than functions and cmdlets.

I made a My.Types.ps1xml file in my PSConfiguration directory and put this in it:

<Types>

  <Type>

    <Name>System.Management.Automation.ScriptBlock</Name>

    <Members>

      <ScriptMethod>

        <Name>RemoteInvoke</Name>

        <Script>

          if ($GLOBAL:remoteUrl -eq $null) { throw 'Set $GLOBAL:remoteUrl first!' }


          [System.reflection.assembly]::LoadWithPartialName("System.Runtime.Remoting") |
               out-null

          $someDll = "C:\foo\Hanselman.RemoteRunspace.dll"

          $asm = [System.Reflection.Assembly]::LoadFrom($someDll) | out-null


          $runspace = new-object Hanselman.RemoteRunspace.RunspaceProxy


          $runspace.Execute([string]$this, $GLOBAL:remoteUrl);

        </Script>

      </ScriptMethod>

    </Members>

  </Type>

</Types>

Then called Update-TypeData My.Types.ps1xml (actually it's in my profile so it happens automatically.)  This file adds a new method to the ScriptBlock type. A ScriptBlock is literally a block of script. It's a very natural "atom" for us to use.

NOTE: I'd like to have the RemoteUrl be a parameter to the RemoteInvoke ScriptMethod, but I can't fine really any documentation on this. I'll update it when I figure it out, but for now it uses a $GLOBAL variable and freaks out if it's not set.

The RemoteInvoke loads the .NET System.Runtime.Remoting assembly, then it loads our Proxy assembly. Then it calls Execute, casting the [ScriptBlock] to a [string] because the Runspace takes a string.

For example, at a PowerShell prompt if I do this:

PS[79] C:\> $remoteUrl="http://remotecomputer:8081/RemoteRunspace.rem"

PS[80] C:\PS[80] C:\> 2+2
4

PS[81] C:\> (2+2).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType

PS[82] C:\> {2+2}.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    ScriptBlock                              System.Object

PS[83] C:\> {2+2}
4

PS[84] C:\> {2+2}.RemoteInvoke()
4

PS[85] C:\>
{2+2}.RemoteInvoke().GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType

Note the result of the last line. The value that comes out of RemoteInvoke is an Int32, not a string. The result of that ScriptBlock executing is a PowerShell type that I can work with elsewhere in my local script.

Here's the CLI-XML that went over the wire (just to make it clear it's not XmlSerializer XML):

<Objs Version="1.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">

  <I32>4</I32>

</Objs>

This 2+2 stuff is a terse and simple example, but this technique works with even large and complex object graphs like the FileInfos and FileSystemInfo objects that are returned from dir (get-childitem).

Remoterunspace

In this screenshot we do a get-process on the remote machine then sort and filter the results just as we would/could if the call were local.

My WishList for the Next Version of PowerShell

  • All this stuff I did, built in already with security and wonderfulness.
  • All the stuff in PowerShellRemoting, with security and wonderfulness.
  • Some kind of editor or schema installed in VS.NET for editing My.Types.ps1xml.
  • TabExpansion for all Types in the current AppDomain (this of course, already done by MonadBlog and MOW).

Thanks again to Brian Windheim for the peer programming today that jump started this!

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 bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

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