Wednesday 25 December 2013

Galaxy S3 keeps notifying of "Download Complete" of photo

Since the latest Android update my Galaxy S3 keeps informing me of "Download Complete" of a photo.jpg.

I fixed this by navigating to the Download app and then deleting all of the downloads shown.

Wednesday 18 December 2013

RESTful design

Get Operations should be idempotent - performing the operation should not alter the underlying resource in any fashion. It can be performed n times and it always returns the same result.

POST should be used to create resources.

PUT should be replace the entire copy of the resource. If it exists it will overwrite it. If it doesnt exist it will create it: PUT can be used for first time creation and updates also. The difference between a POST and a PUT is that a PUT must have the resource identifier available, whereas a POST will not. So you can only PUT to create a resource if the resource identifier was generated external to the save operation.

PATCH should be used for updating part of the resource - perhaps a single field.

http://martinfowler.com/articles/richardsonMaturityModel.html

Monday 16 December 2013

Case namings

I've always referred to Camel Case as the case whereby the first letter is lower case and all compound Words thereafter are uppercase.

e.g. backColour or orderRefundId

this is how you'd name fields in .NET.

and Pascal Case is whereby the first letter is capitals (e.g. properties in .NET).

e.g BackColour or OrderRefundId

....confusingly though Camel Case can refer as upper camel case (Pascal case) or lower Camel Case. Typically though if it is not specifically mentioned then Camel Case is lower camel case.

Saturday 16 November 2013

FIX: Battlefield 4 - 2 player disconnect on a home LAN

If you play Battlefield 4 with 2 players with separate copies and separate accounts on a home network you may find an annoying problem whereby when one user logs in the other is disconnected.

 This can be solved by:

1. Log in to your home router and disable uPnP.

 then, for both computers:

2. In Windows, Go to Start > Run and type in Services.msc
3. Stop the "UPnP Device Host" service.
4. Stop the "SSDP Discovery" service.

 And restart BF4. Hey-presto - it works!

Monday 11 November 2013

Adding a SqlParameter with a null reference - Procedure or function 'Foo' expects parameter '@Name', which was not supplied.

I was debugging a historical issue raised in some legacy code over a year ago.
The problem was reported that the database was raising an error under peak load whenever a payment service was unavailable.

The database error was:

 Procedure or function 'Foo' expects parameter '@Name', which was not supplied.

After some digging it transpires that the error was due to a little gotcha in the database access code.
The code was similar to:

using (var connection = new SqlConnection("Server=localhost;Database=TestDatabase;Integrated Security=SSPI"))
{
    connection.Open();
    using (var cmd = new SqlCommand())
    {
        cmd.Connection = connection;
        cmd.CommandText = "Foo";
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(
            new SqlParameter
            {
                ParameterName = "@Name",
                SqlDbType = SqlDbType.NVarChar,
                Size = 255,
                Value = results.Reference
            }
            );
        cmd.ExecuteNonQuery();
    }
}

If results.Reference is a .NET null reference, then the SqlParameter is NOT added. In this scenario if you want to add a NULL database value then you would need to modify the code to:


    Value = results.Reference ?? DbNull.Value;

Monday 21 October 2013

In-House NuGet

ProGet is package that can be used to source in-house NuGet feeds.

Monday 12 August 2013

StyleCop versus FxCopy versus Code Analysis and MSBuild integration

What is the difference between StyleCop and FxCopy? It is described here.

StyleCop and FxCop overlap in functionality. But StyleCop analyses source code whereas FxCop analyses binaries, so StyleCop is able to pick up on source code rules whereas FxCop cannot.  FxCop tends to focus more on design rules and StyleCop is focusing on coding style (casing, white space, indents, etc).

Code Analysis in Visual Studio contains FxCop plus mode (code metrics etc).

StyleCop can be manually added to the project so that it runs as part of MSBuild. However there are issues about it sharing the same custom dictionary as Code Analysis.

Removing weekends from the TFS Sprint Burndown report

This blog describes how to remove weekends from the Sprint Burndown report in TFS.

Essentially:

Open the report in SQL Server 2012 Report Builder. Save As a new report filename in order to keep the original intact!

Right click outside of the white report canvas and select Report Properties.
Select the Code tab item.

Add the following function:
Function NumberOfDaysToAdjustForWeekends(ByVal valNow as Date, ByVal startOfSprint as Date) AS Int32

  Dim valCurrent As Date = startOfSprint
  Dim weekendDaysPassed As Int32 = 0

  Do While valCurrent < valNow

  valCurrent = valCurrent.AddDays(1)
  If (valCurrent.DayOfWeek = DayOfWeek.Saturday Or valCurrent.DayOfWeek = DayOfWeek.Sunday) Then
  weekendDaysPassed = weekendDaysPassed + 1
  End If

  Loop

  Return weekendDaysPassed

 End Function

Click on the chart, Select Work_Item_Count from the Values fact table and edit the Expression.
Change it to:

=Code.Burndown
(
Sum(Fields!Remaining_Work.Value),
Fields!DateValue.Value.AddDays(-Code.NumberOfDaysToAdjustForWeekends(Fields!DateValue.Value, Parameters!StartDateParam.Value)), Parameters!EndDateParam.Value.AddDays(-Code.NumberOfDaysToAdjustForWeekends(Parameters!EndDateParam.Value, Parameters!StartDateParam.Value))
)

Now the today line is out as it is not taking into account the weekends.
Turn on the Properties Tool Window if it is not already.
Select View menu tab and tick the Properties checkbox.
Click on the date axis.
In the Properties tool window find the Striplines property.
Edit the collection and the IntervalOffset property.
Enter the following value:
=CountDistinct(Fields!DateValue.Value, "dsBurndown") - DateDiff("d", Today(), Max(Fields!DateValue.Value, "dsBurndown")) - Code.NumberOfDaysToAdjustForWeekends(Today(), Parameters!StartDateParam.Value)

Save the report back to the server.

Monday 17 June 2013

Removing bevel on radio button in Adobe Acrobat Forms

If you convert a PDF document into an editable PDF form using Adobe Acrobat, it creates a small solid border around the radio buttons.

However sometimes you have to add your own, in by default they come with a bevelled edge.

How do you remove this? At first it looks like you can't. However you can.

Choose a border colour and a fill colour. At this point the Line Style becomes enabled and is set to "Inset". Change this to solid, and then set the border colour and fill colour back to "No colour". Bingo!

Tuesday 11 June 2013

Installing the Android Emulator

  1. Download the Android SDK and copy it into a folder, e.g. C:\Program Files (x86)\Android SDK
  2. Create a folder for your SDK home, e.g. C:\Android.
  3. Set the system environment variable ANDROID_SDK_HOME=C:\Android
  4. Run "SDK Manager.exe" and download any additional targets as required.
  5. Create a new Android Virtual Device (AVD). It will save to  C:\Android\.android\avd. 
  6. Open a new command prompt as administrator. 
  7. Run C:\Program Files (x86)\Android SDK\sdk\tools\emulator -avd <My AVD Name> -http-proxy <server>:<port> -dns-server <DNS Server> 
  8. Start the device.
  9. Go to settings->Wireless & networks->mobile networks->Access Point Names. Press menu button. an option menu will appear. 
  10. From the option menu select New APN. 
  11. Click on Name. provide name to apn say My APN. 
  12. Click on APN. Enter www. 
  13. Click on Proxy. enter your proxy server IP. you can get it from Internet Explorer's internet options menu.
  14. Click on Port. enter port number in my case it was 8080. you can get it from internet explorers internet options menu. 
  15. Click on User-name. provide user-name in format domain\user-name. generally it is your systems login. 
  16. Click on password. provide your systems password. 
  17. press menu button again. an option menu will appear. 
  18. Press save this and try to open your browser.





Tuesday 4 June 2013

"Always Running" WCF Service

A WCF service hosted in IIS is activated whenever a message is received. It processes the message, and then the service implementation is available for garbage collection. If the application pool is idle for more than the timeout period (with a default of 20 minutes), then the worker processes serving the pool are terminated.

Some services may need to perform some pre-work before they begin accepting requests (like loading in some static data). They may want to activate the application pool before any requests are made to ensure there is no delay when the first request comes in. This can be done with the AlwaysRunning settings on the application pool.

 But what about hosting a Service Bus application in IIS? A Service Bus client must create a connection to the server and keep it open for the duration of the lifetime of the application. The request-based activation does not work here.

This article describes how the application pool is automatically started, how an AutoStart Provider is used to invoke startup code to create a connection to the service bus, and how the service is restarted in the event of an application pool stopping.

References
Death to Windows Services - Long Live AppFabric

Tuesday 7 May 2013

Minecraft Service

Download Minecraft Server
Download the latest Minecraft Server
Run it, and check that it is the correct version.

Download CraftBukkit
Download CraftBukkit
Edit the batch file RunServerWithMods.cmd:

@ECHO OFF
SET BINDIR=%~dp0
CD /D "%BINDIR%"
"C:\Program Files (x86)\Java\jre7\bin\java.exe" -Xmx1024M -Xms1024M -jar craftbukkit-1.5.2-R0.2-20130608.060232-13.jar -nojline

Test the server
Test the server by running RunServerWithMods.cmd. Check that the latest client will work with the new server.
Install Summary - Download yajsw and extract to any folder.
- Open task manager and find the "java" pid under processes. This is most likely your minecraft server.
- Open a command prompt and browse to the "bat" folder under yajsw. (ex. D:\yajsw-beta-10.3\bat).
- Run genConfig.bat  (ex. genConfig.bat 2467).

Note that the config writes the value
wrapper.java.app.jar = craftbukkit-1.5.2-R0.2-20130608.060232-13.jar

for future updates to Minecraft you just need to change this line entry pointing to the new bukkit version.

wrapper.conf
- Browse to "conf" folder (ex. D:\yajsw-beta-10.3\conf) and open wrapper.conf in a text editor.
- Set the working directory (wrapper.working.dir) to your minecraft .jar server file. (ex. \minecraftserver\ for D:\minecraftserver\).
- Uncomment wrapper.app.password and enter your admin account password. Make sure the username on the line above is correct (mine was MinecraftService).
- Fill in service name and descriptions (wrapper.ntservice.name)

Create/Install Service
- Run installService.bat from the bat directory. (ex. D:\yajsw-beta-10.3\bat)
- Open Services Manager through administration tools.
- Right click the server, properties.
- Browse to "Log On" tab.
- Change to "This Account" and use the same account in your wrapper.conf.

Start the service.

You may want to create a new user account for the service. In this scenario, go to Computer Management > User Rights Assignment and Configure for Logon as a Service. I also made my service account a member of the administrators service.

Saturday 4 May 2013

Bootable USBs - IMG to USB, ISO to USB

Option 1
ISO to USB: use the Windows 7 USB/DVD Download Tool.
Option 2
IMG to USB disk imager: Win32 Disk Imager - http://sourceforge.net/projects/win32diskimager/?source=dlp

Option 3 (worked the best)
Manual steps for IMG or ISO to USB for Windows 7 or 8 is described here:
This approach involves creating the bootable USB separately from copying the files over.

Plug in your USB Flash drive if you have not already done so.
Start a Command Prompt as an administrator (click the Start button and type CMD, right-click on cmd.exe and select “Run as administrator" and accept the UAC prompt, assuming you are using Windows Vista or Windows 7)

Type diskpart and then press ENTER For each line, type the parts on BOLD and press ENTER after each entry, the notes are for reference only

DISKPART> list disk (note: this will list the disks on your system. Typically look for the one that matches the capacity of your USB flash drive)
DISKPART> select disk x (note: x is the number for your USB flash drive you obtained from the list command above)
DISKPART> clean (note: this will erase your USB flash drive)
DISKPART> create partition primary (note: this will create a new primary partition on the USB Flash drive)
DISKPART> select partition 1 (note: this will select the partition you just created)
DISKPART> active (note: this will set the new partition as active, which identifies it as a valid system partition)
DISKPART> format FS=NTFS QUICK (note: this will perform a quick format on the USB Flash drive)
DISKPART> assign (note: this will assign a drive letter to the partition)
DISKPART> exit

d, Now we need to put the boot files from the ISO image you downloaded earlier on to the USB Flash drive. You will need to mount the ISO image using SlySoft’s Virtual CloneDrive. To do this, right-click on the ISO image you downloaded (i.e. Windows8-ConsumerPreview-64bit-English.iso) and select “Mount”. If you do not see the “Mount” option, it may mean that the Virtual Clone Drive (or similar) tool is not installed. Once you have selcted “Mount”, a drive letter will be assigned to the ISO image. Make a note as to what drive letter has been assigned to the ISO, in my case drive “F:”.

Next, you will need to start a Command Prompt as an administrator (click the Start button and type CMD, right-click on cmd.exe and select “Run as administrator" and accept the UAC prompt, assuming you are using Windows Vista or Windows 7).

Navigate to your ISO drive, in my case “F:” and type the following:

cd \boot (thanks Ron T for pointing this out)

bootsect /nt60 y: (note: where y: is the drive letter assigned to your USB Flash drive – this will copy across the boot files)

e, Lastly we will need to copy the installation files across from the ISO image to the USB Flash drive. To do this, type the following:

XCOPY X:\*.* Y:\ /E /J /H (note: where x: is the drive letter assigned to your ISO image and y: is the drive letter assigned to your USB Flash Drive)

You should note have a Windows 8 Bootable USB flash drive.

NEW: Option 4

Use WinUSB Maker:

http://blog.powerbiz.net.au/online-tools/how-to-create-a-bootable-usb-from-windows-8-1-and-windows-server-2012r2-iso-media/

Saturday 27 April 2013

Set security on Freenas shares

http://tips.viktak.com/2011/03/how-to-make-freenas-work-with-active.html

Thursday 25 April 2013

Code Review policy for TFS 2012 - Custom Activity in an Agile Template

This post describes how to set up a custom Code Review policy in TFS 2012. It follows on from an excellent article by Jacob Maki which only required a few extra lines of code to get it working. I then extended it by adding an additional boolean variable parameter so that it could be enabled or disabled on the build process template - this would be useful if you wanted to configure code review policy on a per-branch basis.

So, what are we trying to achieve?
The goal here is to force developers to undergo Code Review before checking in code. TFS doesn't do this out of the box, but there are two ways of doing this:

1. Create a custom check-in policy. This is nice because it tells the user that they must perform a code-review before checking in - it stops the problem at source. However it requires a custom check-in policy which then must be distributed to all developers and it cannot be configured on a per-branch basis (unless you start coding in branch names in the code). Here is another example.

2. Alter the build process template so it checks the changesets for code that should have been reviewed. This can be done without distributing code to the developers and can be altered on a branch-by-branch basis, but it will highlight the problem after the code has been checked in and not before.

Option 1 can be simplified using TFS PowerTools for distributing the check-in policy, but for my needs, option 2 worked best. We wanted to enforce code reviews for the Main and Sprint branches, but not for Task branches.

Step one is to write a Custom Activity.


using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Build.Workflow.Activities;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Activities;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;

namespace CustomBuildActivities
{
    [BuildActivity(HostEnvironmentOption.Agent)]
    public sealed class CodeReviewPolicy : CodeActivity
    {
        ///
        /// Gets or sets the build detail
        ///
        [RequiredArgument]
        [Browsable(true)]
        public InArgument BuildDetail { get; set; }

        ///
        /// Gets or sets the team project collection.  Use Microsoft's GetTeamProjectCollection activity.
        ///
        [RequiredArgument]
        [Browsable(true)]
        public InArgument TeamProjectCollection { get; set; }

        ///
        /// Gets or sets the changesets to check for code reviews
        ///
        [RequiredArgument]
        [Browsable(true)]
        public InArgument> Changesets { get; set; }

        ///
        /// Gets or sets the comma separated list of files types to check (for example, ".sql,.cs").  An
        /// empty string means all files require review.
        ///
        [Browsable(true)]
        public InArgument CommaSeparatedFileTypes { get; set; }

        ///
        /// Gets or sets the comma separated list of files types to check (for example, ".sql,.cs").  An
        /// empty string means all files require review.
        ///
        [Browsable(true)]
        public InArgument EnableCodeReview { get; set; }

        ///
        /// Gets or sets a value indicating whether the build will fail if there is non-reviewed code
        /// matching the specified file types.
        ///
        [Browsable(true)]
        [RequiredArgument]
        public InArgument FailBuildOnNonReviewedCode { get; set; }


        /// 
        /// Performs the execution of the activity
        /// 
        /// The execution context under which the activity executes
        protected override void Execute(CodeActivityContext context)
        {
            #region Validate arguments and parameters

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

            TfsTeamProjectCollection teamProjectCollection = context.GetValue(TeamProjectCollection);
            if (teamProjectCollection == null) { throw new ArgumentException("Team Project Collection cannot be null."); }

            IBuildDetail buildDetail = context.GetValue(BuildDetail);
            if (buildDetail == null) { throw new ArgumentException("Build Detail cannot be null."); }

            IList changesets = context.GetValue(Changesets);
            if (changesets == null) { throw new ArgumentException("Changesets cannot be null."); }

            #endregion

            bool enableCodeReview = context.GetValue(EnableCodeReview);
            bool failBuildOnNonReviewedCode = context.GetValue(FailBuildOnNonReviewedCode);

            if (!enableCodeReview)
            {
                WriteBuildMessage(context, "Code review policy is disabled");
                return;
            }

            ICollection filesTypesRequiringReview = ParseFileTypesRequiringReview(context.GetValue(CommaSeparatedFileTypes));
            
            WorkItemStore workItemStore = teamProjectCollection.GetService();
            if (workItemStore == null) throw new NullReferenceException("Cannot access the WorkItemStore");

            WriteBuildMessage(context, "Checking whether any files in the changesets require a review");
            IEnumerable nonReviewedChanges = DoesBuildHaveNonReviewedCode(context, workItemStore, changesets, filesTypesRequiringReview);
            if (nonReviewedChanges == null) throw new NullReferenceException("NonReviewedChanges is null");

            WriteBuildMessage(context, string.Format("There are {0} non-reviewed changes", nonReviewedChanges.Count()));
            bool anyNonReviewedChangesets = false;
            foreach (Change nonReviewedChange in nonReviewedChanges)
            {
                anyNonReviewedChangesets = true;
                HandleChangeWithoutPassingReview(context, failBuildOnNonReviewedCode, nonReviewedChange);
            }

            if (anyNonReviewedChangesets && failBuildOnNonReviewedCode)
            {
                buildDetail.Status = BuildStatus.Failed;
            }
            else
            {
                WriteBuildMessage(context, string.Format("Code review check passed"));
            }
        }

        /// 
        /// Determines if the build has any changesets that have not been reviewed
        /// 
        /// Work item store
        /// Changesets
        /// File types requiring review (empty collection means all)
        /// Changes without a passing review
        private IEnumerable DoesBuildHaveNonReviewedCode(CodeActivityContext context, WorkItemStore workItemStore, IList changesets, ICollection filesTypesRequiringReview)
        {
            if (changesets == null) throw new ArgumentNullException("changesets", "No Changesets specified");
            if (changesets == null || changesets.Count == 0) WriteBuildMessage(context, string.Format("There are {0} changesets associated with this build", changesets.Count));

            foreach (Changeset changeset in changesets)
            {
                // The changeset object passed in may not contain the associated changes (depending on how this is executed - workflow versus unit test)
                Change[] changes = changeset.Changes.Length > 0 ? changeset.Changes : changeset.VersionControlServer.GetChangesForChangeset(changeset.ChangesetId, false, int.MaxValue, null);

                if (changes == null || changes.Length == 0)
                {
                    WriteBuildMessage(context, string.Format("Changeset {0} has 0 associated changes", changeset.ChangesetId));
                }

                foreach (Change change in changes)
                {
                    bool matchingFileToCheck = DoesChangeRequireReview(change, filesTypesRequiringReview);

                    if (matchingFileToCheck)
                    {
                        bool hasPassingCodeReview = DoesChangesetHavePassingReview(workItemStore, changeset);

                        if (!hasPassingCodeReview)
                        {
                            yield return change;
                        }
                    }
                }
            }
        }

        /// 
        /// Determines if the change requires review
        /// 
        /// Change
        /// File types requiring review
        /// True if a passing review is required, else false
        private static bool DoesChangeRequireReview(Change change, ICollection fileTypesRequiringReview)
        {
            bool matchingFileToCheck = fileTypesRequiringReview.Count == 0;

            foreach (string fileType in fileTypesRequiringReview)
            {
                if (change.Item.ServerItem.EndsWith(fileType, StringComparison.CurrentCultureIgnoreCase))
                {
                    matchingFileToCheck = true;
                }
            }

            return matchingFileToCheck;
        }

        /// 
        /// Determines if the changeset has a passing code review associated with it
        /// 
        /// Work item store
        /// Changeset
        /// True if the changeset has a passing review, else false
        private static bool DoesChangesetHavePassingReview(WorkItemStore workItemStore, Changeset changeset)
        {
            Query query = new Query(workItemStore,
                string.Format(CultureInfo.InvariantCulture,
                "SELECT [Id] FROM WorkItemLinks WHERE "
                + "[Source].[System.WorkItemType] = 'Code Review Request' "
                + "AND [Source].[Microsoft.VSTS.CodeReview.Context] = '{0}' "
                + "AND [System.Links.LinkType] = 'Child' "
                + "AND [Target].[System.WorkItemType] = 'Code Review Response' "
                + "AND ([Target].[Microsoft.VSTS.CodeReview.ClosedStatusCode] = 1 OR [Target].[Microsoft.VSTS.CodeReview.ClosedStatusCode] = 2) " // 1 = Looks Good, 2 = With Comments
                + "mode(MustContain)",
                changeset.ChangesetId)
                );

            return query.RunCountQuery() > 0;
        }

        /// 
        /// Takes the appropriate actions when a changeset does not have a passing review
        /// 
        /// Context
        /// True if the message should be treated as an error, else it will be a warning
        /// Change
        private static void HandleChangeWithoutPassingReview(CodeActivityContext context, bool treatAsError, Change change)
        {
            if (treatAsError)
            {
                WriteBuildError(context, string.Format(CultureInfo.CurrentCulture, UnreviewedFileMessageTemplate, change.Item.ServerItem));
            }
            else
            {
                WriteBuildWarning(context, string.Format(CultureInfo.CurrentCulture, UnreviewedFileMessageTemplate, change.Item.ServerItem));
            }
        }

        private static void WriteBuildError(CodeActivityContext context, string message)
        {
            if (context == null) throw new ArgumentNullException("context");
            context.TrackBuildError(message);
        }

        private static void WriteBuildWarning(CodeActivityContext context, string message)
        {
            if (context == null) throw new ArgumentNullException("context");
            context.TrackBuildWarning(message);
        }

        private static void WriteBuildMessage(CodeActivityContext context, string message)
        {
            if (context == null) throw new ArgumentNullException("context");
            context.TrackBuildMessage(message);
        }

        private static ICollection ParseFileTypesRequiringReview(string commaSeparatedFileTypes)
        {
            if (string.IsNullOrEmpty(commaSeparatedFileTypes))
            {
                throw new ArgumentNullException("commaSeparatedFileTypes", "Please specify the file types to be checked for code review");
            }

            return commaSeparatedFileTypes.Split(new[] { ',' });
        }

        public static readonly string UnreviewedFileMessageTemplate = "{0} has not passed code review.";
    }
}

Note the referenced assemblies:








Build this and then check it in to the CustomAssemblies path defined for your build controller.
At this point you may wish to add other assemblies, such as those from the TFS Community Build Extensions.



Mine are here:
 

Now alter the build process template. I am using the MS Scrum 2.1 process template and (a copy of) the corresponding default build process template.

I built a simple project, added a reference to my new Custom Activity, other references and my build process template:


Add your new activity onto the Toolbox  using the Choose Items... context menu.


Find the If AssociateChangesetsAndWorkItems activity and then the child Associate Changesets and Work Items for non-Shelveset Builds. Add a GetTeamProjectCollection activity from the toolbox and then add the CodeReviewPolicy activity.


Edit the properties of the CodeReviewPolicy. You can consume variables that have been set up earlier. Some variables, such as the output of GetTeamProjectCollection, require references to additional assemblies, but these are shown in the screenshot for the Build