Jesper Niedermann's .NET Blog
about .NET and related technologies RSS 2.0
# Sunday, 08 June 2014

I must admit that I prefer SVN over GIT due to the (in 2014 only slightly inferior) tooling and due to the illogical naming and structuring of commands and parameters.
But still GIT has a lot going for it, and I needed the GIT submodule command for a private project of mine  i.e. something that I want to sell
and therefore not place on github.

So away with SVN.

On my trusted Synology I have the SVN server installed which was basicly just plug and play. So I figured that installing the GIT server package would be just as easy.

Sadly that was not case. Now 6 hours later I finally have it working. So this post is here, to hopefully save you and my future self some time.

This is a rundown of what I should have done.

  1. Upgrade to at least DSM 4.3 ( I used 4.2 but the GIT Server package did not work with that. Basicly there was no git commandline interface).
  2. Install the GIT Server package from Synology
  3. Create a user on the server to access GIT
  4. Create a Share for GIT (e.g. named “gitrepo” or similar)
  5. If using a windows client. Install putty to issue GIT commands to the server via SSH (you have to enable SSH on the server)
  6. Issue commands to make a bare server GIT Repo

    mkdir somerepo.git
    cd somerepo.git
    git init --bare –shared

  7. Login to Putty as root (important). Change the owner to be your newly created git User

    hown -R gituser somerepo.git

  8. You can now clone the repo from your prefered Git client – using ssh.

    btw. When using ssh you should access it via full path. I.e. ssh://gituser@<servername or ip>/volume<x>/gitrepo/somerepo.git

Of these steps (not) upgrading to DSM 4.3 was most costly because nothing anywhere indicated that I could only use GIT server after upgrading.

I also had problems changing ownership of files. Turned out I just needed to login to putty as root. Probably just basic linux knowledge that I do not have.

Same goes for the ssh path. I naturally thought the path would be the same as for https i.e. without the /volume<x> part.

So basicly it works now, although I still have to decide on the security part.

Should it be with username/password or a putty key, should I open up my firewall to allow me access from the internet and so on.

Sunday, 08 June 2014 15:00:47 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -

# Wednesday, 07 September 2011

I finally got around to upgrading and releasing Solzip for VS2010.

Solzip is a tool for zipping Visual Studio C# solutions from a right click menu in the solution explorer. You can also Zip individual projects.

You can install it from or from the Extension Manager in Visual Studio.

You can choose to install a command line version or the Visual Studio version either one that requires MME or a single file install which includes MME. Furthermore there is a GAX version for the ambitious.

The one you install from the Extension Manager is the single file install.

BTW: In case you did not notice I upgraded MME in July to enable right click menus in the code window as well as in the solution explorer.

Wednesday, 07 September 2011 08:09:15 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -

# Thursday, 28 July 2011

When making the WP7 game Photo Challenge we quickly agreed that we needed leaderboards. The problem is that is time consuming to build a scalable high quality leaderboard service tailor made for our game and secondly we would have to pay for server storage for a game that statistically won’t make a dime anyway. This meant that we searched for a ready to use leaderboard service. It wasn’t easy to find. But then a miracle happened. We found the amazing is an incredible fit for our game.


  • Most importantly there is great support from the developer Karl Seguin when you run into trouble (which we did – actually one of our problems led him to find and fix a bug in the service).
  • It has an easy to use API. The basic API is Rest based with data transferred in JSon format. This means that is possible to access the leaderboards from any application. I am currently working on an ASP.NET MVC / JQuery based web page to access our leaderboards on the web.
  • On top of the REST API there is a WP7 API which you can reference from your game and it looks like an Android API is currently under development.
  • When you register an account you gain access to adding any number of games, to each of these games you can add a number of leaderboards.
  • Furthermore supports achievements and even has some Facebook integration which I haven’t looked into yet.
  • There is also statistics. A cheap way to see the popularity of your game. On the AppHubs you can see number of downloads, but on you can actually see how many are playing your game.
  • For accessing a leaderboard from your game you use a gamekey a  leaderboardkey and a secret. Each of these are Guid like Id’s. You can fetch pages of 50 scores at a time, and you can get the Rank of a specific user.
  • The leaderboards can be defined as High-to-low or low-to-high. Meaning if it is preferable to have a low or a high score.
  • Each score is associated with a username, a rank and the date&time at which the score was added.
  • In the WP7 API there are a number of ways to define a user in terms e.g. one uses your liveid and another the deviceid combined with a username. The last one is the one we use. This means that 2 users with the same username but different phones will be two distinct users on the leaderboard.

To get started you should download the code from Github and look at the samples there. Furthermore I found this nice blogpost to help me get going

In you can see a screenshot of the graphical look of the leaderboard we came up with in Photo Challenge.

Thursday, 28 July 2011 23:35:35 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Games & Puzzles | Windows Phone 7
# Tuesday, 26 July 2011

I and a team of 1 graphic artist and 1 sound engineer just finished our first game for Windows Phone 7 called “Photo Challenge” a few weeks ago. We planned this pretty simple game to get experience before going for the big hit. The concept has been seen before. A Puzzle Slider where you have to solve a square puzzle with 2x2, 3x3, 4x4, 5x5 or 6x6 squares with one square missing. The Puzzle can be made from you own photos or from some build in ones. Here is a few screenshots:


The point of the game is to solve the puzzle as fast as possible to make it to the leaderboards. We used the great service for the leaderboards. I plan to cover that aspect in another post.

We are very satisfied with the style and feel of the final game. Even for such a simple game details are important. Similar competing games seems to have been made in Silverlight and thus are more limited with regards to graphics and sound than our XNA game.

Some of the learnings from making the game are:

  • XNA is a fantastic framework and my own framework for XNA developed over time for PC and XBox could be used directly with very few changes.
  • WP7 has a fantastic developer platform. IMO better than the iPhones.
  • The WP7 API’s still lacks a lot of functionality that is present in the iPhone API’s but slowly catching up.
  • If you use some of the build in “Tasks” like the PhotoChooserTask or the MarketplaceReviewTask you cannot play sounds on the device if it is connected via USB to the computer. Sounds like a small thing but it means you cannot debug on the device ! Really horrible. My solution was to not play music and sound effects in the DEBUG edition.
  • On the other hand you can debug on the emulator. On the iPhone it is extremly important to debug directly on the iPhone because the iPhone simulator cannot be trusted. I have often experienced that code working in the iPhone simulator was not working on the device. This never happened once for the WP7 emulator and my Samsung Omnia 7. Still it is important to be able to debug on the device since there are things not available in the emulator.
  • As mentioned the API is somewhat lacking. E.g it is impossible to send images in emails via the EmailComposeTask. It is not possible to integrate facebook in an XNA app and so forth. The last one is supposed to be fixed in the Mango update since it has opened up for mixing Silverlight and XNA. I have not tried it yet. But hope it will be possible. Facebook integration in games is almost a must these days.
  • Despite being extremely happy with the developing experience for WP7 the iPhone is still an overall better smartphone experience in my opinion (seen from a user perspective). I hope and think WP7 will catch up in time. Competition is good.
Tuesday, 26 July 2011 23:47:58 (GMT Daylight Time, UTC+01:00)  #    Comments [5] -
Games & Puzzles | Windows Phone 7 | XNA
# Sunday, 24 July 2011

When we were to publish a free version of our new Windows Phone Game Photo Challenge I wanted to maintain both the free and paid version in the same Repository. I wanted the solution file and project file for the new free app to use the same source files as the paid app. This gave some headaches because there needs to be a physical WMAppManifest.xml file for each App. I googled various approaches but I finally made up an entirely different approach which I thought fitted our project best. Here is the steps I took:

  • Copied the solution file PhotoChallenge.sln to PhotoChallengeFree.sln – placed in the same folder
  • Copied the project file PhotoChallenge.csproj to PhotoChallengeFree.csproj – placed in the same folder
  • Changed PhotoChallengeFree.sln via notepad to refer to PhotoChallengeFree.csproj
  • Copied AssemblyInfo.cs to two new folders. One for the paid app and one for the free app.
  • Deleted AssemblyInfo.cs from both PhotoChallenge.csproj and PhotoChallengeFree.csproj
  • From PhotoChallenge.csproj I linked to the new Paid version of AssemblyInfo.cs – using Add –> Existing File, but choosing Add As Link instead of Add.
  • The same in PhotoChallengeFree.csproj. But this time linking to the Free version of AssemblyInfo.cs
  • Changed the following properties in the free version of AssemblyInfo.cs: AssemblyTitle, AssemblyProduct and Guid.

I actually wanted to manipulate WMAppManifest.xml in the same way as I did AssemblyInfo.cs. But this turned out to be impossible. The WMAppManifest.xml file has to be physical – not a link. Instead I did this:

  • Made a project folder in PhotoChallenge.csproj called PropertiesPaid
  • Made a project folder in PhotoChallengeFree.csproj called PropertiesFree
  • Copied WMAppManifest.xml to the new folders and added the relevant one to each project.
  • Deleted WMAppManifest.xml from the properties folder.
  • Opened the project files in Notepad (actually I chose “Unload Project” in Visual Studio and then “Edit PhotoChallenge.csproj”). And changed this:

To this:


Then I reloaded the project in Visual Studio, and did the same for the free project. But now refering to the PropertiesFree folder.

In the free version of WMAppManifest.xml I changed the Title and TokenId to match the AssemblyTitle and AssemblyProduct of AssemblyInfo.cs. Furthermore I changed the ProductId to match the Guid of the AssemblyInfo.cs.

The actual differences between the free and paid version in the source file I maintain using a new compilation symbol I made called “FREE” so I can make statements like this:

#if FREE
//Some code

Altogether my approach seems to work extremely well to minimize maintainance of the two versions of the same app.

One small problem: For some reason which I have not bothered to find out I cannot use the Compilation symbol Free in the PhotoChallenge.csproj project itself, but I have some other referenced projects where it is no problem. So I just have a class in the referenced project which I can use where ever I have to check if the current version is paid or free:

public static class Edition
public static bool IsFree
#if FREE
return true;
return false;
Sunday, 24 July 2011 19:46:58 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Visual Studio | Windows Phone 7
# Monday, 18 April 2011

I like the new look and feel of IE9 but it is not without startup problems though. If you want to use Google as your favorite search provider what do you do ? Well lots of places on the web tells you to go to “Internet options” –> Change Search Defaults (Settings) and then press the lower left link “Find more search providers…”.

I did this but was perplexed. Google was not listed !

After going back and forth a few times I noticed something in the address bar.

Notice the “da” in the link. Apparently the link is dependent on your country of origin.

So I changed it to

And sure enough. I could now choose Google as my default search provider.

Hope this helps someone :)

Monday, 18 April 2011 09:02:31 (GMT Daylight Time, UTC+01:00)  #    Comments [4] -
# Tuesday, 31 August 2010

The new Guidance Automation Framework GAX 2010 and GAT 2010 which is installed through the Extension Manager in Visual Studio 2010, provides a nicer usability experience compared to the Visual Studio 2008 predecessor. It is installed using the new vsix installer. A vsix install is much nicer than the old msi install since it integrates into Visual Studio. You can uninstall using the Extension Manager and if a new version comes out it should appear on the Updates tab of the extension manager.

Another nice thing is that a generated factory template solution now only consists of one project which itself results in a vsix file. So the installer of your own generated factories will also be vsix files. Nice…

But nicest of all is the fact that it is automatically integrated with the Visual Studio 2010 Experimental Instance (formerly known as Experimental Hive). Before you had to manually edit your recipes to get them to register in the Experimental Hive. But know you just press Ctrl+F5 and the Experimental Instance is automatically launched with your factory installed. It is now almost easy to debug your recipes. :)

But apparently there are few weird bugs in GAX/GAT 2010. One I run into all the time is this error:

Unable to read the project file 'Something.csproj'.

C:\Something\Something\Something.csproj(354,3): The imported project "C:\Microsoft.Practices.RecipeFramework.Build.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

Which happens when I try to open a Guidance Automation solution.

For some reason the declaration of the variable RecipeFramework in the project file is not provided. This I deal with by editing the Project file by hand and adding a declaration to the end of the first PropertyGroup like this:


  <RecipeFrameworkPath>$(DevEnvDir)Extensions\Microsoft patterns and practices\GAX 2010\2.0.20406.0</RecipeFrameworkPath>

After applying this fix I can open the solution.

I have read somewhere that it is important to adhere to the following install order:

    1. Visual Studio 2010 Ultimate or Professional (obviously)
    2. The Visual Studio 2010 SDK
    3. GAX 2010
    4. GAT 2010

And this might be what I have screwed up on the particular machine where I get the error.

Anyway the above mentioned fix works. And overall I am very satisfied with the new improvements in GAX/GAT.

Tuesday, 31 August 2010 17:31:11 (GMT Daylight Time, UTC+01:00)  #    Comments [1] -
.NET | GAX | Tips & Tricks | Visual Studio
# Sunday, 13 June 2010

Imagine that you want to make an extension for Visual Studio 2010 that creates new custom right click menus for the Solution Explorer. Imagine that you could do it by just implementing a good old .NET interface like this:

public class MenuManager : IMenuManager
public IEnumerable<IMenuItem> GetMenus(ContextLevels menuForLevel)
var menuItems = new List<IMenuItem>();
var menuItem1 = new MenuItem("My Menu1");
var menuItem2 = new MenuItem("My Menu2");
return menuItems;

public string MainMenu()
return "My Main Menu";


Well it turns out you can. In MME I have helped you do exactly that. No more using the convoluted add-in model of Visual Studio to accomplish this goal. And it is also much simpler than using GAX/GAT (that can do so much more to be fair).

You can easily install MME, either by downloading directly from Codeplex or by installing directly from the Extension Manager in Visual Studio 2010 (you can find it under the Tools menu).

MME does not work for the Express editions of VS.

I also recommend installing the MME MenuManager template which you can also find in the Extension Manager.

At codeplex you can read more about implementing and deploying MME’s and also get further insight on the architecture.

Sunday, 13 June 2010 18:20:02 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Tools | Visual Studio
# Wednesday, 12 May 2010

Windows developers who are used to click events in WinForms, WPF or Silverlight might miss click and double click events, but because of the game loop where everything is drawn and updated every few milliseconds an event based approach is probably not a good idea in most cases. Not so much because of the performance of an event based approach, but more because the complexity is overwhelming. If several users clicks and double clicks several keys on the keyboard simultaneously, how would you decide which of these are clicked and in which order, and further more it is not obvious to subscribers of the events that they are in the game loop, so they might do code which performs inadequately.

I have made a few generic classes that expands the MouseState, GamePadState and KeyboardState in order to make click “events” available. But of course I utilize the standard polling mechanism in XNA which is to call GetState() on each device.

The approach is that I call my own version of GetState() in the main game loop. My GetState() method first enqueues the state in a Queue, and then dequeues all states older than 500 ms, before the state is returned. In this way a historical map of user interactions is maintained at all times.

Now I can simply check if a key or button was clicked by checking if the key was pressed and then released “historically”. Similarly I can check for double click by checking if the key or button was pressed, then released, then pressed again and then released again.

Now you probably realize why I go back 500 ms. It is because this is the standard time in which a double click should be executed.

I have used this approach in the game Protect the Carrot at and it works like a charm (The url for the game does not work today, since the game will only be published in a few weeks).

Here is the implementation of the MouseExtended class which uses this approach:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;

namespace PTC.Input
public class MouseExtended : InputDeviceExtended<MouseState>
private static MouseExtended m_Current;
public static MouseExtended Current
if (m_Current == null)
m_Current = new MouseExtended();
return m_Current;

public MouseState GetState(GameTime currentTime)
MouseState state = Mouse.GetState();
EnqueueNewState(currentTime, state);
return state;

private bool ClickCount(MouseButton checkButton, int requiredCount)
ButtonState found = ButtonState.Released;
int count = 0;
foreach (InputStateExtended<MouseState> stateExt in RecordedStates)
if (found == ButtonState.Pressed &&
ButtonStateToCheck(stateExt.State, checkButton) == ButtonState.Released)
if (count >= requiredCount)
return true;
found = ButtonStateToCheck(stateExt.State, checkButton);
return false;

private ButtonState ButtonStateToCheck(MouseState state, MouseButton checkButton)
switch (checkButton)
case MouseButton.Left:
return state.LeftButton;
case MouseButton.Middle:
return state.MiddleButton;
case MouseButton.Right:
return state.RightButton;
case MouseButton.XButton1:
return state.XButton1;
case MouseButton.XButton2:
return state.XButton2;
return state.LeftButton;

public bool WasSingleClick(MouseButton checkButton)
return(ClickCount(checkButton, 1));

public bool WasDoubleClick(MouseButton checkButton)
return (ClickCount(checkButton, 2));


And here is the generic InputDeviceExtended class which MouseExtended inherits:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace PTC.Input
public class InputDeviceExtended<S> where S : struct
private Queue<InputStateExtended<S>> m_RecordedStates = new Queue<InputStateExtended<S>>();

public Queue<InputStateExtended<S>> RecordedStates
get { return m_RecordedStates; }

private Stack<InputStateExtended<S>> m_StatesForReuse = new Stack<InputStateExtended<S>>();

protected void EnqueueNewState(GameTime time, S state)
if (!state.Equals(m_CurrentState))
m_CurrentState = state;
m_RecordedStates.Enqueue(CreateState(time, state));

private S m_CurrentState;
public S CurrentState
get { return m_CurrentState; }

protected void DequeueOldStates(GameTime currentTime)
InputStateExtended<S> state = null;
if (m_RecordedStates.Count > 0)
state = m_RecordedStates.Peek();
if (state != null && state.StateTime < currentTime.TotalRealTime.Subtract(new TimeSpan(0, 0, 0, 0, InputDeviceConstants.ClickCountTimeMS)))

private InputStateExtended<S> CreateState(GameTime time, S state)
if (m_StatesForReuse.Count > 0)
//Reuses the object to fight of the GC
InputStateExtended<S> stateExt = m_StatesForReuse.Pop();
stateExt.StateTime = time.TotalRealTime;
stateExt.State = state;
return stateExt;
return new InputStateExtended<S>(time, state);

Notice that the Recorded States are reused. When dequeued from the queue the are added to a reuse stack. This is a standard trick to fight of the Garbage Collector, by always keeping a reference to objects on the heap they never become garbage + they are reused so the memory use will not explode.

I have also implemented the necessary extended classes for the Keyboard and the gamepad. I have included them in the attachment to this post. I have not tested the GamepadExtended class since I do not own a Gamepad, but it is implemented exactly as the keyboard and mouse classes and ought to work.

To wire up the new classes you just add the relevant Getstate() calls to the Update game loop like so:

protected override void Update(GameTime gameTime)

And then you can check for click and double click “events”. For instance you check for double click of the left mouse button like this:

//Do double click reaction

Hope you like the stuff.And look out for the amazing “Protect The Carrot” game within the next month or so, at

In I have included the code for all the InputDevice classes.

Wednesday, 12 May 2010 21:38:51 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | Tips & Tricks | XNA
# Sunday, 07 March 2010

In Microsoft CRM you have no choice when doing updates to the database. You have to use the CRM Web Service.

Microsoft does not support direct SQL updates of the underlying SQL Server tables, because of the behind the scenes CRM magic.

The Web Service is OK for small amounts of data. But recently I had a case where I had to code an import of a spreadsheet with up to 100.000 rows into CRM.

This would result in 600.000 web service calls, since there was 5 retrieves for each updates. The first tests showed that each web service call would be about 1,5 seconds even though they were done internally on the CRM server a fast quad-core 64 bit machine. This would be 900.000 seconds or 250 hours, more than 10 consecutive days.

Too slow for our particular business need.

Fortunately UnsafeAuthenticatedConnectionSharing came to the rescue.

proxy.OnGetWebRequest += (sender, e) =>
e.WebRequest.ConnectionGroupName = InitUserId.ToString();
e.WebRequest.UnsafeAuthenticatedConnectionSharing = true;

On the CrmService proxy you set the UnsafeAuthenticatedConnectionSharing to true. This just means that other calls to the web service will use the same connection to the database, and without reauthenticating. Which means that the next call with UnsafeAuthenticatedConnectionSharing set to true, will use the same connection. And will be assumed to be the same user. ConnectionGroupName is a convenient way to split up the connections so that we don’t accidentally reuse connections between different users. This can be done simply by using the guid of the current CRM User.

And now the important thing. This makes the web service call take 3/100 seconds. About 50 times faster ! The 600.000 calls can be done in 5 hours. Of course this speed was only attained because all calls where done internally on the CRM Server.

So why are these two settings not the default ? I don’t know. Perhaps because if you have a site with millions of users the amount of memory used up by each connection will be too big. But on a typical CRM site I would guess there would not be enough users to make this a problem.

But to be safe, if you just use the 2 properties in the areas that need performance with little concurrency between users you will be OK.

This and other performance best practices for CRM can be seen on technet. But I don’t think any will outperform this one.

Sunday, 07 March 2010 14:39:19 (GMT Standard Time, UTC+00:00)  #    Comments [0] -

<2018 September>
About the author/Disclaimer
I am a software architect with focus on Microsoft Technologies. I have been working with these in different large companies since 1995. I am currently employed at UVdata A/S.
Here is my View Jesper Niedermann's profile on LinkedIn

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Privacy policy
The privacy policy of this site.

© Copyright 2018
Jesper Niedermann
Sign In
Total Posts: 28
This Year: 0
This Month: 0
This Week: 0
Comments: 32
All Content © 2018, Jesper Niedermann
DasBlog theme 'Niedermann' created by Jesper Niedermann, based on 'Business' created by Christoph De Baene (delarou)