Getting the Current Method Name

26. August 2010 17:25

I am trying my best to avoid using "magic strings" as much as possible in my current project. Previously I have not been able to get rid of magic strings in one particular circumstance - when needing to use the current method name, whether it be for logging or some other use. In my case this was for a key to use with a cache wrapper. I came across the following which works for me:


[MethodImpl(MethodImplOptions.NoInlining)]
public static string CurrentMethod()
{
	StackTrace st = new StackTrace();
	StackFrame sf = st.GetFrame(1);

	return sf.GetMethod().Name;
}

This means that instead of having to enter the current method as a magic string:


var cacheKey = string.Format("HasPrivilege.{0}",@params.Username);

all I do now is include a call to CurrentMethod:


var cacheKey = string.Format("{0}.{1}", CurrentMethod(), @params.Username);

Don't forget the favico file

3. June 2010 16:11

On our latest ASP.NET MVC 2 project, I was constantly getting a NullReferenceException upon first loading up the application on my development machine. We've overridden the MVC controller factory, and it was in the GetControllerInstance override that this exception was occurring. Today I finally found the cause and the subsequent solution:

 

  1. Add a favico.ico image file to the root of the MVC web project.
  2. Add the following to RegisterRoutes in the global.asax.cs:

    routes.IgnoreRoute("favicon.ico");

 

It turns out that either my IE or an add-in that I have installed is attempting to download the favico.ico image file. As per the default routing, MVC is unable to locate the static file, and therefore attempts to find the 'favico.ico' controller, which obviously doesn't exist - resulting in the NullReferenceException.

Using Powershell Remote Sessions

3. March 2010 20:53

Yesterday I showed the simple steps I used to setup Powershell Remoting between two workgroup based machines. Today I'll show how to create a remoting session and connect to it.

Firstly lets have a look at what cmdlets are available for using PSSession:

Get-Command -noun *pssession*

There are a few cmdlets returned, but initially it looks like the one we might need to use is Enter-PSSession. This can be used either by supplying it with a PSSession object, or by specifying the details of the machine that I want to connect to. I'm going to use the former and pass it a PSSession object. For that I'm going to use the New-PSSession cmdlet:

New-PSSession -ComputerName EeePC -Credential EeePC\Mike -Name Eee

Notice that I've given the session a name of 'Eee'. This just makes it easier for me to find and reference the session once it's been created, as by default a new session will be given a name of Session<x>, where <x> is a sequential number.

When you execute the above cmdlet, you'll get a credential request dialog box popup which is where you supply the password for the user you want to connect as. Once Powershell has created the session you'll see the results of the session creation. Hopefully the State of the session will be Opened.

Now to use that session, or any other session that you've created, you need to use the Enter-PSSession cmdlet. There are three typical ways of using this cmdlet - either by passing the Id of a session, by passing in the name of a session, or by passing in a session object. Here are examples of all three:

Enter-PSSession -Id 4
Enter-PSSession -Name Eee
Get-PSSession -Name Eee | Enter-PSSession

If you are in a remote session, then the name of the remote machine will show in front of your Powershell prompt. Now you can execute any Powershell cmdlets as if you were actually on the remote machine itself. To exit the session you just need to use the Exit-PSSession cmdlet.

Powershell 2.0 Remoting on Workgroup Machines

3. March 2010 00:40

I'm exploring the new features in the Powershell 2.0 release and found that it's a little more contrived to get Powershell remoting working outside of a domain. Here I'll show the steps I took to get remoting working across two workgroup-based Windows 7 machines.


Firstly on both client and server machines you need to run the WinRM quick configuration cmdlet:


Set-WSManQuickConfig

This performs a few steps. It'll start the WinRM service and set it's start mode to automatic. Then it creates a HTTP listener on port 5985 for all IP addresses on the machine, and opens the port in the Windows Firewall to allow remoting requests through.


Next on the server machine that you want to connect to, you need to enable remoting to accept incoming commands:


Enable-PSRemoting -force

And last of all on the client machine the name of the server needs to be added the TrustedHosts setting in the WinRM configuration. This allows your client machine to connect to the server by sending it's credential information without verifying its identity:


Set-Item WSMan:\localhost\Client\TrustedHosts -Value <ServerMachineName> -Force

This will overwrite any value that was previously in TrustedHosts, so if you want to add to the list of TrustedHosts then add the -Concatenate parameter to the above.


In a later post I'll show how to create and use a Powershell remote session.

Host Migration and BlogEngine.NET Upgrade.

1. March 2010 15:33

In an attempt to keep up to date I've changed my hosting provider at the same time as upgrading this blog to v1.6 of BlogEngine.NET. Hopefully you shouldn't notice any problems after what was a very seamless transition.

 

After a couple of years with DotNetPark, I found a great hosting package with tsohost. The Pro package that they offer is absolutely outstanding for the low price of just £5 a month - 10Gb storage, 150Gb bandwidth, plus all the usual suspects. But the clincher for me was the included 100 subdomains (this blog is now on a subdomain), 6 domains, a single MSSQL 2005 database and 100 MySQL databases. This alone sold it to me, but then I read in their customer forums that they do expect to include .NET4 when it is available. This forward thinking was sadly missing at DotNetPark, so it's nice to have a change. Surprisingly I was able to migrate this blog without needed any assistance from tsohost, as small things like changing folder permissions is fully supported from supplied control panel.

 

Next step is to try and migrate the data storage for this blog from the default XML to MySQL.

 

UPDATE 22:35 - I've now migrated to MySQL storage for the blog, using a nice and simple Database Migration Tool from Al Nyveldt. Hopefully this will mean that as this blog expands (yes - I am hoping to write more!) then it shouldn't have the slow-down associated with XML storage.

Simple example of using the SpecFlow BDD Library

1. February 2010 18:16

Ryan Lanciaux has posted a good introduction to the use of SpecFlow .NET library to assist in Behaviour Driven Development. Ryan's example is really easy to follow, and shows you that can even use SpecFlow for small apps.

Determining the DNS servers for the active Windows Mobile connection

26. January 2010 10:42

Here is a nice simple way of determining the DNS servers that are currently being used for the active connection in a Compact Framework application. This requires the OpenNETCF Smart Device Framework.

public static IPAddressCollection DiscoverDnsServerAddresses()
{
    INetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
    foreach (NetworkInterface nic in nics)
    {
        if ((nic.OperationalStatus == OperationalStatus.Up) &&
            (nic.CurrentIpAddress.ToString() != "0.0.0.0") &&
            (nic.Speed > 0) &&
            (nic.NetworkInterfaceType != NetworkInterfaceType.Loopback) &&
            (nic.NetworkInterfaceType != NetworkInterfaceType.Tunnel)
            )
        {
            return nic.GetIPProperties().DnsAddresses;
        }
    }
    return null;
}

Automatically starting Windows Mobile apps on boot

1. October 2009 07:21

I've recently had need to ensure that a CF app of mine is automatically launched on rebooting a Windows Mobile device. Googling for help on this didn't give me quite enough help, so I'm making sure I get this written down for future reference. Chris Tacke touched on the subject, and MSDN had a little information.

When the PocketPC / Windows Mobile OS starts, it looks in the HKEY_LOCAL_MACHINE\init registry key for a list of processes which it should start. The entries in this key are arranged like this:

Entry Value Type
Launchnn <path to process exe> REG_SZ
Dependnn hex:xx,yy[,xx,yy] REG_BINARY (yy is most signficant)


in this table nn is a value which determines the order in which processes are started. The Dependnn entry is optional, and is used to specify any processes upon which the entry has dependencies. For example:

[HKEY_LOCAL_MACHINE\Init]
    "Launch10"="shell.exe"
    "Launch20"="device.dll"
    "Launch30"="gwes.dll"
    "Depend30"=hex:14,00
    "Launch50"="taskman.exe"
    "Depend50"=hex:14,00, 1e,00


Here the first entry (shell.exe) does not have any dependencies, whereas gwes.dll has a dependency on device.dll (0x14 = 20) and taskman.exe has a dependency on both device.dll and gwes.dll (0x1e = 30).

A typical CF app should ideally have dependencies on both shell32.exe (Launch50 / 0x32) and services.exe (Launch60 / 0x3C). Therefore to ensure that your app launches only after these two processes have started, you would add a Launchnn and Dependnn entry with a nn value higher than both of these processes.

Note: there is a restriction on the number of Launchnn / Dependnn entries in the registry. No more than 32 applications can be specified.

As an example, here are the registry entries I have added as part of my CAB installer package:

[HKEY_LOCAL_MACHINE\Init]
    "Launch95"="%InstallDir%\MgdSvcsLauncher.exe"
    "Depend95"=hex:32,00, 3C,00

Note that I've included the %InstallDir% macro as part of the path. This ensures that the correct path is inserted into the registry regardless of which folder the app is installed to.

Dependency Notification

If we have a process listed in the above registry key with dependencies, how do we know when those dependencies have started? This is straightforward, the OS won't launch our process until all our dependencies have notified the OS that they have started.

But how can we notify the OS that our application has started, so that any processes dependant on our application may start? Here we have to use a native API call.

When launched our process will receive an argument value corresponding to the nn value defined in our registry entry (Launchnn). Next we need to import the native API we use to notify the OS:

[DllImport("coredll")]
public static extern void SignalStarted(uint dword);

And lastly we just need to call SIgnalStarted with the nn value passed to us as an argument when we are sure that any dependant processes can use our application if required. This isn't always appropriate to our code, and won't affect anything if it's not called, however any dependant processes will not be automatically launched until SignalStarted is called.

Multi-instance Windows Services with TopShelf

25. September 2009 16:31

Today I was having a look through the TopShelf code to try and determine how the multi-instancing features work (or don't work as I was originally led to believe). I had an issue yesterday with a TopShelf based service which had been installed manually from the command line using SC.exe. The problem was that the service had been named "MobileQueueProcessor_UAT", which caused TopShelf to throw an exception when attempting to start the service.

Background

In the TopShelf configuration you set the name that the service will be installed to, as well as the display name:

var cfg = RunnerConfigurator.New(x => 
{ 
   x.SetServiceName("MobileQueueProcessor"); 
   x.SetDisplayName("Mobile Queue Processor Service"); 
   x.SetDescription("Mobile Queue Processor Service"); 

   x.ConfigureService("", c => 
   { 
      c.WhenStarted(s => s.Start()); 
      c.WhenStopped(s => s.Stop()); 
   }); 
});

If you install this service from the command prompt using the TopShelf built-in installer, then the service will have the name specified in the call to SetServiceName as above ("MobileQueueProcessor").

And herein lies the problem I encountered. If started from the service control applet, the TopShelf library checks to see that the service name defined in code correlates to an installed service. In my case the service had a name of MobileQueueProcessor_UAT, yet the name defined in code did not have the _UAT suffix.

Resolution

TopShelf handles this situation with ease. There is an additional parameter that can be set on the command line that allows you to define an instance:

/instance:<instance_name>

where <instance_name> will be a suffix appended to the servicename. For example:

MobileQueueProcessor.exe /install /instance:UAT

will result in a service name of MobileQueueProcessor$UAT. Note the dollar sign between the name specified in the TopShelf configuration and the instance name (suffix) specified in the command line arguments. The executable path in the installed service configuration will be automatically set to:

<path to exe>\MobileQueueProcessor.exe -service -instance:UAT

Specifying the instance on the command line when running the service ensures that TopShelf will look for an installed service which corresponds to <service_name>$<instance_name>, whereas if no instance name is specified as an argument, then it just looks for an installed name with no suffixes.

Best on-line backup?

10. September 2009 07:58

I thought I'd share my experience with looking for decent on-line backup. After reading the Sept issue of Computer Shopper just over a month ago, I finally succumbed to the desire to have an on-line backup facility as I've just been using local NAS and USB drives for backup. But there always that little voice in my head that says what if we got burgled, or the drives went kerput? I would hate to lose precious memories such as digital photos.

The magazine recommended Humyo and MozyHome. I looked at MozyHome and discounted it immediately on the fact that you need to buy a seperate license for each computer - not ideal in my case where I'd ideally like to have backup from a number of machines. So I thought I'd try Humyo.

Unfortunately you need to purchase the premium package before you can use the client software, so I went ahead and bought the package for £46 a year for 100Gb. But within just a few days of using it, and having the client crashing constantly or not uploading anything, I had to call it quits and get my money back. I would *not* recommend Humyo to anyone due to the rubbish client.

I also tried DropBox, giving the free version (up to 5Gb) a go. The main problem I had with their solution is that you have to keep a copy of all your files on your machine. So if you have several machines which have files you want to backup, then they all have to have a copy of all files. There is a facility to prevent this, but it's not intuitive enough to allow you to backup and forget. So DropBox was out of the equation.

Eventually one of my colleagues mentioned JungleDisk. I'd heard of them before, but dismissed them because I thought they use Amazon S3 storage, which requires you to pay not only for the amount of data stored, but also bandwidth costs. Again not really ideal - if I'm overwritting my backup files, then I'm incurring costs. But on looking closer I saw that they now offer Rackspace storage, which is similar storage costs per Gb as S3, but with NO bandwidth costs. The client is a joy to use, and allows you to setup as many online disks as you want. So I have one for photos, one for my development machine (SVN repository backups etc), and one for all personal files and backups (emails, favourites, etc). The client has rather simplistic built in backup facilties, but still very usable for most. Each online disk is mapped to a network disk in Windows, so you can use your own backup solution if you so choose (I use GoodSync myself).

Today I received my first months invoice. I have three online disks - all Rackspace, and across them I have only backed up 5Gb although I have plans to start backing up a lot more data over the next few months. And the cost for the last month - $2.70 (about £1.60)... And $2 of that is a fixed subscription charge for JungleDisk. Needless to say that I am very pleased with JungleDisk, and would heartily recommend it to anyone.