El TecnoBaúl de Kiquenet

Kiquenet boring stories

Posts Tagged ‘windowsservices’

Create Windows Service With TopShelf

Posted by kiquenet en 29 julio 2014

Topshelf is an open-source hosting framework for building Windows Services using .NET. With Topshelf you can create in a few lines of code your own windows service. It’s a kind of internal DSL for building windows services.

First download Topshelf from GitHub, I used version 2.2 (direct link).

  1. Create a console application named ‘SampleWindowsService‘ inside Visual Studio
    – Be sure to change the target framework to ‘.NET Framework 4
  2. Reference the binaries TopShelf.dll and log4net.dll (included in Topshelf).
  3. Create a simple service called ‘SampleService’ that simply write every 5 seconds to the log. Note that we create explicit a Start and Stop method which is conceptually the minimum that a windows service need.

    C#

    public class SampleService

    {

    private Timer _timer = null;

    readonly ILog _log = LogManager.GetLogger(

    typeof(SampleService));

    public SampleService()

    {

    double interval = 5000;

    _timer = new Timer(interval);

    _timer.Elapsed += new ElapsedEventHandler(OnTick);

    }

    protected virtual void OnTick(object sender, ElapsedEventArgs e)

    {

    _log.Debug("Tick:" + DateTime.Now.ToLongTimeString());

    }

    public void Start()

    {

    _log.Info("SampleService is Started");

    _timer.AutoReset = true;

    _timer.Enabled = true;

    _timer.Start();

    }

    public void Stop()

    {

    _log.Info("SampleService is Stopped");

    _timer.AutoReset = false;

    _timer.Enabled = false;

    }

    }

  4. In the main method of our console application we will use Topshelf to host ourSampleService.
    We we are telling Topshelf how to start and stop the service, what the service name is, etc.
    Note that we need to configure log4net for Topshelf and our service!

    C#

    static void Main(string[] args)

    {

    XmlConfigurator.ConfigureAndWatch(new FileInfo(".\\log4net.config"));

    var host = HostFactory.New(x =>

    {

    x.EnableDashboard();

    x.Service(s =>

    {

    s.SetServiceName("SampleService");

    s.ConstructUsing(name => new SampleService());

    s.WhenStarted(tc =>

    {

    XmlConfigurator.ConfigureAndWatch(

    new FileInfo(".\\log4net.config"));

    tc.Start();

    });

    s.WhenStopped(tc => tc.Stop());

    });

    x.RunAsLocalSystem();

    x.SetDescription("SampleService Description");

    x.SetDisplayName("SampleService");

    x.SetServiceName("SampleService");

    });

    host.Run();

    }

  5. The only thing we have to do now is to configure log4net. Create a file called ‘log4net.config‘ with the following configuration.

    XHTML

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

    This configuration enables to output to the console and through a UDP network protocol so that we can easily monitor the log statements when installed as a windows service. I used Log2Console (Codeplex) to monitor my log statements through UDP.
    – Make sure the output directory of log4net.config is set to ‘Copy always’
    – Note that there is an issue with log4net related to IPv6 and Windows Vista/7. You can fix it by adding the following ’127.0.0.1 log4view-local’ to your hosts file which can be found in folder C:\Windows\System32\drivers\etc\hosts.

When you fit F5 you will see that Topshelf outputs some log statements and you will see that the log statements of our SampleService is included and everything is working properly.

In order to install SampleService as a Windows Service you simply need to do the following through the command prompt.

Be sure to launch the command prompt as an administrator!

SampleWindowsService.exe install

After that when the windows service has been installed successfully we can start the service through services.msc or simply by typing

SampleWindowsService.exe start

Now we can open Log2Console to monitor our log files that is send through the UDP appender.


To uninstall the service we simply write

1

SampleWindowsService.exe uninstall

The sources can be found here (BitBucket)

References:
http://www.christophdebaene.com/blog/2011/03/16/create-a-net-windows-service-in-5-steps-with-topshelf/

Anuncios

Posted in .NET, Componentes | Etiquetado: , | Leave a Comment »

Using PowerShell to Manage Network Interfaces and Windows Services

Posted by kiquenet en 28 julio 2014

PowerShell is a new scripting language that allows you to interact with applications, services and objects as objects. It is a .NET application which shells commands out on your behalf. This is very powerful, because it allows you to leverage the strengths of an object oriented model within your scripting tasks with a very terse, yet simple scripting language. Because it is written in .NET, you can access .NET types, objects and WMI objects from a command prompt.

My current workstation runs Windows Server 2008 Standard Edition with Hyper-V. I use the host/parent partition as my office, and have a number of child partitions that are integrated into a Windows Server 2008 Domain. Needless to say, this configuration gives me everything I need to develop, test and integrate multiple Server OS’, platforms and technologies, and is my environment of choice for developing production code. It still amazes me how far we’ve come in such a short period of time. Not too long ago, I remember setting up similar lab environments at home running Windows NT 4 and Windows Server 2000 on dedicated physical machines.

Anyway, I have to say that I am absolutely delighted with my environment, but it took me some time and effort to learn how to tune Server 2008, and this is all well documented in previous posts. One of the the things that I do to keep performance high is that I only have the 3 services required for Hyper-V running when I need them. In other words, if I am only working with email and writing documents or design drawings, I don’t need to have the Hyper-V services running because they are resource intensive. In addition, I only want my loopback adapter (that provides me with a virtual LAN for all of the child partitions on my domain to communicate) enabled when I need it to be. One reason for this, is that if I leave my loopback on and reboot, boot times can take up to 10 minutes because the loopback is configured to use my domain controller as the primary DNS server, which is a VM. Because the DNS Server only runs when my Domain Controller VM  is up and running, the VM will only come up when I start it. As a result, Windows tries and tries to reach the DNS server for the Loopback adapter until it finally gives up (If anyone knows how to change this timeout, please shoot me a note or post a comment).

So, I only want Hyper-V services running when I need to work in my development environment, and I don’t want my loopback enabled unless it needs to be. For a while, I was managing this as follows…

First, I set the following services to "Manual", so that they do not start automatically:

  • vmms: Hyper-V Virtual Machine Management
  • vhdsvc: Hyper-V Image Management Service
  • nvspwmi: Hyper-V Networking Management Service

The service names are a bit obscure, but the "friendly" names are pretty self explanatory. When I need to start my development environment, I would go into Server Manager, and start each service one by one.

Next, I would enable my loopback adapter so that my child partitions can communicate with each other.

All together, this resulted in a number of clicks, which was somewhat mundane to do every time. Worse, once I enabled the loopback, I often would forget to disable it before shutting down (remember, servers running Hyper-V do not support hibernation). For a while, I thought about writing myself a sticky note and posting it to my forehead so that I would not forget to disable the loopback, and finally, I decided to create an easy button for starting and stopping my development environment.

This is where Powershell comes in.

Using PowerShell to Query and Manage Network Adapters

The first thing I did was figure out how to talk to my network adapters so that I could enable and disable my loopback as needed. It turns out that Microsoft provides a WMI object called Win32_NetworkAdapter. The object exposes a bunch of properties for working with an instance of a Win32_NetworkAdapter:

image

In addition, there are 4 public methods that are exposed, and well documented as shown below:

image

To enumerate all network adapters on my host/parent partition, I issued the following command:

   1: Get-wmiobject win32_NetworkAdapter | format-table 

PowerShell lists each adapter and certain properties in a tabular format because I added a pipe and format-table parameter:

image

To identify the instance that corresponds to my loopback, I simply need to find the "Internal VLAN" instance above, which has a DeviceID of 17:

image

Next, I want to retrieve an instance of the adapter with a DeviceId of 17, so I issue the following statement:

   1: Get-WmiObject win32_networkadapter | where {$_.DeviceId -eq 17}

The where keyword uses a bracketed expression to evaluate the condition. The "$" is a temporary variable, which is similar to the "this" keyword in C#, which provides context for the current instance. The "-eq" operator is the equality operator in PowerShell. So, we are querying all adapters for the adapter with a DeviceID equal to 17. The above command returns the following:

image

Notice that each property is an actual documented property of the WIN32_NetworkAdapter object. If we have access to properties, it would be helpful to determine if the adapter is enabled or disabled. To do this, I assign the adapter to a variable called $adapter as shown below, and then I get the value of the Availability property:

image

The value of the Availability property is 3. Referring to the WIN32_NetworkAdapter documentation, I can see that a status of 3 indicates that adapter is on, and running on full power.

image

Are you getting the hang of it yet? Hopefully, the interaction with PowerShell should feel object-oriented because it is! We are getting a reference to the WMI shell of the adapter and then using it’s get accessors to get the value of the public properties. So, if we can get a reference to the adapter, get properties, we should be able to call methods on it, right?

To disable the adapter, I simply call the Disable() method on my $adapter variable:

image

Now, to confirm that the adapter is disabled, you can look at Network Connections and you will see that the Status is in fact Disabled. To do this programmatically via PowerShell, you can use the ConfigManagerErrorCode property which is also documented. Get a new instance of the adapter, and call the ConfigManagerErrorCode property on it as shown below:

image

A return code of 22 can be matched to the table in the MSDN documentation:

image

Now, enable the adapter by calling the Enable() method:

image

A return code of 0 indicates that the adapter is enabled, and working properly:

image

As you can see, PowerShell is a very easy to use, yet powerful tool for managing system objects in an object-oriented manner. You don’t need to worry about writing VBScript or C# to accomplish simple administrative tasks such as enabling and disabling a network adapter. As you might imagine, the real power comes in being able to run a series of PowerShell commands in a batch, perhaps at the click of the button. This is exactly what I’ll cover next.

Using PowerShell to Query and Manage Windows Services

You’ll recall that I only want the 3 Hyper-V services to run when I need them, so what I want to do is create an "easy button" to toeggle my development environment on and off.

The "On" should:

  • Enable my Internal VLAN Adapter
  • Start the Hyper-V Virtual Machine Management
  • Start the Hyper-V Image Management Service
  • Start the Hyper-V Networking Management Service
  • Get me a cup of Starbucks coffee

The "Off" Button should:

  • Disable my Internal VLAN Adapter
  • Disable the Hyper-V Virtual Machine Management
  • Disable the Hyper-V Image Management Service
  • Disable the Hyper-V Networking Management Service


    I’ve already covered how to manage network adapters using PowerShell as a primer, so I’ll jump right into working with Windows Services. As with any program, sometimes it is helpful to group commands into a subroutine. In PowerShell, these functions are referred to as cmdlets (prounounced "commandlets"). You may not realize this, but you’ve already been working with cmdlets if you’ve tried the commands I covered above on your own machine. The get-wmiobject command is actually a cmdlet that provides a reference to the WMI object specified as the parameter. You could accomplish this without the cmdlet, but why would you want to?

  • Fortunately, a cmdlet is also available for working with Windows Services: get-service.

    To get information about a particular service, simply call get-service with the service name. The actual service name of the Hyper-V Virtual Machine Management service is "vmms", so issuing the get-service vmms command returns a few properties including the Name, DisplayName and Status of the service.

    image

    Starting and stopping the Hyper-V Virtual Machine Management service is as simple as calling the appropriate method: Stop() to stop the service and Start() to start it. While you could use a variable called $service to store the reference to the service object, an abbreviated way to accomplish this is shown below:

       1: (get-service vmms).Stop()

    Now, when you issue the get-service vmms command, you can see that the Status property is "Stopped":

    image

    Starting the service back up is as simple as calling Start() on the cmdlet expression:

    image

    Building the "Easy Buttons"

    There may very well be a more sophisticated way to do this, but I created two batch files, one called "Start.bat" and the other called "Stop.bat" and placed them in my documents folder. Each file contains the appropriate PowerShell syntax as shown below:

    image

    Note, to re-use variables across PowerShell sessions, you must first configure a PowerShell profile: http://msdn.microsoft.com/en-us/library/bb613488(VS.85).aspx

    Next I created two desktop shortcuts, appropriately named "Start" and "Stop" and set the target to each corresponding file.

    Now, I have two "Easy Buttons" for toggling my development environment on and off. While I can’t guarantee that I won’t forget to press the "off  button" before shutting down, it is a heck of a lot easier than going through the contortions manually.


  • References:

    http://rickgaribay.net/archive/2008/09/26/using-powershell-to-manage-network-interfaces-and-windows-services.aspx

    Posted in PowerShell, Scripts, Soporte | Etiquetado: , , | Leave a Comment »