Tuesday, April 30, 2013

Creating a logging service using the Microsoft Enterprise Library Logging Application Block

As part of my recent foray into creating various Windows services, I've come across the need for logging (like all serious apps do) and decided to use the Microsoft Enterprise Library Logging Application Block. We used it at a previous company and it got very good reviews from the developers there who used it. Unfortunately, all of the tutorials out there are a bit useless when it comes to doing anything real with the Logging Application Block, like using custom configuration. Fortunately, it was easy enough to figure out how to get customized configuration of logging working just by looking in the assembly and writing some unit tests to experiment.

For my needs, I like to keep all of my configuration as compartmentalized as possible. To that end, I usually end up using .NET Configuration files on a per-assembly basis. Fortunately, this works very well with the Logging Application Block because you can configure logging with arbitrary Configuration files. To get custom logging working easily in Visual Studio, do the following:
  1. Open Visual Studio (I'm using 2010)
  2. Install NuGet from the Extension Manager, if you haven't already.
  3. Install EnterpriseLibrary.Config from the Extension Manager if you haven't already.
  4. Create your solution and project that requires logging.
  5. If your project (web or application) comes with a .config file already (i.e. Web.config or App.config respectively) you can use that, otherwise, you can create an app.config file for the assembly in which you're creating your logging service.
  6. Once you've figured out which app.config (or Web.config) file you're going to be using (i.e. the same assembly where you're placing your logging class, right click on the .config file. You should see an 'Edit configuration file' entry with an orange logo (provided by the add-in installed in Step 3 above).
  7. Follow any other tutorial out there on the internet for configuring the Logging Application Block. (repeating such information here would be redundant and pointless). There's one such article here.
  8. Now that you've got your configuration, create a class to be your logging service wrapper.
  9. Figure out where your application config file is going to end up after your application is built.
  10. In your logging service wrapper, create a Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, giving the configuration file path as the sole parameter to the constructor.
  11. Create a new Microsoft.Practices.EnterpriseLibrary.Logging.LogWriterFactory, providing the FileConfigurationSource you just created as the sole parameter. You'll probably want to store this as a static object, because we only need a single factory.
  12. For each instance of your logging service, use this static factory that you've created to create a LogWriter.
  13. Implement whatever methods you need to wrap the logging service.
  14. You're done.
Your code should now look something like the following :
    using System;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.IO;
    using System.Text;
    using Interfaces;
    using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
    using Microsoft.Practices.EnterpriseLibrary.Logging;
    using Support.Extensions;

    /// 
    /// A logging services that uses the Microsoft Enterprise Patterns and 
    /// Practices library to provide logging support.
    /// 
    public class MicrosoftPracticesLoggingService : ILoggingService
    {
        /// 
        /// The log writer factory
        /// 
        private static readonly LogWriterFactory LogWriterFactory;

        /// 
        /// Initializes the  class.
        /// 
        static MicrosoftPracticesLoggingService()
        {
            string configFilePath = typeof(MicrosoftPracticesLoggingService).Assembly.GetCodeBaseFile().FullName + ".config";

            if (File.Exists(configFilePath) == false)
            {
                throw new InvalidOperationException(String.Format("Configuration file could not be found at '{0}'", configFilePath));
            }

            FileConfigurationSource configSource = new FileConfigurationSource(configFilePath);

            LogWriterFactory = new LogWriterFactory(configSource);
        }

        /// 
        /// The log writer used by this service to write to logs.
        /// 
        private readonly LogWriter logWriter;

        /// 
        /// Initializes a new instance of the  class.
        /// 
        public MicrosoftPracticesLoggingService()
        {
            this.logWriter = LogWriterFactory.Create();
        }

        #region Implementation of ILoggingService

        /// 
        [SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1604:ElementDocumentationMustHaveSummary", Justification = "InheritDoc")]
        [SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1611:ElementParametersMustBeDocumented", Justification = "InheritDoc")]
        public void LogException(Exception ex, string messageFormat, params object[] parameters)
        {
            if (ex == null)
            {
                throw new ArgumentNullException("ex");
            }

            if (messageFormat == null)
            {
                throw new ArgumentNullException("messageFormat");
            }

            StringBuilder messageBuilder = new StringBuilder();

            messageBuilder.AppendFormat(messageFormat, parameters).AppendLine();
            messageBuilder.AppendLine(ex.StackTrace);

            if (ex.InnerException != null)
            {
                Exception root = ex;

                while (root.InnerException != null)
                {
                    root = root.InnerException;
                }

                messageBuilder.AppendLine("Caused by:");
                messageBuilder.AppendLine(root.StackTrace); 
            }

            LogEntry logEntry = new LogEntry
                {
                    Message = messageBuilder.ToString(),
                    Severity = TraceEventType.Error
                };

            this.logWriter.Write(logEntry);
        }

        #endregion
    }

Sunday, April 28, 2013

Journey to robust web services: debugging a net.tcp service

I'm creating a net.tcp-based WCF web service for use with my current project, and so far the learning curve hasn't been very shallow. I've just recently learned, thanks to this post on Stack Overflow, that the default ASP.NET application doesn't support the net.tcp protocol, so IIS must be used instead. With that in mind, I've decided to move on to just using the Web Service I'm creating through a Windows Service via a ServiceHost. However, I've now encountered some problems debugging the Windows Service startup. This page on MSDN contains links and instructions on how to debug the startup of a Windows Service. While attempting to install the Debugging tools, I encountered a failure trying to install them as part of the Windows 7 SDK. This page on Stack Overflow had a solution, but it wasn't quite complete. This page had the missing parts.

Saturday, April 27, 2013

Journey to robust web services: configuring your WCF web service

WCF comes with a bunch of handy configuration tools.  You can find an introduction to them on the WCF configuration tools page on MSDN. Once you've created your WCF service project in Visual Studio, you'll need to use these tools to configure the service beyond a simple and basic test environment (which uses a Basic HTTP binding by default).

The specific tool mentioned on this page that you'll want to use is the Service Configuration Editor (svcconfigeditor.exe). This tool is used to edit Web.config files for WCF services. It comes with a handy wizard for adding a new service. When using this wizard, I ran into an error message similar to the following when trying to select the assembly I built containing my service: "Could not load assembly. This assembly is built by a newer runtime than the currently loaded runtime and cannot be loaded.". To solve this, I had to go and change the application configuration file for the program ("svcconfigeditor.exe.config" in the same directory as the program). I added the following under the root 'configuration' element:


 <startup useLegacyV2RuntimeActivationPolicy="true">
  <supportedRuntime version="v2.0" />
  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
 </startup>

This will allow the program to run using your currently installed framework (mine happened to be 4.0).


Friday, April 12, 2013

Finally understand the purpose of event accessors in .NET

As most people who deal with .NET are aware, C# (and also VB.NET) have Properties and Events.  In the case of properties, there are property accessors (get and set) which you can leave to the compiler to define, or you can define your own custom accessors. Similarly, there are event accessors (e.g. add and remove) so that you can customize subscriptions to your event handlers. Until today, I never understood why, until I read the MSDN article on Advanced C#. The reason is explained near the end of the section called "Standard Event Pattern", and it's pretty simple and common sense: in classes where you have a significant number of events (e.g. WPF / Forms Controls) and only a few of them are likely to be subscribed to, you can achieve a smaller memory footprint by overriding the event accessors and placing the event subscribers in an internal IDictionary, rather than using compiler-generated event accessors. In the former case, you'll have to store only the subscribers + the dictionary, whereas in the latter case, you'll have to store the subscribers + n events, and the latter is likely to be far larger than the former.

Tuesday, March 05, 2013

Getting error message with XSD MSBuild task

Lately I've been getting the error message :

error MSB4018: Microsoft.Build.Shared.InternalErrorException: MSB0001: Internal MSBuild Error: xsd.exe unexpectedly not a rooted path

... while I've been building a project that uses that task in a pre-build step to generate code from XSDs. After googling around a little bit, I found the solution on this page. The gist of it was that xsd.exe wasn't in the PATH variable, and therefore Visual Studio couldn't find it. If anybody else has this problem, add this folder to your PATH:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools

... or your system's equivalent, wherever the XSD.exe tool is stored on your system.

Monday, February 11, 2013

Debugging multiple processes and following the children in Eclipse Juno

I guess Eclipse has made it much easier in recent versions of Eclipse and CDT to debug multiple processes and have the debugger follow children. It was actually easier than I had thought it would be to get this functionality in Eclipse Juno. To do so, follow these steps:

  1. Create your debug configuration, pointing to the project and program you require. 
  2. Ensure that you setup your LD_LIBRARY_PATH in your environment variables as necessary.
  3. (and here's the really important part) In the Debug Configuration, go to the 'Debugger' tab. You should see a groupbox called 'Debugger Options' containing (at least) two tabs: 'Main' and 'Shared Libraries'. On the 'Main' tab, ensure that you have 'Non-stop mode' and 'Automatically debug forked processes'. In order to get these abilities, you'll need to have both non-stop gdb and multi-process gdb
  4. As a side note, you may need to also have your debug configuration pointed to a custom gdbinit command file with the following line:
    • set follow-fork-mode child
This is admittedly a pretty high-level overview of how to get things going, but if I ever have any problems with this in the future, I'll post more details. Or if people ask me :P

Wednesday, February 06, 2013

Using key gestures with parameterized Commands in WPF is "broken"

Ok, it's not actually broken, it just doesn't work the way I wanted (or expected). Apparently, there's a very good article on why they don't work the way I expected. To be clear, the way I expected them to work was:

  1. Define the command as a static RoutedUICommand and set the keyboard / mouse gestures I wanted on the command's InputGestures collection.
  2. Use said command in MenuItems, Buttons etc.
  3. Automatically have keyboard / mouse bindings setup everywhere (including the nice shortcut text on menu items in context menus / menu bar menus)
Turns out, no, and it's by design of the WPF team. See the article above for the explanation. At least now I know there's a good reason why it's not working, and I have a starting point for getting the key / mouse gesture functionality that I want.

Thursday, January 24, 2013

"Network is unreachable" on an embedded box

We've been working extensively with embedded boxes lately trying to migrate our platform over. One of the programs we've been trying to migrate today was a simple announcer program that sends out a UDP broadcast. On our first go, the program wouldn't work, saying that the "Network is unreachable" when doing a 'perror' after the call to 'sendto'. After much experimentation with various network binding flags, etc, which took the whole day, I went into overtime trying to figure out the problem. Eventually, I got to the point where I inspected the routing tables of the embedded system and was shocked to find .... there was no routing table entry for the default gateway, i.e. 0.0.0.0 destination IP. I'm actually kind of ashamed of how long it took me to find this, but in my defense, I was dealing with a wild mixture of systems and had done a lot of network reconfiguration with the systems and some of the stuff was handled automatically for me by my Ubuntu box, which gave me some inconsistent results at times when experimenting.  For my own future reference, here's how I solved the problem:

  • Run 'route -n'
  • Ensure there's an entry that looks like the following :
    • Destination: 0.0.0.0 Gateway: [the desired gateway, e.g. 192.168.10.1] Genmask: 0.0.0.0 Flags: UG, Metric: 0, Ref: 0, Use: 0, Iface: eth0 (or eth2, or whatever you may have)
  • If the above entry doesn't exist, add it with the following command:
    • sudo route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.10.1 dev eth0
You should now have no problems with your UDP broadcasting. If you do, well, let me know how it goes, I'd love to hear your problem and your solution.

Friday, January 18, 2013

Synchronizing with a remote SVN repository

We recently had a double hard-drive failure on our RAID 5 on our main server at work, and we lost our stuff. Our primary backup method of that system had completely failed due to the incompetence of some of the staff in our parent company that was completely beyond our control. It's only by the grace of the fact that our IT guy had an extra weekly backup that we were able to recover as much as we were. That said, it brought to light the need to have our own extra backups of our source code because we can't rely on the people we're supposed to be able to rely on to do the backups for us. We're now going to be creating our own copies of the SVN server on a semi-daily basis, and I've found instructions on how to do it on this awesome StackOverflow post. I'm just sorry I didn't know about this sooner.

Cross-compiling libexpat (and other libraries)

So, lately I've been trying to cross-compile libexpat for a new board with a different architecture from what we typically use at work, and I've been having one heck of a time, until I finally got help online from my question at stackoverflow. Turns out, I just needed to be more specific about my host architecture in the configure command:

./configure --host=arm-none-linux --enable-shared CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ AR=arm-none-linux-gnueabi-ar RANLIB=arm-none-linux-gnueabi-ranlib STRIP=arm-none-linux-gnueabi-strip

I'm going to try similar recompilation with other libraries so that I can improve the functionality of our older systems as well.

Tuesday, January 15, 2013

Journey to robust Windows Services

Because I have the need for it in several projects, I'm going to be working with Windows Services implemented with .NET quite a bit in the next little while. That said, I'd like to refer to some resources for working with Windows Services:

Also, there are some issues that I ran into while working on my first service. I had originally planned to expose a WCF endpoint through WS-HTTP, however, I can into an unpleasant exception when I tried to do so: AddressAccessDeniedException. Apparently, the cause of this is the fact that http bindings are reserved for processes run as administrators. Fool me once, shame on me. In light of that fact, I'm switching over to using net.tcp for my local Windows Service-hosted WCF service. I'll post more here as I learn it.

Adding the Network Service account to the permissions for a file/folder/registry key etc

I'm currently developing a Windows Service that's to be run under the Network Service account (owing to the fact that it requires substantial network access). I'm just starting to learn how to program Windows Services, so this is very new to me. I just started developing a simple service to start, and when I followed the instructions on this MSDN page, I was surprised when, after trying to start my service, I got the error 005: Permission denied. I later found out that I needed to give the network service account to the folder from which the service was running, i.e. the debug output folder of my project. Doing this isn't as simple as setting the permissions for other users. To add the network service account to the permissions list in Windows 7, do the following :

  1. Right click on the folder containing the service you want to debug, and go to Properties
  2. Go to the Security tab, and under the box marked "Group or user names", click on Edit ...
  3. Under the window that pops up, you'll see another box marked "Group or user names". Underneath that box, click on Add ...
  4. In the "Select Users or Groups" dialog that pops up, click on the Advanced... button at the bottom left.
  5. In the advance "Select Users or Groups" dialog that pops up, click on Find Now to find all the users, groups and built in security principals.
  6. Once the search results are populated, scroll down and select "NETWORK SERVICE" (not "NETWORK") and click on Ok, then Ok again in the Select Users or Groups dialog.
  7. One you're back to the Permissions window, ensure that you give the Network Service account Full Control over the folder in the Permissions box, then click Ok.
  8. Click Ok one last time to close the properties for your folder, and you're done.

Sunday, January 06, 2013

Wpf2WinRT: Bindings are not the same!

I've just learned something new about the bindings system in WinRT: they're not the same as Bindings in WPF. Check out the MSDN page for WinRT BindingMode, and you'll see that they're missing a value from WPF: OneWayToSource.

Migrating from WPF to Windows 8

As part of the ongoing development efforts at my company, I'm always researching the latest technologies and developments. My latest endeavour is researching Windows 8 and doing technical feasibility work to find out if it's right for us. On that front, I'm learning how to develop for the Windows 8 runtime in C#. I've got a lot of experience in WPF, and our current Line-Of-Business application is written in WPF, so I'm used to certain things, things which I'm finding no longer hold true in WinRT programming. For example, how resources such as strings are accessed in XAML. For WPF, if I wanted the internationalized string for a label, I'd do something like this : <Label Text="{x:Static resources:Messages.UserName}"/> However, the x:Static XAML extension no longer exists. Instead, you have to follow the *very different* ways of accessing string resources on this MSDN document, because the means of accessing resources for a WinRT application are both simpler (in some ways) and more robust, if a little bit confusing at first. For string (and even other resources, such as images) internationalization in WinRT, what you do is this: 1. Create a folder path for your strings: \Strings\en-US 2. Under the aforementioned folder, create a resources file named Resources.resw (not that it's not .resx, as with previous .NET applications written in Windows Forms, WPF and ASP.NET) 3. Add a new string with the Name "ApplicationName.Text". The ".Text" suffix is very important; you'll see why in a minute. 4. In your XAML, create a TextBox like this: <TextBlock x:Uid="ApplicationName" Text="" /> The Uid attribute is used for associating controls with resources, according to the MSDN link provided above, and the .Text suffix in the resource Name column, specifies the property to which the resource is linked. Honestly, I'm not sure I like the way this is going, but if it reduces code clutter, I'm willing to at least give this a try. We'll see how this pans out.

Wednesday, December 19, 2012

Finding the public key and public key token of an assembly for use with InternalsVisibleTo

It seems like one of the most common problems out there when it comes to testing and dealing with strongly-named assemblies is getting the public key and the public key token of a CLR assembly when you want to create test projects for that assembly. The quick and easy way: 1. Ensure that 'sn.exe' is in your path. If it's not, it's usually in the Windows SDK directory, typically in a folder like : C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\sn.exe 2. Open up a command window, and navigate to the directory containing the snk you're signing your assemblies with. 3. sn -p my.snk Public.snk 4. sn -tp Public.snk ...and voila, the program will print out the public key and public key token to the screen for you. The reminder I found this at was here. After you've found the public key, you'll want to paste a line similar to the following in the AssemblyInfo.cs file of the project whose internals you wish to expose:

[assembly: InternalsVisibleTo("MyCompany.ProjectName.Tests,
PublicKey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")]

Changing the default URI of a WCF web service

I recently returned to one of my previous employers since they lured me away with a better employment offer than I was currently receiving. I'm now placed on a large scale project to revamp our equipment and our software, and improve our software services to the point where we have absolute control and communication with our software out in the field. To that end, I'm presently writing a service that our field personnel's laptops will use to communicate with our home office. I've decided to implement the service in WCF since I've got experience with it and it will be the quickest route to getting a working service deployed. There are other reasons for the choice, but we won't go into those at the moment. One of the things I had forgotten about was the best practice of changing the default namespace of the service away from tempuri.org. I found an article here to remind me of how to do it, so hopefully others will be able to find it as well.

Sunday, September 16, 2012

Previews with a DataContext in WPF

Both the company I currently work for and the previous company I worked for use WPF extensively in some of their products. I recently ran across an incredibly helpful bit of functionality that aids in designing controls and forms on this blog. The TL;DR is that it lets you specify the data context that's supposed to be associated with a window / control, and lets you preview the control at design time using design data. This is useful because it lets you get an idea of what the control is going to look like with real data, and can be especially helpful when trying to size controls on a form, or seeing what lists are going to look like, and will be a real time saver because it means you no longer have to compile and start the application in order to view styles on things like DataTemplates.

Sunday, June 26, 2011

Deleting more Subversion folders

Further to my previous post on deleting subversion folders with powershell, I recently had the need to do the same in bash on linux. Here's a useful little command :
find . -name .svn -exec rm -rf {} \;

Wednesday, October 13, 2010

Determining what ports Tomcat is running on

I've recently had problems connecting to a Tomcat server setup by another developer. In order to troubleshoot these problems, I wanted to use netstat to see what ports were being bound to, but apparently server sockets don't come up by default. If you really want to see what server sockets are in use on your machine, use the following :

netstat -lntp


The undocumented 't' option will cause netstat to show server sockets.