I’ve been meaning to get around to sorting out the plethora of App.config in a large, multi project C# solution, but it wasn’t anywhere near the top of the pile of problems that needed solving. I just keep hacking values into the *.exe.config file after the build to make things work.

In a spare (and rare) 20 minutes, while drinking a coffee, I thought I’d have a quick look and discovered a really simple solution. For some reason this technique had completely passed me by. Imagine you’ve got a C# solution made up of 3 projects which build into 3 separate executables, each requiring a common config file. If you have simply added a config file to each project and try to keep them in sync you quickly end up in config hell. So rather that add a new config file to each project, simply create one in one of the projects and then link it in the others.

Here’s how, in our imaginary 3 project solution


  • Right click on Project1 and select Add->New Item->Application Configuration File and it will create a the file App.config in Project1.
  • Right click on Project2 and select Add->Existing Item and browse to Project1’s App.config file, but don’t hit the Add button. Select the Add button drop down and select Add as link.
  • Repeat for Project3

So now when you open any of the projects App.config files you will be using the same file. More importantly, when you build the solution, each projects bin/Debug (Release) directory will have it’s own, but identical copy of the config file (Project*.exe.config) leaving you the freedom to deploy the executables with their own or a common config file. Essentially, building the solution duplicates the config files from a single master version.

Itch successfully scratched.

Ever had this problem trying to remote desktop (RDP) to a Windows Server 2003? I got very frustrated by this today. All the Administrator group sessions had been used up, the selfish remoters had gone home and left themselves logged in, so I wasn’t able to admin the server. Arrrrggg!

Yes, all I needed to do was to be able to get to the Terminal Services Manager and forcably terminate their sessions, but I couldn’t get in – the keys were effectively locked in the safe. The server I was trying to admin had a limit of 2 admin RDP sessions – the default limit for Server 2003 I think.

It turns out there is a simple answer to get around this (aren’t they all simple when you know them). The number of sessions on the server is calculated on the RDP client admin sessions, but console connections aren’t included. So the work around is;

Run a cmd session on your client machine and start a console based terminal service to the machine you want to connect to.

mstsc /v:xxx.xxx.xxx.xxx /f -console

where xxx.xxx.xxx.xxx is the IP or resolvable server name

You can then use Control Panel->Administrative Tools->Terminal Services Manager to disconnect the selfish remoters and connect with the RDP client as normal.

Don’t forget to logoff yourself when you’ve finished though.

Yesterday I was mainly deploying a new release of php code to a Linux server.  Not that it’s a problem, but I normally develop php web application on IIS running on Windows Server just because I know where all the knobs and switches are.  VS.PHP from jcx.software is a great add-in for Visual Studio and with the Zend server side debugger it makes an awesome development environment. Sure I could use Eclipse PDT in a similar way for free, but ‘m more productive using Visual Studio; rightly or wrongly, the keyboard shortcuts are now part of my DNA.

I never quite feel comforable using Linux and I’m not sure why. Clearly it’s an excellent OS and I have  several embedded boxes which have been running Linux that I’ve never had to reboot. My WRT54G and NSLU2 always perform flawlessly. However, while on my journey home last night I realised what the problem might be. Linux makes my fingers hurt with all the typing I have to do!

Anyway, tip of the day for me was this little gem. I needed to copy the (massive) previous releases directory into my deployment working area and was happily using

cp -r blah blah

Then I started worrying about whether the permissions were being copied. (Ok so I’m happy to admit my perpetual virgin status when it comes to Linux). It was then pointed out to me buried in the directory structure were a raft of symbolic links and using cp would do a deep copy and fill up my server disc space pretty quickly. “Use tar to copy from the current directory to the new one like this”, they said.

tar cBf -.|(cd new_directory && tar xvBf -)

It worked a treat, I feel less like a Linux virgin, but my fingers still hurt.

There loads of these all over the place, but here’s some useful preg_replace examples for text and html processing that were hard to find or I ended up writing  – use/praise/embellish/flame as you see fit.

Remove repeated words (case insensitive)

$text = preg_replace("/\s(\w+\s)\1/i", "$1", $text);

‘Keep your your head’ becomes ‘Keep your head’

 Remove repeated punctuation

$text = preg_replace("/\.+/i", ".", $text); 

 ‘Keep your head…’ becomes ‘Keep your head.’ Don’t forget to escape regex characters.

Clean up a sentence end that has no trailing space

$text = preg_replace("/\.(?! )/i", ". ", $text);

‘Keep your head.Don’t fall apart’ becomes ‘Keep your head. Don’t fall apart’  This uses lookahead.

Remove carriage returns, line feeds and tabs

$text = str_replace(array("\r\n", "\r", "\n", "\t"), '', $text);

An oldy but goody.

Get all image urls from an html document

$images = array();
preg_match_all('/(img|src)\=(\"|\')[^\"\'\>]+/i', $data, $media);
foreach($data as $url)
	$info = pathinfo($url);
	if (isset($info['extension']))
		if (($info['extension'] == 'jpg') || 
		($info['extension'] == 'jpeg') || 
		($info['extension'] == 'gif') || 
		($info['extension'] == 'png'))
		array_push($images, $url);
Puts all the image URLs in an array

Strip non printable characters

$text = preg_replace("/[^[:print:]]+/", "", $text);

Does what it says on the tin

Remove HTML tags

$text = preg_replace
	// Remove invisible content
	// Add line breaks before & after blocks
	' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
	"\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0",
	"\n\$0", "\n\$0",),$text
// Remove all remaining tags and comments and return.
$text = strip_tags( $text );

Ok, so strip_tags sort of does this, but fails to remove script, style etc etc.

PHP performance tips

April 22, 2009

It’s Sunday morning, the weather’s terrific and I’m sitting at the desk in the office at home finishing off some project work that should have been done on Friday. Still, it’ll be done in a jiffy and I can take the dog out to the meadow in St Ives and reflect on why I don’t work at home every day rather than waste 4 hours commuting. It’s more productive, it doesn’t seem like work and I just get more time.

Anyway, I can’t talk too much about the project itself, other than it’s a website developed using PHP which involves extensive natural language parsing and processing. It needed to be performant and scalable so, although I’ve used PHP many times before, I thought it would be useful to revisit PHP performance.

Consequently, I build a small performance testing framework so I could quickly evaluate which PHP methods yielded the best results. Over the duration of the development I’ve compiled the following list which I thought I’d share.

  • Use single quotes over double quotes.
  • Use switch over lots of if statements.
  • Avoid testing loop conditionals with function tests every iteration eg. for($i=0;i<=count($x);$i++){…
  • Use foreach for looping collections/arrays.
  • PHP4 items are byval PHP5 items are byref
  • Consider using the Singleton Method when creating complex PHP classes.
  • Use POST over GET for all values that will wind up in the database for TCP/IP packet performance reasons.
  • Use ctype_alnum,ctype_alpha and ctype_digit over regular expression to test form value types for performance reasons.
  • Use full file paths in production environment over basename/fileexists/open_basedir to avoid performance hits for the filesystem having to hunt through the file path. Once determined, serialize and/or cache path values in a $_SETTINGS array. $_SETTINGS[“cwd”]=cwd(./);
  • Use require/include over require_once/include_once to ensure proper opcode caching.
  • Use tmpfile or tempnam for creating temp files/filenames
  • Use a proxy to access web services (XML or JSOM) on foreign domains using XMLHTTP to avoid cross-domain errors. eg. wibble.com<–>XMLHTTP<–>wobble.com
  • Use error_reporting (E_ALL); during debug.
  • Set Apache allowoverride to “none” to improve Apache performance in accessing files/directories.
  • Use a fast fileserver for serving static content (thttpd). static.mydomain.com, dynamic.mydomain.com
  • Serialize application settings like paths into an associative array and cache or serialize that array after first execution.
  • Use PHP output control buffering for page caching of heavilty accessed pages
  • Use PDO prepare over native db prepare for statements. mysql_attr_direct_query=>1
  • Do NOT use SQL wildcard select. eg. SELECT *
  • Avoid using SQL directive DISTINCT
  • Use database logic (queries, joins, views, procedures) over loopy PHP.
  • Use shortcut syntax for SQL inserts if not using PDO parameters parameters. eg. insert into sometable (field1,feild2) values ((“x”,”y”),(“p”,”q”));
  • Use Zend – it’s the best PHP library around

Comments on a postcard please.

QuickTime, short temper

February 19, 2009

I’m currently setting up a trancode farm using Rhozet CarbonCoder. What a great piece of software this is and a dream to configure and use when compared with FlipFactory. And it’s very cheap!

However, it requires QuickTime to run – no problem I thought – but you try installing and running QuickTime v7.6 on Windows Server 2003 SP1. It installs fine, but absolutely refuses to run, unhelpfully telling you…

QuickTime failed to initialize (error -2096).

A quick search reveals it may be a compatibility issue. There is an article indicating that turning off Compatibility mode would resolve this issue, but Compatibility mode is not turned on for iTunes or QuickTime.

The same issue is discussed in the Quicktime forum, here:

I struggled for a couple of hours, frustrated by something seemingly so simple stopping me doing what I needed to do – as usual in a hurry. I lost count of how many times I installed and then uninstalled QuickTime and CarbonCoder. I even resorted to cleaning the registry of any refernces to QT.

I eventually gave up and decided to go home. As I was walking out I realized I hadn’t actually tried installing an older version. I quickly grabbed v7.2 from the Apple site and – hey presto – it worked.

Now the point of all this really is the Apple support forum driving me mad. Yes, there’s an article posted there with a few replies http://discussions.apple.com/thread.jspa?messageID=6595367 but it’s been archived (so no replies) so now I can’t post my conclusive findings.

On the one hand I think Apple is great compared with Microsoft. On the other I think they are just as bad as each other. I guess the wind is blowing and it changed my mind for the day.

Is that video for real?

November 21, 2008

Extreme makeover: computer science edition

Stanford artificial intelligence researchers have developed software that makes it easy to reach inside an existing video and place a photo on the wall so realistically that it looks like it was there from the beginning. The photo is not pasted on top of the existing video, but embedded in it It works for videos as well – you can play a video on a wall inside your video. The technology can cheaply do some of the tricks normally performed by expensive commercial editing systems.