Sunday, 4 March 2012

XML schema for log4Net

Here’s a quick reminder about the XML schema for log4Net. I use this if I choose to put the log4Net configuration in a separate file and want Visual Studio intellisense to work.
Firstly, to get the log4Net configuration into a separate file I do something like this in the application configuration file (e.g. App.config):
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>

  <log4net configSource="Config\Log4Net.config"/>
</configuration>
In the Log4Net.config file I make sure the log4Net element is given a reference to the log4Net schema and and a namespace:
<log4net xsi:noNamespaceSchemaLocation="http://csharptest.net/downloads/schema/log4net.xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  
  <!-- log4Net configuration omitted -->

</log4net>
Hey presto! We now have intellisense for the log4Net configuration file.

Thursday, 1 March 2012

Specifying x86 at the solution level and in CruiseControl.Net

On my latest project I have to ensure all the projects in a solution are built using the x86 platform. To ensure this works as expected I needed to use the Configuration Manager in Visual Studio 2010. I also needed to ensure the solution built correctly in CruiseControl.Net.

Visual Studio Configuration Manager

The configuration manager can be found is 2 ways:

  1. Go to Build > Configuration Manager…
  2. Right-click on the solution in the Solution Explorer and select Properties from the context menu. Click the Configuration Manager… button in the solution property pages dialog.

Once the configuration manager has opened you can change the build configuration for the entire solution. Here’s an example before making changes to the build configuration:

Untitled

You can now select the appropriate build configuration and platform for each project in the solution. If you change the Active solution platform you may find that the Build check boxes are all unticked. Don’t forget to tick them if you want the projects to build (note that you can get caught out here; if these check boxes are cleared and you subsequently try to Clean or Build at the solution level nothing will happen).

 Untitled1

Sometimes the x86 option is not available in the Platform dropdown next to each project. To create it select the <New…> option and in the resulting New Project Platform dialog box do the following:

  1. Select x86 under New platform:
  2. Under Copy setting from: choose Any CPU
  3. Deselect Create new solution platforms
  4. Click OK

Untitled2

CruiseControl.Net configuration

To modify the CruiseControl.Net project configuration change the MsBuild task as follows:

<msbuild>
    <executable>C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</executable>
    <workingDirectory>C:\<your>\<working>\<directory></workingDirectory>
    <projectFile>Your.Solution.File.Name.sln</projectFile>
    <timeout>600</timeout>
    <buildArgs>/p:Configuration=Release /p:Platform=x86</buildArgs>
    <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>

Note line 6 where we specify the configuration and the platform.

Monday, 23 January 2012

Counting lines of code

Not that it means a great deal every now and then you get asked for the number of lines of code in a project. Greg D answered a question on StackOverflow about this using PowerShell. I liked his answer a lot because it’s so simple. Here’s his line of PowerShell code:

(dir -include *.cs,*.xaml -recurse | select-string .).Count

Thursday, 12 January 2012

Unable to update Subversion source using TortoiseSVN

I tried to update source code coming from Subversion using TortoiseSVN but got an error. I had tried to update from a folder below the root (the “Implementation” folder in this case).

Error  Working copy ‘C:\source\<project name>\Implementation’ locked.
Error  'C:\source\<project name>' is already locked.

 

Untitled


Trying the TortoiseSVN > Release Lock... command did nothing in this case because I had not taken a lock out on any file. The solution was to use TortoiseSVN > Cleanup... from the root folder (‘C:\source\<project name>’ in this case.

Untitled3

Wednesday, 11 January 2012

APSDaemon.exe – Apple’s machine killer

I have 2 iPod Nanos that I use all the time and as such have to use iTunes. I’m a Windows user and I have to say that iTunes on Windows sucks. It wouldn’t be so bad if all you got was iTunes but you don’t; you also get a bunch of other services that drag your machine to its knees. In my case they are services I just don’t want, don’t need and wish would go away.

Anyway, APSDaemon.exe is one such piece of nonsense that is officially known as Apple Push. In my case it takes up so much CPU time my machine becomes totally unusable. It’s not the newest machine but it does have an AMD Athlon 64 3500+ processor. APSDaemon.exe will happily sit there chewing on 50% of my CPU. I have also noticed that when APSDaemon.exe is working hard so is Kaspersky Internet Security. Between the 2 of them 100% CPU is utilised. If I kill APSDaemon.exe Kaspersky also settles back down.

APSDaemon.exe seems to be invoked under 2 conditions, both of which must be addressed to stop the thing from starting:

  1. At system startup.
  2. When iTunes is started.

How to stop APSDaemon.exe from starting

  1. Pop open the task manager, find APSDaemon.exe and kill it.
  2. Go to Start > Run and type msconfig.
  3. Go to the Startup tab and find ASPDaemon.exe. Uncheck it. This will stop the application from starting when your system does.
  4. Go to C:\Program Files\Common Files\Apple\Apple Application Support and rename ASPDaemon.exe to something else (e.g. ASPDaemon.I_dont_want_this_to_run). This will stop iTunes from being able to start it.

iTunes will still start and run normally but ASPDaemon.exe will not. Result.

Thursday, 27 October 2011

Handling WCF faults in Silverlight

Here’s a quick reminder to self about handling SOAP faults in Silverlight applications, something that happened recently and I forgot a simple step.

Before going any further read this (it will probably answer all your questions): Creating and Handling Faults in Silverlight

Firstly, I had a WCF service that was exposing faults contracts using the [FaultContract] attribute.

[ServiceContract(Namespace = "http://some_namespace_here/ConfigurationService/2011/10/01/01", Name = "ConfigurationService")]
public interface IConfigurationService
{
    [OperationContract(Name = "GetConfiguration")]
    [FaultContract(typeof(MyFault))]
    [FaultContract(typeof(ValidationFault))]
    ConfigurationResponse GetConfiguration(ConfigurationRequest request);
}

The service was implemented along with fault types, for example:

[DataContract(Namespace = "http://some_namespace_here/WIRM/2011/10/01/01", Name = "MyFault")]
public class MyFault
{
    [DataMember(IsRequired = true, Name = "FaultDetail", Order = 0)]
    public string FaultDetail { get; set; }

    [DataMember(IsRequired = true, Name = "FaultCode", Order = 1)]
    public string FaultCode { get; set; }
}

The problem was that back in Silverlight when I was handling exceptions generated from service calls the exception didn’t have the specific detail of the fault. The trick to making this work is in the article linked to above. We chose to use the “alternative client HTTP stack” approach by adding this to App.xaml.cs:

public partial class App : Application
{
    public App()
    {
        bool registerResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
        InitializeComponent();
    }
}

Thereafter it was possible to get at the actual fault exceptions and take advantage of specific exception details:

private void ClientGetConfigurationCompleted(object sender, GetGetConfigurationEventArgs e)
{
    if (e.Error == null)
    {
        // Do normal processing here...
        return;
    }
            
    if (e.Error is FaultException<ValidationFault>)
    {   
        var ex = e.Error as FaultException<ValidationFault>;
        // Do stuff with validation errors (via ex.Detail)
    }
            
    if (e.Error is FaultException<MyFault>)
    {
        var ex = e.Error as FaultException<WirmFault>;
        // Do stuff with MyFault (via ex.Detail)
    }
}

That’s it.

Wednesday, 19 October 2011

Feature layers not displaying when using the ArcGIS Silverlight API

I have been using the ArcGIS Silverlight API to create a mapping application. To provide some context, the application had to show a pipe network together with valves and other associated assets. The pipes were to be selectable in the interface so that pipe asset IDs could be used to drive queries and other processing.
In order to render the valves etc. I chose to use the ESRI FeatureLayer. I also used a FeatureLayer with a Mode of SelectionOnly for pipe selection.
One of the requirements of the system was that background imagery be used. This was created using an ArcGISDynamicMapServiceLayer. The feature layers and the background layer were taking their data from different ArcGIS services.
Although my code was using MVVM the scenario could be replicated in XAML like this (this is the map control XAML only with a number of layers omitted):
<esri:Map x:Name="AWMap">
    <esri:Map.Layers>
        <esri:ArcGISDynamicMapServiceLayer 
                 ID="BaseLayerStreets" 
                 Url="http://servername/ArcGIS/rest/services/projectname/backgroundservicename/MapServer" />
        
        <esri:FeatureLayer ID="Hydrants" 
            Url="http://servername/ArcGIS/rest/services/projectname/featureservicename/MapServer/0"
            Where="1 = 1"
            Mode="OnDemand"
            Renderer="{StaticResource ValveRenderer}">
            <esri:FeatureLayer.Clusterer>
                <esri:FlareClusterer 
                    FlareBackground="Red" 
                    FlareForeground="White" 
                    MaximumFlareCount="9" />
            </esri:FeatureLayer.Clusterer>
        </esri:FeatureLayer>
    
    </esri:Map.Layers>
</esri:Map>

The problem

The problem was that as soon as the background layer was included the feature layers simply didn’t render. Handling the feature LayerInitialized and InitializationFailed events showed that the feature layers were initialised and that no errors were reported.
So what was going on?

The solution

After hours of head-scratching I reread the ESRI documentation and this popped out:
“By default, the first layer with a valid spatial reference defines the spatial reference for the map. Dynamic ArcGIS Server map and image services as well as feature layers (FeatureLayer) will be reprojected to the map's spatial reference if necessary.” - http://help.arcgis.com/en/webapi/silverlight/help/index.html#/Creating_a_map/016600000011000000/
When I checked the metadata for the 2 services in the ArcGIS Services Directory I noticed that the Spatial Reference was different for the 2 services. So, I changed the XAML to something like this (note lines 2 to 8):
<esri:Map x:Name="AWMap">
    <esri:Map.Extent>
        <esri:Envelope XMin="111111" YMin="222222" XMax="333333" YMax="444444" >
            <esri:Envelope.SpatialReference>
                <esri:SpatialReference WKID="27700"/>
            </esri:Envelope.SpatialReference>
        </esri:Envelope>
    </esri:Map.Extent>
    <esri:Map.Layers>
        <esri:ArcGISDynamicMapServiceLayer 
                 ID="BaseLayerStreets" 
                 Url="http://servername/ArcGIS/rest/services/projectname/servicename/MapServer" />
        
        <esri:FeatureLayer ID="Hydrants" 
            Url="http://servername/ArcGIS/rest/services/projectname/servicename/MapServer/0"
            Where="1 = 1"
            Mode="OnDemand"
            Renderer="{StaticResource ValveRenderer}">
            <esri:FeatureLayer.Clusterer>
                <esri:FlareClusterer 
                    FlareBackground="Red" 
                    FlareForeground="White" 
                    MaximumFlareCount="9" />
            </esri:FeatureLayer.Clusterer>
        </esri:FeatureLayer>
    
    </esri:Map.Layers>
</esri:Map>
The result was that the missing feature layer magically appeared.
So, if you are having problems with missing feature layers check your spatial references. My guess is you should change the spatial references at the server to prevent re-projection on the client; performance may be better.