Feeds:
Posts
Comments

Blog has moved! You should check this post out on kevinpelgrims.com

I wrote this entry last year September, but for several reasons the post and the code never made it to the interwebs. After running into it again I decided to post it anyway and upload the code to Codeplex. So, here goes!

A while back I created this PowerShell script to remotely manage services (see Remote Service Manager), a bit later I made the available help a bit more professional (see Add help to your own PowerShell scripts). Now I was thinking it would be cool to create an interface in .NET for this script. So I started developing a WinForm application around the script. Initially, it looked like this:

This was the first (working) prototype of the RSM-GUI. But then I started thinking it would be much cooler to create an application that can run all scripts, even those with parameters. I started thinking about how to do this and actually it didn’t seem so hard. I started by creating a form that can execute simple PowerShell commands and show the output, then added support for running scripts stored on the hard drive. For the parameters I just made sure they are all displayed in a grid, where you can give them a value by simply typing something in. And that was it! I now have a Windows application that can run scripts on a more visual way. Now you can simply load the script with an OpenFileDialog and see what parameters are available. If you still don’t fully understand how the script works, you can press the Get-Help button to display the help information in the outputbox.

And now, it looks like this:

PowerShell Script Commander help function

PowerShell Script Commander running the RSM script, with parameters

A lot of work needs to be done to make this more reliable and to make it work with all scripts on the planet 😉 But I think it’s already pretty cool.

The source code can be found here: http://pscommander.codeplex.com/

Advertisements

Blog is moving! You should check this post out on kevinpelgrims.com

When you are installing MapGuide OS and you encounter following error:

Failed while processing WebVirtualDirs

Fear not, because here is the solution!

The problem is with how MapGuide OS is trying to install its websites. This is not configurable during the installation and will by default be installed in a website called “Default Web Site” on port 80. This is the website that is created for you when IIS is installed. If you change the name of the website or the port number, the MapGuide OS installation freaks out!
So the simplest solution is to create a website called “Default Web Site” and have it run at port 80. You can then edit those settings after the installation is done without any problems, so you can still run the MapGuide OS websites on a different port.
If you need some more explanation, this is an interesting thread http://osgeo-org.1803224.n2.nabble.com/Installation-error-td3858392.html with a good answer by Jason Birch.

Blog is moving! You should check this post out on kevinpelgrims.com

Autodesk Infrastructure Map Server logoI encountered a problem today while working on a website that uses Autodesk Infrastructure Map Server 2012 (aka MapGuide) and it’s API. To programmatically create a new layer on a map it seems to be recommended to use the LayerDefinitionFactory that is provided with the installation of the server. Now the problem is that this factory is only provided in PHP and I am working in C#. I could install PHP on the server and try to get all freaky with .NET-PHP communication. But it seemed easier to just port the factory to C# (it’s not that big anyway).

I wrote some basic functions and then only converted the stuff I need for this particular project, but it should be very easy to convert the other functions when you need them. I did not rewrite the sprintf() function that can be found in PHP, because it is a lot easier to use String.Format() if you adjust the template files. So, this is what one of the templates now look like after changing all the occurrences of %s to the C# version with {0}, {1}, etc.:

<?xml version="1.0" encoding="UTF-8"?>
<LayerDefinition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="LayerDefinition-2.3.0.xsd" version="2.3.0">
  <VectorLayerDefinition>
    <ResourceId>{0}</ResourceId>
    <FeatureName>{1}</FeatureName>
    <FeatureNameType>FeatureClass</FeatureNameType>
    <Geometry>{2}</Geometry>
    {3}
  </VectorLayerDefinition>
</LayerDefinition>

And here is the code:

using System;
using System.Text;
using System.IO;

/// <summary>
/// Factory for MapGuide layer definitions.
/// </summary>
public class LayerDefinitionFactory
{
	string templatePath;

	public LayerDefinitionFactory(string path)
	{
		templatePath = String.Concat(path, "{0}.templ");
	}

	/// <summary>
	/// Read the template required for the layer definition.
	/// </summary>
	/// <returns>Returns (a part of) the layer definition in XML.</returns>
	private string ReadTemplate(string filename)
	{
		StreamReader reader = new StreamReader(String.Format(templatePath, filename));
		string templateDefinition = reader.ReadToEnd();
		reader.Close();
		return templateDefinition;
	}

	/// <summary>
	/// Create a new layerdefinition.
	/// </summary>
	public string CreateLayerDefinition(string resourceId, string featureClass, string geometry, string featureClassRange)
	{
		string[] values = new string[] { resourceId, featureClass, geometry, featureClassRange };
		return String.Format(ReadTemplate("layerdefinition"), values);
	}

	/// <summary>
	/// Create a new line rule for the layer definition.
	/// </summary>
	public string CreateLineRule(string lineStyle, string thickness, string color)
	{
		string[] values = new string[] { lineStyle, thickness, color };
		return String.Format(ReadTemplate("linerule"), values);
	}

	/// <summary>
	/// Create the line type style with line rules for the layer definition.
	/// </summary>
	public string CreateLineTypeStyle(string lineRules)
	{
		string[] values = new string[] { lineRules };
		return String.Format(ReadTemplate("linetypestyle"), values);
	}

	/// <summary>
	/// Create the scale range for the layer definition.
	/// </summary>
	public string CreateScaleRange(string minScale, string maxScale, string typeStyle)
	{
		string[] values = new string[] { minScale, maxScale, typeStyle };
		return String.Format(ReadTemplate("scalerange"), values);
	}
}

Blog is moving! You should check this post out on kevinpelgrims.com

Testing e-mails sent from .NET code

It’s always a big hassle to test sending e-mails from websites or applications written in .NET (or any other platform/language). Your inbox gets flooded or even worse, customers’ inboxes get flooded. Or you’ve set up a dummy account to test if e-mails get sent. But sometimes e-mail addresses need to be picked up dynamically depending on certain parameters, from a database, for example. Testing gets annoying here. You can debug and check if the address you want is the right one, you can bother people to check their inbox everytime you’re testing, ..

There has to be a better solution, right? Yes there is!

Developers, let’s start testing!

Thanks to this little tool I found last week, this has become a lot easier. It’s actually been around for about 2,5 years already. Too bad I never found out about it earlier 🙂

UPDATE: Just found out about this thing, which is on CodePlex, so we can play with the code! It’s called smtp4dev and can be found here: http://smtp4dev.codeplex.com/.

Here are URLs to the 3 blogposts by Donovan Brown about the little server app:

Note: Don’t download the application from the first blogpost! The post about POP3 has the latest version.

Be sure to read the documentation, it has everything you need to know about using this tool.

Too bad Donovan has never put this on Codeplex (or any other open source repository), because I think we can all imagine some nice features to add to this little useful thing..

Blog is moving! You should check this post out on kevinpelgrims.com

What is parallel programming?

Sequential programming assumes a set of instructions that are executed sequentially by a single processor. The point of parallel programming is to program systems that consist of multiple processors and therefore have multiple simultaneous instruction streams.

Why do we need it?

The clock speeds of chips are no longer increasing. All future improvements in computer speed will come from parallelism. In other words, more and more processors are being added to new computers. These chips enable software to do multiple tasks at the same time. Each processor it’s own task. So one way to make applications run faster, is to use parallel programming.
This is not the same as multithreading, though. Multithreading can be done on a single core CPU. In that case, two threads can never execute at the same time on the CPU. The operating system (which takes care of multi-threading) divides the time of the processor between all open threads. When you have too many executing threads at once, your system slows down as there is not enough time for all the threads to run at full speed.

Concurrent vs Parallel

To be clear, parallel programming is not the same as concurrent programming. As they say, a picture says more than a thousand words:

Comparison between concurrent and parallel

Well, maybe it could use some explanation.
Concurrent applications tend to create a thread that handles a whole series of tasks. Most of the time these concurrent applications create threads because they need an isolated process for a concurrent event.
Parallel applications divide a process into small tasks that are executed on seperate threads. Because the tasks are small, the threads can be divided evenly over the processors, resulting in very efficient use of a multi-core CPU.

Parallel programming in .NET 4.0

In the .NET 4.0 framework parallel is included in the form of Task Parallel Library (TPL) and Parallel LINQ (PLINQ). These functions are actually built on top of the existing thread pool in previous versions of the .NET framework. Parallel is pretty easy to implement, but also very easy to misuse or overuse. Caution is required!

Overview of parallelism in .NET (MSDN)

The following posts will give an introduction to parallel programming in C# 4.0 and provide some guidelines and best practices.

Resources

Blog has moved! You should check this post out on kevinpelgrims.com

A while ago I created a script to manage services on a remote server (see Remote Service Manager). Included in that script was a way to display some information with the use of a switch (-help). A few days later I was wondering if there wasn’t a better way to include help in own PowerShell scripts. And of course there is! It’s even in the help files.

So, here’s what to do. First, check the information in PowerShell help by running following command:

Get-Help about_Comment_Based_Help

There we can see this help thing will be pretty straightforward to implement. Here’s what it says:

The syntax for comment-based Help is as follows:

    # .< help keyword>
    # <help content>

-or -

    <#
        .< help keyword>
        < help content>
    #>

So, this means we just have to make a comment block, with some specific keywords. Cool. So, what are the right keywords?  They’re also in the help. Here’s a small list of the most important stuff:

  • .SYNOPSIS
  • .DESCRIPTION
  • .PARAMETER <Parameter-Name>
  • .EXAMPLE
  • .NOTES
  • .LINK

For more details and a complete list of keywords, I suggest you look at the help in PowerShell. Here is a little example of how we’re going to put this to work:

<#

.SYNOPSIS
This is a simple Powershell script to explain how to create help

.DESCRIPTION
The script itself will only print 'Hello World'. But that's cool. It's main objective is to show off the cool help thingy anyway.

.EXAMPLE
./HelloWorld.ps1

.NOTES
Put some notes here.

.LINK
https://kevinpelgrims.wordpress.com

#>

Write-Host ‘Hello World!’

There, that’s all there is to it. I wish I looked at that before I made the RSM script 🙂 It adds some kind of professionalism to a script, don’t you think? And also, it’s intuitive for users to use the Get-Help command. Everyone is happy! Below is a screenshot of our own help.

Blog is moving! You should check this post out on kevinpelgrims.com

This is the last part (of four) in a series of articles on the new features in PowerShell 2.0. Last time we discussed modules, now it’s time for remoting!

Remoting

One of the coolest new features is remoting. It is kind of like running remote desktop in command line. Altough it’s an important piece of PowerShell 2.0, there’s not a lot to explain about this. It’s all pretty easy to use.

What’s fun is that we have the option of executing one command on different remote computers at the same time. This will save system administrators a lot of time. To demonstrate this consider following command:

Invoke-Command -ComputerName Server1 -scriptblock {Get-Service}

This gets all services from Server1. To run this on multiple servers we just adjust the command:

Invoke-Command -ComputerName Server1, Server2, Server3 -scriptblock {Get-Service}

Now we get all services from Server1, Server2 and Server3 in a really easy way.

Another way to use remoting is by connecting to a remote session with Enter-PSSession. You type commands in your local console, but everything is executed on the remote machine. Until you leave the remote session, by using Exit-PSSession.

PS D:\ProjectsPS> Enter-PSSession -ComputerName Server1

PS Server1> Get-Process powershell

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
547       8    95660       8852   199     6,84   5136 powershell

PS Server1> Exit-PSSession
PS D:\ProjectsPS>

Of course, there are a lot of other commands available, so for the last time I will tell you to use the PowerShell 2.0 help: Get-Help about_PSSessions. Much can be learned from the official documentation (yes, it’s really good!).

And another good resource is of course Technet, where all the available cmdlets are explained in a more readable manner (see resources).

So that’s all for today folks! I hope you learned some things that will be useful in future projects.

Recources

A list of resources on the discussed topics: