June 2006 - Posts

In this personal webcast episode called "AzMan for dummies", I'm showing you how to use AzMan (Authorization Manager) to implement role-based security in your managed code application (18 minutes in length).

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Some time ago I published an example of how to create a PowerShell cmdlet on my blog, "Windows PowerShell - Make your application manageable - Write your first cmdlet". As a reader pointed out, the creation of a custom shell is no longer required. At the time of writing the .NET Magazine article (Dutch), the PowerShell software hadn't reached the RC stage and I hadn't much time to mess around with the SnapIn-methodology, so it wasn't incorporated in the original article (we were happy we could get the MSH to PowerShell rename in the published article in time, as well as doing the required incompatibilies spotting to have the original code compile on the RC bits).

Today, I'm going to point out how to modify the code from the "Windows PowerShell - Make your application manageable - Write your first cmdlet" post (with the FindString cmdlet) to a SnapIn that can be registered in PSH shells on your machine, without the need for creating a new custom shell using make-shell. For the original post, see the link above. Below you'll find the stripped-down and updated version of this post using a snap-in approach.

Your first cmdlet (snap-in)

Step 1 - Create a Visual Studio project

To kick off, create a new class library project (e.g. in C#) and give it a meaningful name, for example FindString. Next, add a reference to the System.Management.Automation.dll assembly which you can find in %programfiles%\Windows PowerShell\v1.0. Include a reference to System.Configuration.Install as well.

Step 2 - Declare the cmdlet class

Next, it's time to declare our cmdlet-acting class as follows (updated using VerbsCommon, thx to Lee for his comment):

using System.Management.Automation;

[
Cmdlet(VerbsCommon.Get, "Matches"
)]
public class FindString :
PSCmdlet
{
}

The class has to inherit from PSCmdlet and has to be annotated with the CmdletAttribute attribute as you can see.

Step 3 - Parameterize the cmdlet

private string pattern;

[
Parameter(Mandatory=true
, Position=0)]
public string
Pattern
{
   get { return
pattern; }
   set { pattern = value
; }
}

private string
[] fullName;

[
Parameter(Mandatory=true, Position=1, ValueFromPipelineByPropertyName=true
)]
public string
[] FullName
{
   get { return
fullName; }
   set { fullName = value
; }
}

The first parameter is called Pattern and will contain the regular expression pattern we'll look for. The second one is called FullName and can contain more than one filename, which can be fed in through the pipeline by the property name. That means that cmdlets that return objects with a public property called FullName can be linked to this cmdlet by means of piping (|), e.g. from the get-childitem cmdlet.

Step 4 - Implement the core functionality

The core of the cmdlet's implementation goes in the ProcessRecord method. The following is a pretty short implementation of our matching logic relying on System.Text.RegularExpressions and System.IO to read files, and System.Collections.Generic for the List class:

protected override void ProcessRecord()
{
   List<Match> matches = new List<Match>();

   ProviderInfo
info;
   foreach (string item in FullName)
      foreach (string file in GetResolvedProviderPathFromPSPath(item, out info))
         using (StreamReader sr = File.OpenText(file))
            matches.Add(
new Match(file, Regex.Matches(sr.ReadToEnd(), pattern)));

   WriteObject(matches);
}

The call to WriteObject returns the result to the pipeline for further processing; other cmdlets could use our output as their input, or the user can just feed this in to cmdlets like format-list (or work with variables, etc). To aid our implementation, we've created a simple Match class:

public class Match
{
  
public Match(string file, MatchCollection
matches)
   {
     
this
.file = file;
     
this
.matches = matches;
   }

  
private MatchCollection
matches;

  
public MatchCollection
Matches
   {
     
get { return
matches; }
     
set { matches = value
; }
   }

   private string
file;

   public string
File
   {
     
get { return
file; }
     
set { file = value
; }
   } 
}

Step 5 - Create a snap-in and deploy it

Basically, a snap-in is a wrapper around one or more cmdlets that can be "imported" in a PowerShell instance. Instead of creating a separate shell (using make-shell) one can rely on snap-ins to bring custom cmdlets to Windows PowerShell.

The core of the snap-in methodology lies in the CustomPSSnapIn class from the System.Management.Automation namespace. This class inherits from System.ComponentModel.Component and thus it can be used in combination with instalers in .NET (using installutil.exe). That's how snap-ins work. In order to bring this technology to our own cmdlet-implementation, we have to do the following (with using directives for the whole codefile):

using System;
using System.ComponentModel;
using System.IO;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Text.RegularExpressions;

#region
Snap-in

[
RunInstaller(true
)]
public class FindStringPSSnapIn :
CustomPSSnapIn
{
     private Collection<CmdletConfigurationEntry> cmdlets = new Collection<CmdletConfigurationEntry
>();
    
private Collection<ProviderConfigurationEntry> providers = new Collection<ProviderConfigurationEntry
>();
    
private Collection<TypeConfigurationEntry> types = new Collection<TypeConfigurationEntry
>();
     private Collection<FormatConfigurationEntry> formats = new Collection<FormatConfigurationEntry
>();

     public FindStringPSSnapIn() : base
()
     {
          cmdlets.Add(
new CmdletConfigurationEntry("get-matches", typeof(FindString), null
));
     }

     public override string
Name
     {
          get { return "FindStringPSSnapIn"
; }
     }

     public
override string Vendor
     {
          get { return "BdsSoft"
; }
     }

     public
override string Description
     {
          get { return "This snap-in contains the FindString cmdlet."
; }
     }

     public
override Collection<CmdletConfigurationEntry> Cmdlets
     {
          get { return
cmdlets; }
     }

     public override Collection<ProviderConfigurationEntry
> Providers
     {
          get { return
providers; }
     }

     public override Collection<TypeConfigurationEntry
> Types
     {
          get { return
types; }
     }

     public override Collection<FormatConfigurationEntry> Formats
     {
          get { return
formats; }
     }
}

#endregion

This might look quite some code at first glance, but it's really straightforward. All that you have to do over here is override from CustomPSSnapIn and provide code that returns a vendor, a name, a description and a few collections through properties. Those collections hold references to cmdlets, providers, types and format that are included in the snapin. In this case, we only include one single cmdlet which is done by preparing a Collection (from System.Collections.ObjectModel) of CmdletConfigurationEntry (from System.Management.Automation.Runspaces) instances. In our case on single entry is enough, holding the name (get-matches) and type info (typeof(FindString)). The last constructor parameter isn't used as we don't have a help file associated with the cmdlet.

Compile the whole stuff and open a Visual Studio 2005 Command Prompt (or a PS prompt if you're ambitious) and run installutil.exe against the compiled .dll file (note: on Vista, you'll have to evelate the Visual Studoo 2005 Command Prompt to run with administrative credentials in order to allow installutil.exe to write to the HKLM registry hive):

C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug>installutil.exe FindString.dll
Microsoft (R) .NET Framework Installation utility Version 2.0.50727.88
Copyright (c) Microsoft Corporation.  All rights reserved.


Running a transacted installation.

Beginning the Install phase of the installation.
See the contents of the log file for the C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug\FindString.dll assembly's progress.

The file is located at C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug\FindString.InstallLog.
Installing assembly 'C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug\FindString.dll'.
Affected parameters are:
   logtoconsole =
   assemblypath = C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug\FindString.dll
   logfile = C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug\FindString.InstallLog

The Install phase completed successfully, and the Commit phase is beginning.
See the contents of the log file for the C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug\FindString.dll assembly's progress.

The file is located at C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug\FindString.InstallLog.
Committing assembly 'C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug\FindString.dll'.
Affected parameters are:
   logtoconsole =
   assemblypath = C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug\FindString.dll
   logfile = C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug\FindString.InstallLog

The Commit phase completed successfully.

The transacted install has completed.

C:\Users\Bart\Documents\Visual Studio 2005\Projects\FindString\FindString\bin\Debug>

Step 6 - Testing time

Launch the Windows PowerShell and display a list with registered snap-ins as follows:

PS C:\Users\Bart\Documents> get-pssnapin -registered


Name        : FindStringPSSnapIn
PSVersion   : 1.0
Description : This snap-in contains the FindString cmdlet.

As you can see, the snap-in was registered successfully. However, get-matches still doesn't work:

PS C:\Users\Bart\Documents> get-matches
'get-matches' is not recognized as a cmdlet, function, operable program, or script file.
At line:1 char:11
+ get-matches <<<<

To make it available, you have to call add-pssnapin, as displayed below:

PS C:\Users\Bart\Documents> add-pssnapin FindStringPSSnapIn

Now get-matches should work:

PS C:\Program Files\Windows PowerShell\v1.0> get-matches Wmi about_Alias.help.txt

Matches                                 File
-------                                 ----
{Wmi, Wmi, Wmi}                         C:\Program Files\Windows PowerShell\...

Step 7 - Taking it one step further

Performing add-pssnapin every time again doesn't boost your productivity. In order to provide easier access to your shell configuration you can export the settings using export-console:

PS C:\Users\Bart> export-console MyShell

This creates a file called MyShell.psc1 that contains the following piece of XML:

<?xml version="1.0" encoding="utf-8"?>
<PSConsoleFile ConsoleSchemaVersion="1.0">
  <PSVersion>1.0</PSVersion>
  <PSSnapIns>
    <PSSnapIn Name="FindStringPSSnapIn" />
  </PSSnapIns>
</PSConsoleFile>

You can now open your customized shell using powershell.exe by specifying the psc1-file as a parameter (or create a shortcut of course):

powershell -PSConsoleFile c:\users\bart\myshell.psc1

Have fun!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

So here's a new tool for my personal toolbox: a simple MD5 checksum calculator for files, written in .NET 2.0.

The little "open Visual Studio 2005 trigger" story: A friend of mine reported a problem with his Vista Beta 2 installation which reported corruption, so the obvious first check was to calculate the MD5 checksum. However, a 5-seconds internet search didn't provide me with a simple tool, so I took the do-it-yourself-in-5-minutes approach and wrote such a tool myself.

In the end, the code comes down to:

string f = args[0];
MD5 md5 = MD5
.Create();
StringBuilder sb = new StringBuilder
();

using
(FileStream fs = File.Open(f, FileMode.Open))
{
     foreach (byte b in
md5.ComputeHash(fs))
          sb.Append(b.ToString(
"x2"
).ToLower());
}

Console.WriteLine("MD5 checksum: {0}", sb.ToString());

but of course I made it a little more fancy, with the new System.Console capabilities to put a "spinner" and the elapsed time on the screen (using System.Diagnostics.Stopwatch) while calculating the checksum (you know, a little thingie that does | / - \ continiously) using a background thread. I also found out the following thanks to IntelliSense:

Console.TreatControlCAsInput = true;

The result is a little .exe that can be downloaded over here. I'll create a PowerShell cmdlet for the same task as well, which I'll publish over here too.

Here's the Windows Vista Ultimate Beta 2 x86 DVD ISO MD5 output (elapsed time for an Intel Centrino Duo 2.16 GHz + 2GB RAM running Windows Vista Beta 2):

MD5 File Checksum Calculcator 1.0.0.0
Copyright (C) BdsSoft 2006. All rights reserved.

Calculating checksum...

Results
-------
File:         d:\Downloads\en_windows_vista_beta2_x86_dvd.iso
MD5 checksum: 0e733ab1a8e8ff9a8684fd3639332773
Elapsed time: 00:01:06.2558607

Another example of BCL power and richness...

Update: A SHA1 checker is available too over here (using the HashAlgorithm.Create factory method this was a matter of seconds). Output for Windows Vista Ultimate Beta 2 x86 DVD ISO (matches the MSDN Subscribers SHA1 checksum):

SHA1 File Checksum Calculcator 1.0.0.0
Copyright (C) BdsSoft 2006. All rights reserved.

Calculating checksum...

Results
-------
File:          d:\Downloads\en_windows_vista_beta2_x86_dvd.iso
SHA1 checksum: 2404153a60d81103861b876878893222a5529d3a
Elapsed time:  00:01:39.4758180

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Rather calm on my blog lately due to a high workload. So, let's give a little overview of some recent hot releases that are worth to check out in case of some spare free time. This summer, I'll try to put some more serious posts on the web over here.

Here we go:

  • First of all, there's of course Windows Vista Beta 2 and the 2007 Microsoft Office System Beta 2 which are both available through MSDN (of course) and via the Customer Preview Program (CPP) on http://www.microsoft.com/betaexperience and on http://www.microsoft.be/testdrive for Belgian people. As I mentioned over here a while ago, I'm running those two (together with Windows Live Messenger, see further) on a day-to-day basis without complaints (so I have to deny all the stuff Paul Thurott is saying on his WinSuperSite - or I'm just very lucky it runs rocket fast on my machine).
  • Developers, don't forget to download the WinFX Runtime Components Beta 2 over here as well as the Visual Studio Extensions (a.k.a. "Fidalgo") and Workflow Foundation stuff. Of course the SDK will be a real bandwidth limits killer and can be found over here.
  • Graphic folks (working with WPF, the web or just bitmaps and vector graphics) will be pleased to see the May CTP builds of the Expression tools: Interactive Designer, Graphic Designer, Web Designer.
  • Windows Live Beta website refresh on http://www.live.com looks very promising and has become my homepage for a couple of days now. Of course I've set Windows Live as the default search provider in Internet Explorer 7 (a search is now reduced to CTRL-E to jump to the search box and entering the keywords - or, on Vista, by entering the search keywords right in the start menu's search box).
  • For those of you running Windows XP or Windows Server 2003, Internet Explorer 7 Beta 2 should be on the download list. Check it out over here: www.microsoft.com/ie, and don't forget to keep an eye on the IE team blog on http://blogs.msdn.com/ie.
  • For the communication stuff I'm running on Windows Live Messenger (the successor of MSN Messenger) which can be grabbed over here (RTM release).Check out other great Live Ideas on http://ideas.live.com as well.
  • Visual Studio Team Edition for Database Professionals (a.k.a. "Data Dude", more info over here) has reached the CTP3 stage and can be downloaded right now. Pay Gert's blog a visit too on http://blogs.msdn.com/gertd and listen to his first podcast on sqldownunder.
  • Today the .NET Framework Compact Framework 2.0 SP1 was released as well. It's available on the Microsoft Download site.
  • A few days ago, the next generation Data Access vision has been released to the web on MSDN. Pablo Castro provides the links on the data access blog. The May 06 LINQ CTP can be downloaded too, including the C# 3.0 and VB 9.0 compilers. Anders and Sam give more information on ADO.NET vNext, Entities, providers and LINQ on Channel 9.
  • Right from the Microsoft Research folks, the Microsoft Robotics Studio CTP was released to the web a couple of days ago. All useful information as well as links to the download can be found via http://msdn.microsoft.com/robotics.
  • MSBee brings MSBuild to .NET Framework 1.x developers and can be grabbed from CodePlex. Other interesting releases include the Team Foundation Server Admin Tool (download) and the Managed Stack Explorer (download).
  • ASP.NET Atlas shouldn't be missing on this list too. Check it out here.
  • Exchange Server 2007 Beta 2 will be publicly available too in a while, if you register to get the beta on the Exchange site. IT folks will want to check out the System Center site too, for updates on the next releases of MOM (or should I say System Center Operations Manager now?) and other family members such as DPM and SMS. Find it over here: http://www.microsoft.com/windowsserversystem/systemcenter.
  • Windows PowerShell RC1 shouldn't be missing on your have-to-download list too. Download it here.
  • I blogged about SQL Server 2005 Everywhere Edition a couple of days ago. More information over there.
  • Last but not least, check out http://connect.microsoft.com to get a glimpse of other available programs, such as BDD (Business Desktop Deployment) with Windows PE 2.0, WDS (Windows Deployment Services) and WIM (Windows Imaging Format) stuff as well as USMT, ACT 5.0 and the WAIK. Other stuff includes BizTalk 2006 R2, Phoenix, Speech Server 2007, Windows Server 2003 SP2, Windows Server 2003 Compute Cluster Edition and much much more.

I'm sure I've forgotten a bunch of great releases in this list but I'm sure you'll find those exciting materials when you need them :-).

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

A few days ago, Microsoft released the first CTP of SQL Server 2005 Everywhere Edition, the successor to SQL Server CE. You can download it over here, as well as the mandatory Books Online that accompany every SQL Server release :-). Check out the SQL Mobile blog as well, on http://blogs.msdn.com/sqlmobile/.

So, what's in a name. Basically, SQL Server Everywhere is targeted at smart devices (Pocket PC 2003, Windows CE 5.0 and WM 5.0 based devices) as well as Tablet PC s, and provides a compact but feature-rich database engine. By means of subscriptions, it's possible to synchronize this (off-line) database with a "big brother" in SQL Server 2005. Furthermore, the product is free to redistribute with your applications (which can be automated using VS2005 features such as ClickOnce).

For a complete feature list, check out the BOL.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Formerly called WinFX, the official name of the piece of software art is now called .NET Framework 3.0. The technology is based on .NET Framework 2.0 and bundles the following next-generation internet-enabling technologies that are considered key pillars of the Vista wave (but will be available for XP and W2K3 as well):

  • Windows Communication Foundation (WCF) - formerly called Indigo
  • Windows Presentation Foundation (WPF) - formerly called Avalon
  • Windows Workflow Foundation (WF)
  • Windows CardSpace (WCS) - formerly called InfoCards

Quite a bunch of .NET heroes are blogging about this, including 'Soma' and Jason Zander. Notice LINQ stuff goes in the Orcas timeframe, which is coming after Vista.

More information on the brand new site www.netfx3.com. And now I'm in the mood of giving away links to interesting sites, take a look at www.iisseven.com as well for information on the next-generation webserver technology: IIS 7.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

So, here we are, live on Vista Beta 2 and running the 2007 Microsoft Office System Beta 2 for day-to-dat activities. Last weekend I moved from the previous Vista CTP build - which was running on a rather small partition just for sake of demos - to the beta 2 stage running on my main partition. And it's just running soooo smoothly, I absolutely love it. The same holds for the 2007 Office tools which I'm working with every day right now. One thing I love about Word 2007 is the new equation editor, as I'm writing a lot of math the last couple of weeks.

Oh, and I also enabled BitLocker Drive Encryption (I never trusted that before the beta stage, shame on me), so my personal stuff is absolutely secure against theft (the key is kept on a USB stick, as I don't have a TPM in my machine).

Usually I don't show my desktop to everyone, but here's a little screenshot (click to enlarge).

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

More Posts