Archive for November 2012

C# – Creating a Service to Monitor a Directory

Let’s say you wanted to watch a directory and perform an action each time a file is added, deleted, changed, or renamed.

  • Microsoft has a Visual C# Windows Service project template in Visual Studio.
  • Microsoft also has a nice class already created to help with this: FileSystemWatcher

Example Project

Here is an example project you can download: DirectoryMonitoring.zip

Step 1 – Create a Visual C# Windows Service project in Visual Studio

  1. Select File | New Project.
  2. Select Templates | VIsual C# | Windows | Windows Service.
  3. Provide a name: DirectoryMonitoring
  4. Click OK.

Step 2 – Create an object that inherits from FileSystemWatcher

  1. Right-click on Project and choose Add | Class.
  2. Name it MyFileSystemWatcher.cs.
using System;
using System.IO;

namespace DirectoryMonitoring
{
    public class MyFileSystemWatcher : FileSystemWatcher
    {
        public MyFileSystemWatcher()
        {
            Init();
        }

        public MyFileSystemWatcher(String inDirectoryPath)
            : base(inDirectoryPath)
        {
            Init();
        }

        public MyFileSystemWatcher(String inDirectoryPath, string inFilter)
            : base(inDirectoryPath, inFilter)
        {
            Init();
        }

        private void Init()
        {
            IncludeSubdirectories = true;
            // Eliminate duplicates when timestamp doesn't change
            NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size; // The default also has NotifyFilters.LastWrite
            EnableRaisingEvents = true;
            Created += Watcher_Created;
            Changed += Watcher_Changed;
            Deleted += Watcher_Deleted;
            Renamed += Watcher_Renamed;
        }

        public void Watcher_Created(object source, FileSystemEventArgs inArgs)
        {
            Log.WriteLine("File created or added: " + inArgs.FullPath);
        }

        public void Watcher_Changed(object sender, FileSystemEventArgs inArgs)
        {
            Log.WriteLine("File changed: " + inArgs.FullPath);
        }

        public void Watcher_Deleted(object sender, FileSystemEventArgs inArgs)
        {
            Log.WriteLine("File deleted: " + inArgs.FullPath);
        }

        public void Watcher_Renamed(object sender, RenamedEventArgs inArgs)
        {
            Log.WriteLine("File renamed: " + inArgs.OldFullPath + ", New name: " + inArgs.FullPath);
        }
    }
}

Notice that each method is logging. We will implement this log next.

Step 3 – Add logging

  1. Add the class from a previous post: A simple Log singleton in C#
  2. Make sure to change the namespace to match.

Step 4 – Implement the Service

  1. Right-click on the Service1.cs file and choose View Code.
  2. Change both the Name and the ServiceName to DirectoryMonitoringService. You can right-click on the file to rename. If that doesn’t rename the class, you can open the file, right-click on the class name and choose Refactor | Rename.
  3. Go to the code of the DirectoryMonitoringService.cs file (which was Service1.cs just a couple steps ago) in Visual Studio.
  4. Implement the constructor as follows:
using System.IO;
using System.ServiceProcess;

namespace DirectoryMonitoring
{
    public partial class DirectoryMonitoringService: ServiceBase
    {
        protected FileSystemWatcher Watcher;

        // Directory must already exist unless you want to add your own code to create it.
        string PathToFolder = @"C:\Directoy\To\Monitor";

        public DirectoryMonitoringService()
        {
            Log.Instance.LogPath = @"C:\ProgramData\DirectoryMonitoring";
            Log.Instance.LogFileName = "DirectoryMonitoring";
            Watcher = new MyFileSystemWatcher(PathToFolder);
        }

        protected override void OnStart(string[] args)
        {
        }

        protected override void OnStop()
        {
        }
    }
}

Step 5 – Create a Service Installer

  1. Right-click on DirectoryMonitoringService.cs and choose View Designer.
  2. Right-click anywhere in the designer window and choose Add Installer. This adds a ProjectInstaller.cs file.
  3. Right-click on ProjectInstaller.cs and choose View Designer.
  4. In the designer, right-click on serviceProcessInstaller1 and choose Properties.
  5. In the properties, set Account to LocalSystem.
  6. Back in the designer, right-click on serviceInstaller1 and choose Properties.
  7. Set StartType to Automatic.
  8. Add a descriptions if you want.

Step 6 – Install the Service

  1. Open the Developer Command Prompt by right-clicking and choosing Run as Administrator.
    Note: If you don’t have the Developer Command Prompt, you can open a normal command prompt as administration and get installUtil.exe from this path:

    c:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe
  2. In the command prompt, change to the bin\debug folder in your project directory.
  3. Run this command to install the service:

    installutil.exe DirectoryMonitoring.exe

  4. Start the service with this command.

    net start DirectoryMonitoringService

Step 7 – Debug the Service

  1. Make sure the service is started and running.
  2. In Visual Studio with the DirectoryMonitoring project open, click Debug | Attach to Process.
  3. Select the DirectoryMonitoring.exe file.
  4. Put a break point at each event in the MyFileSystemWatcher object.
  5. Test all four events:
    1. Add a file.
    2. Rename a file.
    3. Open and save a file.
    4. Delete a file.

You have now created a service to monitor a directory and you have seen how to debug it.

Is Windows 8 Pro Hyper-V the end of VMWare Workstation?

So I have had a license for VMWare Workstation through work since 2004. I have been a loyal user for eight years. However, my current job is not going to provide any further VMWare Workstation licenses.

Price of VMware Workstation vs Hyper-V

Because Hyper-V is included in Windows 8 Pro and the Microsoft Windows 8 Pro Upgrade is under $70 for a full version (not upgrade) of Windows 8 Professional System Builder DVD 64-Bit you are only looking at over $125.00 on sale (normally $199). VMWare Workstation alone is $249. VMWare Workstation is $50 more expensive than paying full retail price for the full version of Windows 8. If you are planning to buy Windows 8 Pro anyway, then technically, VMWare Workstation $249 too much.

Hyper-V vs VMWare Workstation

Having used both, I am going to mention some differentiating features.

  • Hyper-V virtual machines seem to snapshot and revert must faster than VMWare Workstation.
  • VMWare auto sizes the screen does, Hyper-V doesn’t.
  • VMWare workstation has a cool mode where you can run apps from the virtual machine as if they were regular desktop apps.
  • VMWare workstation works better with alternate operating systems.

There are advanced features that I haven’t tested. For example, when I worked at LANDesk we need to test PXE Booting so the ability for the virtual machine to PXE Boox was extremely important, and VMWare worked really well with PXE Booting. I haven’t tested Hyper-V with PXE Booting, so if you have please post and let me know if how it works.

Of course, don’t forget about Virtual Box. The open source edition, Virtual Box OSE, is free no matter what operating system is the host, whether it is Windows 8 or FreeBSD or Linux. It has been free for a while and yet VMWare Workstation is still popular so maybe it will remain popular despite Windows 8 Pro?

How to open a command prompt on a remote computer

There are three tools that can do this:

  • PSExec – Not redistributable but free for download. No source code.
  • RemCom – BSD Licensed but not really maintained and I haven’t been able to get it to work in Windows 7. Source code available. Uses its own command line.
  • PAExec – Free to distribute but no source code. Uses same command line as PSExec.

So they all use the same command line to connect to a remote computer. I think I am going to go with PAExec because it is newer, maintained, distributable, and works in Windows 7.

PAExec \\RemotePC cmd.exe

However, with that command line, it can be confusing to have a command prompt open on your machine without a way to know it is actually a command prompt for a remote computer so it is a good idea to add a prompt.

PAExec \\RemotePC cmd.exe /k prompt $C%computername%$F$S$p$G

I hope this helps.

I just broke 1000 points on StackOverflow

Ok, this may be a total geek thing to celebrate, but I just broke over 1000 reputation points on Stack Overflow.
http://stackoverflow.com/users/375727/rhyous

I thought I would celebrate by sharing this geekiness of mine with everyone.