Archive for the “.NET” Category

I have been working alot lately with Virtual Lab and automatic builds and deployment and today I learned something new
1. xcopy32 does not work on network shares (unless they are mapped to a drive)
2. robocopy messes up deploys because it can return an errorcode different from 0 even if it is just to tell you that he succeeded.

Now robocopy is replacing xcopy in my book and to make robocopy play nice, I add ^& exit 0 at the end. Like this:


robocopy \\networkdrive destpath *.* ^& exit 0

Comments No Comments »

When running SQL Server Management Studio 2008 on a Win7 64bit machine you might stumble upon poor, very poor performance. Clicking on a table results in waiting for 10-20 seconds before being able to do anything, doing a select would again take an eternity. The reason is unknown to me (sorry, I don’t feel like reading tons of articles and kb notes).

Still I got it fixed. Just two steps:
- set the management studio to run in XP SP3 compatibility mode
- if you have the UAC turned off, turn it on on the first level (raise the level from the bottom one notch)

Now it’s working like a charm.

Comments No Comments »

On the “to be deployed” machine install: Lab Agent, Test Agent, Build Agent
When creating the template on which the “to be deployed” machine will be based, make sure it is not set with a virtual network
Install virtual guest services on the virtual machine before converting it to a template
On the test controller set the dns append suffix to the domain where the test agents reside (they try to default to the name and not to the FDQN). Do the same on the test agent to be able to resolve the testcontroller
Set the test agent to run as a service and using an administrator account.

Comments No Comments »

Nice and usefull one:
1. Open Command prompt
2. Go to Program Files (x86)\Microsoft visual Studio 10.0\Common7\IDE (or in 9.0 if you are using VS2008)
3. run witadmin.exe destroywi /collection:http://[tfsurl]:8080/[collection] /id:workitemid

where workitemid is the id given to the workitem by TFS

You can also see the documentation here

Comments No Comments »

Ok, for anyone that knows me the title sounds strange, but it should not. The reason is there so bear with me.

I thought alot on this. I am in holiday and the news intrigued me to say the least.
There has been alot of discussion and debate on the reason, starting from patent needs (motorola has 17000 patents and counting) to support infrastructure and enterprise targetting. I am more interested in the outcome. With this move we are witnessing a stalemate on the three side war. We have Microsoft Nokia, Apple and now Google Motorola. Of the three, only Apple is low on patents compared to the others, but they have alot of new ones and also important ones, and their powerfull market possition. This leads as I said to a stalemate with each side not in a power possition. What is going to happen next?
Well, all of them want market share and the only way to achieve that is through technological breakthroughs and services! As I said: rejoice. Good times are coming for smartphone users.

What I see: Mikrokia will deliver, Googrola will finally bring order in the chaos that is android and Apple will begin to listen and diminish the Jobs tax

Comments No Comments »

Simply put: “it does not work out of the box”. Building the MVC website on the development desktop is ok. When checking the code and building using the TFS it crashes:

[Any CPU/Release] /temp/global.asax(1,0): error ASPPARSE: Could not
load type 'TestMVCApp.MvcApplication'.

The reason is simple but not easy to find out. It seems the AspNetCompiler expects the dll’s to be found in the Bin directory and TFS puts the output in a different folder. Thus the AfterCompile step fails. To fix this we need to change (using notepad) the csproj of the web project.

Original:

<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
  <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
</Target>

Fixed version:

<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
  <AspNetCompiler Condition="'$(IsDesktopBuild)' != 'false'"
     VirtualPath="temp"
     PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
  <AspNetCompiler Condition="'$(IsDesktopBuild)' == 'false'"
     VirtualPath="temp"
     PhysicalPath="$(PublishDir)\_PublishedWebsites\$(ProjectName)" />
</Target>

Hopefully MS will fix this in the future.

Comments No Comments »

Well I was expecting this beta and then some. Unfortunately I am disappointed. After the fine beta that was Win7 this feels rushed.

Here are my “bad” points:
- address bar is skewed, again. I simply cannot choose from the last lets say 20 url’s entered and there is no way to do this. Think about::config in firefox
- the page tabs are squeezed on the right of the address bar. Excuse me! Where do I fit my usual 10 tabs. Group them? No, I don’t want that.
- page loading is simply unintuitive. I have no feedback on the status and from 10 pages at least 2 fail to load. No error message just a blank page

The good points (yes there are some):
- the interface is nice, feels more aero-like
- the perceived performance (once you actually get to see something) is good

I was planning to switch to IE9 from Firefox (the damned resource hog) but it is not there yet. Waiting for beta 2.

Comments No Comments »

A long time ago I was looking on how to process pdb files in order to get additional information that reflection simply could not provide.
Now I stumped over a 5 year old post of Mike Stall (here) and suddenly all became clear. I’ve put together a small example which uses .net 4.0 to read the method body code as it is in the source code from where the assembly was compiled. Mind you that in order for this to work you have to have the pdb of the assembly available. Also please make sure you add a refference to ISymWrapper and your project is targeting .Net 4.0 framework, not .Net 4.0 Client.

using System;
using System.Diagnostics.SymbolStore;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;

namespace PdbTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly ass = Assembly.GetExecutingAssembly();
            ISymbolReader symreader = SymUtil.GetSymbolReaderForFile(ass.Location, null);

            MethodInfo m = ass.GetType("PdbTest.TestClass").GetMethod("GetStringRepresentation");
            ISymbolMethod met = symreader.GetMethod(new SymbolToken(m.MetadataToken));

            int count = met.SequencePointCount;

            ISymbolDocument[] docs = new ISymbolDocument[count];
            int[] offsets = new int[count];
            int[] lines = new int[count];
            int[] columns = new int[count];
            int[] endlines = new int[count];
            int[] endcolumns = new int[count];

            met.GetSequencePoints(offsets, docs, lines, columns, endlines, endcolumns);

            StreamReader reader = new StreamReader(docs[0].URL);
            string[] linesOfCode = reader.ReadToEnd().Split('\n');
            reader.Close();

            Console.WriteLine("The content of method PdbTest.TestClass.GetStringRepresentation");
            for (int i = lines[0]; i < endlines[count - 1] - 1; i++)
            {
                Console.WriteLine(linesOfCode[i]);
            }
        }
    }

    #region test class

    public enum MyEnum
    {
        Apples,
        Oranges
    }

    public partial class TestClass
    {
        public string GetStringRepresentation(MyEnum e)
        {
            MyEnum e2 = MyEnum.Apples;
            return e.ToString() + e2.ToString();
        }
    }

    #endregion test class

    #region Get a symbol reader for the given module

    // Encapsulate a set of helper classes to get a symbol reader from a file.
    // The symbol interfaces require an unmanaged metadata interface.
    static class SymUtil
    {
        static class NativeMethods
        {
            [DllImport("ole32.dll")]
            public static extern int CoCreateInstance(
                [In] ref Guid rclsid,
                [In, MarshalAs(UnmanagedType.IUnknown)] Object pUnkOuter,
                [In] uint dwClsContext,
                [In] ref Guid riid,
                [Out, MarshalAs(UnmanagedType.Interface)] out Object ppv);
        }

        // Wrapper.
        public static ISymbolReader GetSymbolReaderForFile(string pathModule, string searchPath)
        {
            return SymUtil.GetSymbolReaderForFile(
                new System.Diagnostics.SymbolStore.SymBinder(), pathModule, searchPath);
        }

        // We demand Unmanaged code permissions because we're reading from the file 
        // system and calling out to the Symbol Reader
        // @TODO - make this more specific.
        [System.Security.Permissions.SecurityPermission(
            System.Security.Permissions.SecurityAction.Demand,
            Flags = System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
        public static ISymbolReader GetSymbolReaderForFile(
           System.Diagnostics.SymbolStore.SymBinder binder, string pathModule, string searchPath)
        {
            // Guids for imported metadata interfaces.
            Guid dispenserClassID = new Guid(0xe5cb7a31, 0x7512, 0x11d2, 0x89,
                0xce, 0x00, 0x80, 0xc7, 0x92, 0xe5, 0xd8); // CLSID_CorMetaDataDispenser
            Guid dispenserIID = new Guid(0x809c652e, 0x7396, 0x11d2, 0x97, 0x71,
                0x00, 0xa0, 0xc9, 0xb4, 0xd5, 0x0c); // IID_IMetaDataDispenser
            Guid importerIID = new Guid(0x7dac8207, 0xd3ae, 0x4c75, 0x9b, 0x67,
                0x92, 0x80, 0x1a, 0x49, 0x7d, 0x44); // IID_IMetaDataImport

            // First create the Metadata dispenser.
            object objDispenser;
            NativeMethods.CoCreateInstance(ref dispenserClassID, null, 1,
                ref dispenserIID, out objDispenser);

            // Now open an Importer on the given filename. We'll end up passing this importer 
            // straight through to the Binder.
            object objImporter;
            IMetaDataDispenser dispenser = (IMetaDataDispenser)objDispenser;
            dispenser.OpenScope(pathModule, 0, ref importerIID, out objImporter);

            IntPtr importerPtr = IntPtr.Zero;
            ISymbolReader reader;
            try
            {
                // This will manually AddRef the underlying object, so we need to 
                // be very careful to Release it.
                importerPtr = Marshal.GetComInterfaceForObject(objImporter,
                    typeof(IMetadataImport));

                reader = binder.GetReader(importerPtr, pathModule, searchPath);
            }
            finally
            {
                if (importerPtr != IntPtr.Zero)
                {
                    Marshal.Release(importerPtr);
                }
            }
            return reader;
        }
    }
    #region Metadata Imports

    // We can use reflection-only load context to use reflection to query for 
    // metadata information rather
    // than painfully import the com-classic metadata interfaces.
    [Guid("809c652e-7396-11d2-9771-00a0c9b4d50c"),
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [ComVisible(true)]
    interface IMetaDataDispenser
    {
        // We need to be able to call OpenScope, which is the 2nd vtable slot.
        // Thus we need this one placeholder here to occupy the first slot..
        void DefineScope_Placeholder();

        //STDMETHOD(OpenScope)(                   // Return code.
        //LPCWSTR     szScope,                // [in] The scope to open.
        //  DWORD       dwOpenFlags,            // [in] Open mode flags.
        //  REFIID      riid,                   // [in] The interface desired.
        //  IUnknown    **ppIUnk) PURE;         // [out] Return interface on success.
        void OpenScope([In, MarshalAs(UnmanagedType.LPWStr)] String szScope,
            [In] Int32 dwOpenFlags, [In] ref Guid riid,
            [Out, MarshalAs(UnmanagedType.IUnknown)] out Object punk);

        // Don't need any other methods.
    }

    // Since we're just blindly passing this interface through managed code to the Symbinder, 
    // we don't care about actually importing the specific methods.
    // This needs to be public so that we can call Marshal.GetComInterfaceForObject() on 
    // it to get the underlying metadata pointer.
    [Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44"),
        InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [ComVisible(true)]
    [CLSCompliant(true)]
    public interface IMetadataImport
    {
        // Just need a single placeholder method so that it doesn't complain
        // about an empty interface.
        void Placeholder();
    }
    #endregion

    #endregion Get a symbol reader for the given module
}

Thanks Mike.

Comments 2 Comments »

I have to write this down for me and others. It’s a headache each time I do it and I imagine for others as well. The problem at hand is how to make a build definition for a solution (or a new build definition for a solution already having a build definition) which is build on a build machine hosting multiple build agents (scenario not endorsed by Microsoft).

Here are the steps:

  1. If you don’t know what you are doing ask someone who does and go to step 10. If you don’t have someone to ask you can still proceed but at your own risk.
  2. Log on onto the build machine as an administrator (just to avoid pesky security checks)
  3. Go to c:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies – this may vary due to the OS being 32 or 64 and if you’re using TFS2008 (you go to vs 9.0 directory) or if you’re using TFS2010 (you go to vs 10.0 directory)
  4. Copy TFSBuildService.exe as TFSBuildService2.exe (just make sure you have different executables for each build agent, I use numbers added to the name of the file)
  5. Copy TFSBuildService.exe.config as TFSBuildService2.exe.config (same logic as above)
  6. Edit TFSBuildService2.exe.config:
    • such that the “port” and “InteractivePort” have values not yet used. For the second agent these would be 9193 and 9194 which I will be using later in the process.
    • Here you can also fool the build agent to use whatever version of MSBuild you want by modifying MSBuildPath. For example I use the MSBuild of .Net 4.0 on a TFS2008.
    • Modify “SourcesSubdirectory” to “Sources\projectname” where projectname is an arbitrary value, just make sure it’s different for all build agents
    • Modify “BinariesSubdirectory” to “Binaries\projectname” – same logic as above
    • Modify “TestResultsSubdirectory” to “TestResults\projectname” – same logic as above
  7. Create a service for the build agent. Open a visual studio command prompt (will save you to write fullpath to sc.exe) and run the command: sc create VSTFBUILD2 binpath= “C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\TFSBuildService2.exe” displayname= “Visual Studio Team Foundation Build – projectName” start= auto. Observations:
    • the name of the service VSTFBUILD2 should differ from all other build agent services and thus I added the 2 suffix
    • the TFSBuildService2.exe should be the one you created at step 4
    • the display name is not very important but helps in identifying the service in the service manager window
  8. Go to service manager window (start\control panel\administrative tools\services), find your newly created service, go to properties, the log-on tab and modify there to make the service to log on as the TFSService (default account for the TFS). Make sure you’re using also the domain there if you are in a domain.
  9. Start the service
  10. Create a folder where the build results will be added. Something like “c:\b\pname”. Be carefull to choose as shorter names as possible to not hit the 240 char limit of TFS when getting all the source code. Share this folder with the people that need to access build results and make sure TFSService has full rights on it
  11. Log on to the TFS machine
  12. Start visual studio (must have team explorer installed).
  13. Use team explorer to navigate to your sollution and right click on the Builds and select Manage Build Agents. If you don’t see the option you may not have rights – get them.
  14. Click New. Choose a display name. I choose buildmachine_2. In the computer name add buildmachine and the communication port you set at step; in this case 9193. Set the agent status to Enabled and finish.
  15. Log on to your development machine. Use team explorer and go to the builds folder of your sollution.
  16. Right click builds and choose New build definition.
    • Put a build definition name there,
    • select the trigger,
    • select the workspace (what needs to be retrieved by the source control) and put in the build agent folder the folder created at step 10.
    • In the Build defaults select in the build controller dropdown buildmachine_2 (if it is not yet visible there restart visual studio and try again). Also put into the build output folder textbox the UNC path to the share created as step 10.
    • In the project file put the source control path to the TFSBuild.proj if you have it already, if not you should be able to create it from this tab
    • done here. After saving this you should see your build definition in the builds folder in team explorer.
  17. In the TFSBuild.proj file (seen at last step of step 16) modify:
    • BuildMachine – buildmachine_2 – this is just to make sure because it should be ignored normally
    • BuildDirectoryPath – put the full name of the directory created at step 10 (not the UNC path! but the path as seen when logged-on on the build machine, like “c:\b\pname”)
  18. Done. You should be able to queue a new build.
  19. Have fun.

Comments No Comments »

The question: if you use a linq query over a list of elements and you want to select only the first element, using the First extension, does the processing continue after hitting a match? Why is this important? it’s because the query might be very heavy and you don’t really need to process all elements, only if an element matches your query.

Here is the test:

    class Program
    {
        static void Main(string[] args)
        {
            List<Element> lst = new List<Element>();
            lst.Add(new Element("1"));
            lst.Add(new Element("2"));
            lst.Add(new Element("3"));
            lst.Add(new Element("4"));
            lst.Add(new Element("5"));

            var res = (from e in lst
                       select e.Name).First();
            Console.ReadKey();
        }
    }

    class Element
    {
        private string m_name;
        public string Name
        {
            get { Console.WriteLine(m_name); return m_name; }
        }
        public Element(string name) { this.m_name = name; }
    }

And the answer: Linq will stop after the first element corresponding to your query is found.

Comments No Comments »