October 2005 - Posts

Added support for Monad scripts to CodeHTMLer

For all those people posting Monad scripts to their blogs you might be interested in making your scripts look better by using CodeHTMLer. Just paste in your code script and select MSH as the language and it will output some stylized HTML that can easily be copied into your blog post. Of course you can use it to post code for most languages. Its what I use to colorize all my code samples.

Posted by puzzlehacker | 1 comment(s)
Filed under: , ,

Monad script to convert your doskey macros to Monad functions

Last week I talked about how I wanted to write a script to convert my doskey macros into Monad functions. I used this opportunity to learn about writing scripts in Monad. I must say I'm impressed so far, it has been pretty easy to pickup. The one thing that I kept getting burned by and that I don't care for much is the comparison operators. I don't like using -lt, -gt, etc, I'm too used to <, >. At anyrate here is the code (keep in mind that I'm new to Monad scripting so if I did something wrong go easy on me ;) with that said I'm open to suggestions).

# $macro should be of the form <macroname>=<macro> where <macro> supports 
# everything doskey does plus traditional environment variables
function global:doskey([string] $macro, [bool] $verbose=$false)
{
    if($macro -match "^(?<name>[^=]+)=(?<macro>.+)$")
    {
        $cmd = $matches['macro'];
        
        # Escape the quotes
        $cmd = $cmd.Replace('"', '`"').Replace('`'', '```'');
        
        # Replace $1-$9 doskey variables
        for($i = 1; $i -lt 9; $i++)
        {           
            $cmd = $cmd.Replace('$' + $i, '`'+$args[' + ($i-1) + ']+`'');
        }
            
        # Replace $* doskey variable
        $cmd = $cmd.Replace('$*', '`'+$args+`'');
        
        # Replace $T doskey (i.e. command splitter);
        $cmd = $cmd.Replace('$T', '; & ');
        
        # Replace %PATH% environment vars $ENV:PATH
        $cmd = [System.Text.RegularExpressions.Regex]::Replace`
            ($cmd, '%(?<var>.*?)%', '`'+$ENV:${var}+`'');
        
        # wrap the cmd with a call to invoke-command
        $cmd = 'invoke-command(`'& ' + $cmd + '`')';
        
        # Cleanup the empty quotes
        $cmd = $cmd.Replace('+`'`'', '');
        
        # Create a function that represents the doskey macro
        $func = 'function global:' + $matches['name'] + ' { ' + $cmd + ' }';
        
        if($verbose) { echo $func; }
        invoke-command($func);
    }
    else
    {
        echo "ERROR: $macro is not of the form <name>=<macro>";
    }
}

function global:doskeyfile([string] $macrofile, [bool]$verbose=$false) 
{     
    if($macrofile.Length -eq 0 -or !(test-path $macrofile)) 
    { 
        echo "Error: File [$macrofile] does not exist"; 
        return; 
    }
    
    foreach($macro in (get-content $macrofile)) 
    {
        doskey $macro $verbose;
    }
    echo "Finished processing $macrofile."
}

To use this you can save those functions in a .msh script file and then run that script from the prompt. Here are a couple examples of doskey macros and what they get converted to.

Doskey macros

ie="%PROGRAMFILES%\internet explorer\iexplore.exe" $*
echo2=echo "1:$1" $T echo "2:$2"

Monad functions

function global:ie 
	{ invoke-command('& "'+$ENV:PROGRAMFILES+'\internet explorer\iexplore.exe" '+$args) }
function global:echo2 
	{ invoke-command('& echo "1:'+$args[0]+'" ; &  echo "2:'+$args[1]+'"') }

Enjoy!

[Cross posted on my personal blog]

Posted by puzzlehacker | with no comments
Filed under: ,

Monad A.K.A. Microsoft Command Shell

I've finally got some time to start playing with Monad (Microsoft's new command shell). If you are interested the Monad blog has links to download Monad beta2.

I have been using it for about a week now and the biggest hurdle has been getting my shell environment setup properly (i.e. mainly my environment variables and my doskey macros). Setting up the environment through .bat files is one of the backwards compatibility issues of Monad according to this tech chat. It is an issue because Monad does NOT interpret .bat files it just passes them to cmd.exe, so any environment variables that get set by a .bat file are not persisted.

In order to get around the environment variable problem I just start cmd.exe like I normally do but now at the end of my startup script I make a call to msh.exe. Since msh.exe is child process of cmd.exe it inherits all the environment variables.

Now the other major hurdle for me was to get all my doskey macros up and running under Monad. At first I thought I could just translate each doskey macro into a Monad alias. However, a Monad alias can only reference a cmdlet ;(. After reading some of the Monad documentation I found that the preferred way to do this is to create functions for each doskey macro.  I thought it would be interesting (and educational) for me to create a Monad script to translate my doskey macro files into Monad functions. I've got my script working pretty well and as so as I clean it up a little I will post it for all to use.

With these two hurdles out of the way I can now use Monad as my primary command shell. Stay tune I plan on posting more about Monad and my experiences using it.

[Cross posted on my personal blog]

Posted by puzzlehacker | with no comments
Filed under:
More Posts