Friday, May 16, 2014

I’m moving my blog to msdn

So after a year of working at Microsoft I have finally decided to pick up my blogging again. I would like to write about the engagements I undertake with customers. I am not going to mention names, but rather things that are of interest that crop up and problems that we solve in my day job.

So for work related musings please follow me here: -

http://blogs.msdn.com/b/softwaresimian/

Sunday, September 15, 2013

Creating a MSDeploy package outside of Visual Studio – gotchas

I meet with a lot of customers that have the same problems creating packages that can deploy to IIS successfully. Here is my 3 stage process.

  1. Create a web application (SampleWebApplication.sln), check it renders a page and then close Visual Studio
  2. Create a batch file at the same location as the sln file, lets say Package.bat and run it.

msbuild SampleWebApp.sln /p:DeployOnBuild=true;Configuration=Release;PackageLocation=c:\src\test\SampleWebApp.zip;DeployIisAppPath="Default Web Site\SampleWebApp"

  • By supplying the DeployOnBuild property this is the only way to call the /t:Package on a solution – otherwise you would have to build the csproj instead.
  • If you do not supply the DeployIisAppPath then inside the SampleWebApp.SetParameters.xml file you will see that the IIS Application is suffixed with _deploy which comes from the default Microsoft.Web.Publishing.targets
  • If you do not supply the PackageLocation you will find that the output is in the obj\Release\Packages folder

3.  Deploy it with msdeploy. Get a command prompt and invoke the batch file that is created for you

C:\src\test\SampleWebApp.deploy.cmd /Y /M:simian-work

All done, you should have a package that you can deploy to your server from a command line. Next we look at customising IIS a bit more.

Sunday, May 19, 2013

Changing the WCF Concurrency programatically

I have a customer who contacted me regarding a WCF service that is currently configured to have a 'Single' InstanceContextMode and during testing they have noticed that there is only ever one concurrent thread. Now this is by design as the default setting for the Concurrency is 'Single'. Ideally it would need to be set as 'Multiple' for more than one operation to be handled at a time.

Now, the customer is too close to their delivery date to recompile their code at this stage and wants to see the different options that WCF offers them within configuration. However, the InstanceContextMode and ConcurrencyMode attributes are normally set declaratively within the ServiceBehaviour attribute in the code behind. That would mean a recompilation of the service. This post is about changing this behaviour programmatically as an extension in a separate assembly.

In order to test this I wanted to create a behaviour that prevents the service from starting if it is set to 'Single' Concurrency.

using System;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

public class MultipleConcurrencyServiceValidator : IServiceBehavior
{
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        var behaviour = serviceDescription.Behaviors.Find<ServiceBehaviorAttribute>();
        if (behaviour.ConcurrencyMode == ConcurrencyMode.Single)
        {
            throw new InvalidOperationException("ConcurrencyMode set at Single - should be Multiple.");
        }
    }

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }
}
Ok, so the main points to note in this class are that we are able to interrogate the service description and retrieve the ServiceBehaviorAttribute and check what value it has been set to. But, we are not able to change any of its values, if we were to place some code in the ApplyDispatchBehavior and set the ConcurrencyMode it would not take effect as the service has already been started. Let's link this class to our service behaviour within our config file

    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFConcurrency35.Service1Behavior">
          <multipleConcurrencyValidator />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <add name="multipleConcurrencyValidator" type="WcfExtensions.Extensions.MultipleConcurrencyServiceValidator, Wcf.Extensions" />
      </behaviorExtensions>
    </extensions>

We add the type reference in and give it a name and then just add this element into the serviceBehaviour. In order to test it, we simply add the following line to our service and browse to it.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
public class Service1 : IService1

Now with our new class hooked up if we were to browse to it, we would get our exception thrown. So next let's create some code that will change the concurrency mode and get this to work again. So normally, we should create our own ServiceHost but this is just a quick example to change a behaviour that is not exposed by the framework. Let's create a service host factory class.

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;

public class ConcurrentServiceHostFactory : ServiceHostFactory
{
    public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    {
        var serviceHost = base.CreateServiceHost(constructorString, baseAddresses);
        serviceHost.Description.Behaviors.Find<ServiceBehaviorAttribute>().ConcurrencyMode = ConcurrencyMode.Multiple;
        return serviceHost;
    }

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        var serviceHost = base.CreateServiceHost(serviceType, baseAddresses);
        serviceHost.Description.Behaviors.Find<ServiceBehaviorAttribute>().ConcurrencyMode = ConcurrencyMode.Multiple;
        return serviceHost;
    }
}

This is just simple code to create our service host, change the service behaviour and return it as normal. Next, we need to get our service to be created with this factory and that is simple too; edit the svc file like so

<%@ ServiceHost Factory="Wcf.Extensions.ConcurrentServiceHostFactory" />
 
So now, we have that all tested, all I have to do to change my concurrency on an already compiled application is to add a simple Factory line into the markup of the svc file.

New job

So in 2009 I started a contract where all of my blog writing was encouraged to be internal. Personally this sucks; I believe that keeping information regarding technology inside a company's borders goes against the 'community'. As a developer lots of the knowledge I have gained has been from blogs, articles and knowledge bases. So at the start of the year, I started a new permanent position at Microsoft as an Application Development Manager. I have made a pact to start up my blog again and try and give back to the community.

Saturday, May 2, 2009

Google Chrome and XABP applications

If like me you don’t use Internet Explorer you will need this little tip. In order to get WPF applications to work in Google Chrome; simply add this to your PATH environment variables.

c:\Program Files\Mozilla Firefox

Thursday, April 30, 2009

Fix to install .Net 3.5 on Windows Server 2008 - 80073712

I have spent about four frustrating hours trying to get my Server 2008 to have the latest .Net on it. After trying to install the dontnetfx35.exe manually and it failing and reading the Microsoft blog that I should install a hot fox and if that failed I should repair my whole installation. So dutifully I did this; still the same problem!!

So I stuck with it and followed the “System Update Readiness Tool” and let it scan my component store. Whilst it was doing this I learnt about the new way that Vista and Server 2008 handle OS updates here. After the tool had run I followed the instructions and looked in the log files for any errors and low and behold it told me that it was missing a manifest with wcf, which I thought would be the reason why it could not install the latest .Net.

After reading Aaron’s blog “Steps I use to narrow down an OS update installation failure on Windows Vista and higher”, I looked at all of the logs and found that mine was failing because it stated that

DepCheck indicates Microsoft .NET Framework 2.0SP1 (x86) (CBS) is not installed

So armed with this looking in the registry (from Aarons post), I find the missing package that should have installed the wcf manifest and it gives me a Microsoft Knowledge Base (KB958481). Now I need to install MSU into Windows 2008 as it is not liking the MSI’s as they have blocks in them in order to check what version they are being installed on. But if you look at this update for dotnetfx35 you will see that it is made up of three separate updates – one of them .Net 2.0 which I need. You can download this here. So I install these two standalone patches and re-run the CRU check (1st stage). It has removed my six missing dotnet manifests, but added a whole bunch of new ones!

I need .Net 3.5 on this machine as I want to put SQL Server on this machine and I am getting frustrated as this has been about 6 hours! Then a brainwave, what about the Visual Studio WCU (Windows Component Update), so I stick the Visual Studio 2008 DVD and navigate to

The best resource I found for Server 2008 setup steps

http://technet.microsoft.com/en-us/library/cc753802.aspx

 

Ok – After all of this – the simple thing to prevent all of this is not to setup IIS before you have installed the dotnet3.5 service pack on Windows Update. I found the best way to solve all of this was to just re-install the operating system. Leave it running over night and INSTALL WINDOWS UPDATES as the very first thing

TFS 2008 problem creating Team Project. TF30171

I was attempting to create a new Team Project in TFS and it would not let me TF30177. So I realised I had an orphan project laying around.

How to delete a Team Project from TFS 2008 from TFS which was fine, but I still had the Sharepoint project. So here is how to get rid of that too.