in

But it works on my PC!

The random thoughts of Richard Fennell on technology and software development
  • Remember the new URL format for the TFS2010 web services have changed

    To have a good look at TFS2010 I have migrated some existing VS2008 projects to VS2010. This has meant they are now being built using a new TFS 2010 build server. Now I wanted to make sure everyone still knew what was building and what was not, so I updated the configuration on our build wallboard to get the status from both the older 2008 and the new 2010 server – and it did not work. I fiddled around, upgraded the build wallboard to use the TFS2010 assemblies, all to no avail, the application just exited when I tried to get a reference to the build service.

    Then I had another think, the Url of the TFS server has changed format in 2010. It used to be http://my2008server:8080 it is now http://my2010server:8080/tfs. I had been leaving off the trailing /tfs, an easy mistake to make. Once this was corrected my old build wallboard worked without a problem, there was no need to use the TFS2010 assemblies in the project.

  • Visual Studio 2010 project upgrade bug; test assemblies being copied to release folders in error

    After I upgraded an ASP.NET Web Application VS2008 solution to VS2010 I found a strange problem. When I build either the whole solution or the test project in the solution the test assembly gets copies to Web Applications bin directory. However if I build the solution from the command line with MSBUILD they are not copied (so MSBUILD behaves as VS2008 used to).

    Turns out it is easy to repeat, the process is as follows:

    1. Open Vs2008 SP1
    2. Create an empty solution
    3. Add a C# Class library project (targeted on .NET 3.5)
    4. Add a C# ASP.NET Web application (targeted on .NET 3.5)
    5. Add reference from the web application to the class library
    6. Build the solution, note that we see the class library and web application assemblies are in the web application bin directory
    7. Add a C# Test project 3.5 (targeted on .NET 3.5)
    8. Add reference to the Web application project
    9. Build the solution, note that we still just see the class library and web application assemblies are in the web application bin directory – there is no test assembly
    10. Exit VS2008 and load VS2010
    11. Load the solution and allow it to be upgraded. On the dialog about .NET versions say to leave the projects on .NET 3.5.
    12. Rebuild the solution and note that now in the Web Application bin directory we have the class library, web application and test assemblies
    13. Do a clean of the solution, note that in the Web Application bin directory the test assembly is not removed.

    So why is this a problem? .NET 4.0 is a replacement for previous .NET version not an extension as 3.0 and 3.5. were for 2.0. This means basically that in any given deployment you need to have all 4.0 assemblies or all 2.0, 3.0, 3.5 ones. However, under VS2010 a test project must target .NET 4.0 (to get all the new cool testing features), so the fact at this 4.0 test assembly ends up in a 3.5 based Web Application directory is a problem.

    I have no answer to the problem as yet, though I have reported it. At present the workaround is to either

    1. Delete the test assemblies from the Web Application bin directory. once this is done everything behaves as you would expect.
    2. Or make sure you only target .NET 4.0, though I suspect this might be an issue for some people developing web applications as it will be a while before we see ISP deploying .NET 4.0
  • Re-awarded MVP

    I am really happy to say that I have had my MVP for Team System Re-awarded, it is a privilege to get to work with such a great group of people as a have met via the MVP programme.

    Posted Jul 02 2009, 01:32 PM by Richard with no comments
    Filed under:
  • Problems with uplink on an 8 port Netgear Gigabit switch

    All the ports on the Netgear GS608 I think are meant to be auto speed and uplink sensing, I have found this not to be true. I had the 1Gb uplink to our central switches in Port 8 and a 100Mb Ethernet workstation in port 2 could not get an IP address via DHCP. When I moved the uplink to Port 1 it all leapt into life. Interestingly other 1Gb PCs in other ports had no problem with the uplink in either port 1 or 8.

    So my tip is put you uplink in port 1 on a Netgear switch to avoid problems with auto sensing.

  • .NET Framework 3.5 SP1 issue on Windows SharePoint Services v2.0

    If you apply the TFS2008 SP1 to a system that has been upgraded from TFS 2005, but the WSS was not upgraded from 2.0 to 3.0 you can get a problem that you cannot access the SharePoint portal sites due to WebPart load errors (you get an Event ID: 1000 error in the Windows event logs). This is because the TFS 2008 SP1 installs .NET framework 3.5 SP1 which causes some problems for WSS 2.0. Note this is not usually a problem for new installs of TFS 2008 as these use WSS 3.0 by default, but the upgrade of TFS from 2005 to 2008 does not force the upgrade of WSS 2.0 to 3.0 so sites that upgraded are susceptible.

    Most of the blog posts suggest a removal of .NET 3.5 and reinstall of 2.0 with service packs, this is not an option for a TFS 2008 installation. Luckily there is a solution, the .NET framework family update. Once these patches are installed for the historic versions of .NET all seems OK

    Thanks to Wes MacDonald for pointing me at this fix, saved me no end of headaches

  • Logging everything that is going on when an assembly loads using CThru

    Whist trying to work out if there is any way to get around the problem I am suffering with Sharepoint workflows idling inside a Typemock Isolator test harness I have been having a good look at CThru; a set if libraries for Typemock that, and I quote Codeplex here, ‘… allows creating interception and isolation frameworks for logging, testing and many other things very simply’. This is the framework is used to create the Silverlight mocking frame work on the same Codeplex site.

    To aid my analysis I wrote a basic Logger using the Aspect concepts of CThru, which I call as follows:

    // set the name of the types I want to monitor
    TestProject.LoggingAspect.TypeNamesToMatch.Add("SharePoint");
    // tell it where to look for aspects
    CThru.CThruEngine.AddAspectsInAssembly(System.Reflection.Assembly.GetExecutingAssembly());
    // and start it up
    CThru.CThruEngine.StartListening();

    The source is below is just included in my assembly, it allow me to chose if I want to log as text for CSV format. I am sure it will need editing for your logging needs but it gives you the basic idea….

    using System;
    using CThru;
    using System.Diagnostics;
    using System.Collections.Generic;
    using System.Text;
     
    namespace TestProject
    {
        /// <summary>
        /// A sample Aspect logger for CThru
        /// </summary>
        class LoggingAspect : Aspect
        {
            /// <summary>
            /// The current logger in use
            /// </summary>
            private static IAspectLogger logger  = new DebugTextLogger() ;
     
            /// <summary>
            /// A list of the available logging formats
            /// </summary>
            public enum LoggingMethod
            {
                TextToDebug,
                CommaSeparatedToDebug
            }
     
            /// <summary>
            /// The list of string to do partial matches against when logging
            /// If any string in this list is in the namespace or typename it gets logged
            /// If this list is empty then all types are logged
            /// </summary>
            public static List<string> TypeNamesToMatch = new List<string>();
     
            /// <summary>
            /// Sets the current logging format
            /// </summary>
            public static LoggingMethod CurrentLoggingMethod
            {
                set
                {
                    switch (value)
                    {
                        default:
                        case LoggingMethod.TextToDebug:
                            logger = new DebugTextLogger();
                            break;
                        case LoggingMethod.CommaSeparatedToDebug:
                            logger = new DebugCVSLogger();
                            break;
                    }
     
                }
     
            }
     
            public static bool LogToCSV = false;
     
            public override void StaticConstructorBehavior(DuringCallbackEventArgs e)
            {
                LogEvent("LoggingAspect.StaticConstructorBehavior", e);
            }
     
            public override void ConstructorBehavior(DuringCallbackEventArgs e)
            {
                LogEvent("LoggingAspect.ConstructorBehavior", e);
            }
     
            public override void MethodBehavior(DuringCallbackEventArgs e)
            {
                LogEvent("LoggingAspect.MethodBehavior", e);
     
                if (e.MethodName == "StsCompareStrings")
                {
                    e.MethodBehavior = MethodBehaviors.ReturnsCustomValue;
                    e.ReturnValueOrException = true;
                }
     
            }
     
            public override void MissingMethodBehavior(DuringCallbackEventArgs e)
            {
                LogEvent("LoggingAspect.MissingMethodBehavior", e);
            }
     
            private static void LogEvent(string description, DuringCallbackEventArgs e)
            {
                logger.LogEvent(description, e);
            }
     
            /// <summary>
            /// The control to see which 
            /// </summary>
            /// <param name="info">The info on the currently handled assembly</param>
            /// <returns>True if we should monitor this event</returns>
            public override bool ShouldIntercept(InterceptInfo info)
            {
                if (TypeNamesToMatch.Count > 0)
                {
                    foreach (string name in TypeNamesToMatch)
                    {
                        // find the first match of this string in a namespace typename
                        if (info.TypeName.Contains(name) == true)
                        {
                            return true;
                        }
                    }
                }
                else
                {
                    // none in the list match all
                    return true;
                }
                return false;
            }
     
            /// <summary>
            /// Helper method to format the parameters as a list in a string
            /// </summary>
            /// <param name="e">The handled event</param>
            /// <returns>A strung listing the params and their values</returns>
            public static string ParametersListToString(DuringCallbackEventArgs e)
            {
                var sb = new StringBuilder();
                if (e.ParameterValues != null)
                {
                    for (int i = 0; i < e.ParameterValues.Length; i++)
                    {
     
                        if (e.ParameterValues[i] != null)
                        {
                            sb.Append(String.Format("{0} [{1}]", e.ParameterValues[i].GetType(), e.ParameterValues[i]));
                        }
                        else
                        {
                            sb.Append("null");
                        }
                        if (i < e.ParameterValues.Length - 1)
                        {
                            sb.Append(",");
                        }
                    }
                }
                return sb.ToString();
            }
     
        
     
        }
     
        /// <summary>
        /// Logger interface 
        /// </summary>
        public interface IAspectLogger
        {
           void LogEvent(string description, DuringCallbackEventArgs e);
        }
     
        /// <summary>
        /// Logs an items as plain text
        /// </summary>
        public class DebugTextLogger : IAspectLogger
        {
            public void LogEvent(string description, DuringCallbackEventArgs e)
            {
                Debug.WriteLine(string.Format("{0}: {1}{2}.{3}({4})",
                    description,
                    e.TargetInstance == null ? "[Static] " : string.Empty,
                    e.TypeName,
                    e.MethodName,
                    LoggingAspect.ParametersListToString(e)));
            }
        }
     
        /// <summary>
        /// Logs an items as comma separated to ease analysis
        /// </summary>
        public class DebugCVSLogger : IAspectLogger
        {
            
            public DebugCVSLogger()
            {
                // write out a header so we know the colomns
                Debug.WriteLine(string.Format("{0},{1},{2},{3},{4}",
                    "Event logged",
                    "Is Static",
                    "Type name",
                    "Method name",
                    "Parameter List...."));
            }
     
            public void LogEvent(string description, DuringCallbackEventArgs e)
            {
                Debug.WriteLine(string.Format("{0},{1},{2},{3},{4}",
                    description,
                    e.TargetInstance == null ? "True" : "False",
                    e.TypeName,
                    e.MethodName,
                    LoggingAspect.ParametersListToString(e)));
            }
        }
     
     
     
    }
  • 0x800106ba Windows Defender error in Windows Vista

    I was installing a new PC for a friend yesterday; after using the Easy Transfer Wizard (first time I used this and I can heartily recommend) to move their settings from their old XP system to their new Vista one I got the 0x800106ba Windows Defender error on start-up. Now there is a lot of frankly useless comments on this error on various forums, strange as the solution is simple. I suspect this is down to this issue being predominantly a problem that hits home user who are not a familiar with the internal workings of services etc. in Windows.

    Anyway the solution is make sure the Defender service is set to auto-start. You get the error if it has not been started when Windows check to see if it is running, I assume as part of the security centre checks.

    It is not that the forums are really wrong, they usually suggest a reinstall of Defender (which will reset the service start-up), but it is just that this is not easy to achieve on Vista where Defender is backed into the operating system not as separate install as it was in Vista.

  • 29109 error when installing the quiescence GDR patch for TFS 2005

    Whilst upgrading a single server TFS 2005 to a dual server 2008 install I hit a problem. I had installed the new 2005 Data Tier (DT) and patched it without issue. However then I tried to apply the patch VS80-KB19156-v2-x86, the Quiescence GDR patch, on the Application Tier (AT) I got the 29109 error: SQL Reporting Services configuration encountered an unknown problem. A search on the web found this is a common issue usually fixed by repeated retries! This did not work for me.

    After much fiddling, I started again and cleaned down both the DT and AT. This time I made one change from the process detailed in the TFS dual server installation walkthrough – I DID NOT patch the SQL 2005 instance of Reporting Services on the AT prior to installing TFS. This time the TFS patches applied OK, I then patched SQL at the end of the installation process to bring it in line with the DT SQL patch level.

    This would suggest the problem is that the TFS 2005 patches are checking for something that was set in a default SQL 2005 install but not present in one that is patched to SP3.

    Anyway hope my experience saves you some time.

  • TFS Sharepoint Extensions on a Load Balanced Sharepoint farm

    I posted yesterday about problem creating a new team project if you had missing templates on your Sharepoint server. This problem could of course be avoided if you had installed the TFS Sharepoint Extensions onto your Sharepoint server as your are meant to. However, as I have discovered it is not that easy to do if your chosen  Sharepoint system has network load balanced front ends.

    The problem is that Sharepoint will replicate your MSFAGILE30.STP template between the various servers, but it will not move other TFS artefacts such as the TFSREDIRECT.ASPX in the 12 hive or setting to point to the reporting service instance in the registry. To add these other items you need to install the extensions an then run the TFSConfigwss.exe tool to edit the registry. The problem is the Extensions MSI will not complete if it detects the STP already in place (which as I said will that have been replicated by Sharepoint). The only solution I found was to cheat a bit:

    1. Run the Extensions MSI until you get the warning dialog it cannot complete
    2. In c:\program files copy the 'Team Foundation Server 2008 Sharepoint Extensions x64 Power Tool' directory
    3. Let the MSI finish, it will remove the directory, but you have a copy with the TFSconfigwss.exe tool which is probably the only thing you need.
    4. Run TFSConfigwss.exe to setup the registry.

    Or you could just copy the files you need from your original Sharepoint server where you managed to install the Extensions correctly

  • TF30227 error when creating team projects on TFS 2008

    Historically we have used the eScrum process template for our TFS team projects. However, with a view to the TFS 2010 future we have decided to moved back to the MSF Agile template. We used eScrum to provide an easy to use web based project dashboard; we now think that we can achieve the same or better in TFS 2010 using Excel’s enhanced links to TFS and Excel Services in Sharepoint.

    So when I had to create a new team project today I decided to use the TFS 2008 "MSF for Agile Software Development - v4.2" template, to hopefully ease any upgrade issues. The problem was when I tried to create the team project I got the error TF30227, if I looked in the detailed log I saw:

    Event Description: TF30162: Task "SharePointPortal" from Group "Portal" failed
    Exception Type: Microsoft.TeamFoundation.Client.PcwException
    Exception Message: TF30272: Template not found on the server

    (Note that as is common with TFS the main error reported hides another error code.)

    The problem was exactly as the error says, the template was missing on our central Sharepoint farm. We have been through a number of Sharepoint upgrades and relocation of our portal sites. This had meant that the TFS templates had to be reinstalled manually, this was done correctly for the eScrum template but a mistake was made for the MSF Agile one. We had installed the template with the command

    Stsadm -o addtemplate -filename MSFAgile30.stp -title VSTS_MSFAgile30

    when it should have been

    Stsadm -o addtemplate -filename MSFAgile30.stp -title VSTS_MSFAgile

    as TFS looks for a template call VSTS_MSFAgile not one called VSTS_MSFAgile30. Once this was correct the new project could be created.

  • Addressing binding issues with with Ivonna 2.0.0 using <dependentAssembly> in web.config

    I have been having some binding problems when trying to use Ivonna 2.0.0 against a version of Typemock Isolator other than the 5.3.0 build it was built to run against. This is a know issue, if your version of Ivonna and Typemock don’t match then you have to use .Net Binding redirection to get around the problem.

    So to track down the exact problem I used the Fusion logger shipped with the .NET SDK (via fuslogvw.exe). This in itself has been an interesting experience. A few points are worth noting:

    • You cannot alter the settings (as to what it logs) from fuslogvw.exe unless you are running as administrator (because these a really just registry edits in HKLM\SOFTWARE\Microsoft\Fusion node). However you can use the viewer to view logs even if not an administrator as long as the registry entries are correct.
    • I could only get the Fusion log to work if I was running my ASP.NET application in Visual Studio 2008 running as administrator, if I was a standard user nothing was logged.
    • You have to remember to press refresh on fuslogvw.exe a lot. If you don’t you keep thinking that it is not working when it really is.

    Anyway using the fusion logger I found I had two problem assemblies, not just the one I had expected. I had guessed I need to intercept the loading of the main Typemock assembly, but what the fusion logger showed me was I also needed to intercept the Typemock.Intergration assembly. Also I needed to reference the Typemock.Intergration assembly in my test project and make sure it was copied locally (something I had not needed to explicitly do when using Typemock 5.3.0 where it had found via I assume via the GAC)

    Now it is important to remember that if using MSTEST and Ivonna you need to point the build directory for the Test Project to Web Application under test’s bin directory. This means that the .NET loader will check the web.config in the web application for any binding information, not just in the app.config in the test project as I had first assumed.

    So all this means that I needed to add the following to my Web Application’s web.config and app.config

    <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
    <assemblyIdentity name="TypeMock.Integration"
    publicKeyToken="3dae460033b8d8e2"
    culture="neutral" />
    <bindingRedirect oldVersion="5.3.0.0"
    newVersion="5.3.1.0"/>
    </dependentAssembly>
    <dependentAssembly>
    <assemblyIdentity name="TypeMock"
    publicKeyToken="3dae460033b8d8e2"
    culture="neutral" />
    <bindingRedirect oldVersion="5.3.0.0"
    newVersion="5.3.1.0"/>
    </dependentAssembly>

    </assemblyBinding>
    </runtime>

    Once this was done all my test loaded as expected

    Updated 4th June 2009 – There is now 2.0.1 release of Ivonna that does support Isolator 5.3.1 so this binding is not required, but details are good as in the future there is bound to be another version mismatch

  • The setup story for TFS 2010

    I have been looking at the various install and upgrade stories for the TFS 2010 Beta. I have to say they are very nice compared to the older TFS versions. You now have a SharePoint like model where you install the product then use a separate configuration tool to upgrade or setup the features required. There are plenty of places to verify your setting as you go along to greatly reducing the potential mistakes.

    One side effect of this model is that it is vital to get all your prerequisites in place. The lack of these has been the cause of the only upgrade scenario I have tried that has failed. This was on a VPC I used for TFS 2008 demos. This VPC used a differencing VHD using the older 2004 format that had a 16Gb limit and this disk was virtual full. To upgrade to TFS 2010 I needed to upgrade SQL to 2008 and this in turn needed Visual Studio 2008 patched to SP1 which needed over 6Gb free space, which was never going to happen on that VHD. So my upgrade failed, but that said this is not a realistic scenario, who has servers with just 16Gb these days!

    Posted May 27 2009, 09:09 PM by Richard with no comments
    Filed under: ,
  • Everytime I have to use Typemock I need to ask does my code stinks?

    Ok a bit sweeping but I think there is truth in this, if you have to resort to a mocking framework (such as Typemock the one I use) I think it is vital to ask ‘why am I using this tool?’ I think there are three possible answers:

    1. I have to mock some back box that is huge and messy that if I don’t mock it will mean any isolated testing is impossible e.g. SharePoint
    2. I have to mock a complex object, I could write it all by hand, but it is quicker to use an auto-mocking framework. Why do loads of typing when a tool can generate it for me? (the same argument as to why using Refactoring tools are good, they are faster than me typing and make less mistakes)
    3. My own code is badly designed and the only way to test it is to use a mocking framework to swap out functional units via ‘magic’ at runtime.

    If the bit of code I am testing fails into either of the first two categories it is OK, but if it is in third I know must seriously consider some refactoring. Ok this is not always possible for technical or budgetary reasons, but I should at least consider it. Actually you could consider category 1 as a special case of category 3, a better testable design may be possible, but it is out of your control.

    So given this I looked at the new Typemock feature with interest, the ability to fake out DateTime.Now. Something you have not been able to do in the past due to the DataTime classes deep location in the .NET framework. OK it is a really cool feature, but that is certainly not a good enough reason to use it. I have to ask if I need to mock this call out does my code stink?

    Historically I would have defined an interface for a date services and used it to pass in a test or production implementation using dependency injection e.g.

    public class MyApplication 
    {
    public MyApplication(IDateProvider dateProvider)
    {
    // so we use
    DateTime date1 = dateProvider.GetCurrentDate();
    // as opposed to
    DateTime date2 = DateTime.Now
    }
    }

    So in the new world with the new Typemock feature I have three options:

    1. Just call DateTime.Now in my code, because now I know I can use Typemock to intercept the call and return the value I want for test purposes
    2. Write my own date provider and use dependency injection to swap in different versions (or if I want to be really flexible use a IoC framework like Castle Windsor)
    3. Write my own date provider class with a static GetDate method, but not use dependency injection, just call the method directory wherever I would have called DateTime.Now and use Typemock to intercept calls to this static method in tests (the old way to get round the limitation that Typemock cannot mock classes from MSCORELIB

    I think this bring me back full circle to my first question: does the fact I use the new feature of Typemock to mock out DateTime.Now mean my code stinks? Well after bit of thought I think it does. I would always favour putting in some design patterns to aid testing, so in this case some dependency injection would appear the best option. Like all services it would allow me to centralise all date functions in one place, so a good SOA pattern. With all my date service in one place I can make a sensible choice of how I want to mock it out, manual or via an auto mocking framework.

    So in summary, in mocking, like in so many things in life, just because you can do it is no reason why you should do something in a polite society. If you can, it is better to address a code smell with good design as opposed to a clever tool.

  • Post Developer Day South West thoughts

    DD-SW in Taunton seems to go well, a big thank you to Guy and the rest of the Bristol .NET user group for all their work getting this event up and running. Also it was nice to see new faces, it is certainly a good idea to get the DDD family events out to places beyond Reading, spreading the good works of the community across the country.

    Thank you to those who attended my session on Scrum, I hope you all found it useful. You can find a virtually identical set the slides on the Black Marble web site and the actual stack I used will be up on the DD-SW site soon.

    I actually managed to attend some sessions this time, as usual this just means more work as I invariably realise I have to spend some time on learning some new technologies This time it was MEF and jQuery, the latter  technology I have ignored too long. It was also great to see a truly mind bending session by Marc Gravell on Expression trees, we need to see more of these deep dive sessions a community events. I have never checked to see if is it that they are not proposed or that they are not voted for? Can it be true the community just wants level 200 general overviews?

    Anyway another great day – a pointer to everyone that if you haven’t been to DDD event you really should.

  • Developer Day South West is this weekend

    It is Developer Day South West this weekend where I will be speaking on Scrum. I may also do a lunch time grok talk on SharePoint and Typemock Isolator as I did at Developer Day Scotland.

    I think there are still spaces at this event, so if you can make your way down to Taunton on Saturday I think it will be well worth the trip.

    DDD South West

More Posts Next page »
Black Marble 2004-2009
Powered by Community Server (Commercial Edition), by Telligent Systems