August 2007


One of the items that I had been struggling with was the ability to create a new project that did some pretty specific items when it was “unfolded” as they say in the GAT world.  I wanted to use a custom recipe instead of a template link.  After researching around a little with one of my favorite tools reflector, I wrote out some basic code for an action that creates a project.  Please use as you see fit.

 

public class CreateNewProject: Action

    {

        private const string PATH_SEPARATOR = @”\”;

 

        private string _ProjectName;

        [Input]

        public string ProjectName

        {

            get { return _ProjectName; }

            set

            {

                _ProjectName = value;

            }

        }

 

        private string _ProjectNamespace;

        [Input]

        public string ProjectNamespace

        {

            get

            {

                return _ProjectNamespace;

            }

            set

            {

                _ProjectNamespace = value;

            }

        }

 

        private Project _VSProject;

        [Output]

        public Project VSProject

        {

            get { return _VSProject; }

            set { _VSProject = value; }

        }

 

        private string _Template;

 

        public string Template

        {

            get { return _Template; }

            set

            {

                _Template = value;

            }

        }

 

        private string GetTemplateDirectory()

        {

            string tempString = ReflectionHelper.GetAssemblyPath(Assembly.GetExecutingAssembly());

            return tempString.Substring(0,tempString.LastIndexOf(PATH_SEPARATOR)) + PATH_SEPARATOR + @”Templates” ;

        }

        public override void Execute()

        {

            Template = @”Projects\BaseProject\Project.vstemplate”;

            string templateFile = GetTemplateDirectory() + PATH_SEPARATOR + Template;

            string destination = GetSolutionDirectory() + PATH_SEPARATOR + @”\src” ;

 

                base.GetService<DTE>(true).Solution.AddFromTemplate(templateFile, destination, ProjectNamespace + “.” + ProjectName, false);

 

        }

 

        private string GetSolutionDirectory()

        {

            string temporaryPath = (string)base.GetService<DTE>(true).Solution.Properties.Item(“Path”).Value;

            temporaryPath = temporaryPath.Substring(0, temporaryPath.LastIndexOf(PATH_SEPARATOR));

            return temporaryPath;           

        }

 

 

Items in the code to note:

  1. When a GAT package is deployed, it contains a dll and the Templates directory folder relative to the dll.  This way I can use the ReflectionHelper class, located inside the RecipeFramework to get the assembly path for the current assembly.
  2. Notice also that I have hard coded the Template property in the execute method.  This was just for testing purposes.  will change to become an input to the action.

 

If anyone wants the full source of this with tests and comments, let me know.

 

 I recently downloaded a .chm file for Domain-Specific Language tools (here). After downloading and opening it, I got this wonder view of the chm.  I mean on every page.  At first, I thought that the help file was corrupt.

image

Then my better sense got to me.  There had to be a security issue with html based help files.  Sure enough.  Look at the properties for the chm file.

image

Down at the bottom, there is a setting to unblock the file.  Click it and you are good to go.

image

 

Technorati Tags: ,

I have come across several issues with using the GAT.  One of them is when I go to add some new artifact (a new project, solution, T4 template) without first unregistering the package.  I can just go and register the guidance package, however, sometimes, it gets corrupted.  If that happens, see my post on Uninstalling a GAT Package Manually.  What makes this interesting, is that the xml of solutions and projects looks to be inspected during the unregister process for references.

To get an error unregistering, do the following.

  1. Register the GAT
  2. Add a new project template (.vstemplate) below the projects folder
  3. Create a TemplateReference in your base solution to a new project
  4. Try to unregister the GAT
  5. Register the GAT again. Then unregister, it should work.

 

This little quirk has bothered me for some time because of the way I was creating new items for the GAT.  Just thought I would pass the information along.

 

I am developing a Guidance Package to better formulate some development methodologies.  I believe one of the ways to do this is to give developers a cookie cutter approach to some redundant tasks.  One of these is to create a basic solution to work from.  For this post, my end goal is to create a blank solution with some solution folders attached to it.

 

To Begin

  1. Create a new guidance package from visual studio.  I am assuming that the GAT and GAX have been installed. 
    • Modify the XML configuration file by removing all of the recipes. The end result should look something like this:

       image

    • Clean out all content (Besides the XML configuration file) from the Package, but leave the directory structure in place.  This has a direct affect on the build process.
    • Build the Solution.  You should have a clean build at this point
  2. Create a new Solution vstemplate file underneath the templates\solutions folder.  Below is the text for the file.
    <VSTemplate Version=”2.0.0″ Type=”ProjectGroup” xmlns=”http://schemas.microsoft.com/developer/vstemplate/2005″>
      <TemplateData>
        <Name>Basic Solution Template</Name>
        <Description>Creates a Basic Solution with attached recipes</Description>
        <SortOrder>91</SortOrder>
        <Icon>YourIconHere.ico</Icon>
        <ProjectType>CSharp</ProjectType>
        <DefaultName>PlaceDefaultSolutionNameHere</DefaultName>
        <ProvideDefaultName>true</ProvideDefaultName>
      </TemplateData>
      <TemplateContent>
        <ProjectCollection>
          <SolutionFolder Name=”src”> 
          </SolutionFolder>
        </ProjectCollection>
      </TemplateContent>
      <WizardExtension>
        <Assembly>Microsoft.Practices.RecipeFramework.VisualStudio, Version=1.0.51206.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
        <FullClassName>Microsoft.Practices.RecipeFramework.VisualStudio.Templates.UnfoldTemplate</FullClassName>
      </WizardExtension>
      <WizardData>
        <Template xmlns=”http://schemas.microsoft.com/pag/gax-template” SchemaVersion=”1.0″ Recipe=”NewSolution”>
        </Template>
       </WizardData>
    </VSTemplate>

    Replace the following items in this template data with your own content.

    • Icon – Provide an Icon in the same folder structure where your solution template file is.  This is what will show up in Visual Studio.
    • DefaultName – This is the default name for the solution when the user creates a new solution.
    • Notice the SolutionFolder named src.  Create your own solution directory tree here.  For the purposes of this example, I am adding a src folder so that I can add recipes against it.Save the file

      Other items of note:  A normal solution template does not include the WizardExtension node.  This is what tells the GAX to execute recipes.  We currently have this solution tied to the NewSolution recipe.  Lets save the file and add the recipe to the XML configuration.

  3. Open up the XML configuration file and add the following contents in the GuidancePackage Node:
  4. <Recipes>
      <Recipe Name=”NewSolution”>
        <Caption>Build a new Solution</Caption>
      </Recipe>
    </Recipes>

  5. Save the file and rebuild the solution.  Ensure that the solution fully builds, if not you could have corruption issues.
  6. At this point we are ready to register the package. Right-Click on the class library project and select Register Guidance Package.  Once the Guidance Package is registered successfully, open another instance of Visual Studio. You should now see your own package.

You have now completed creating a basic Guidance Package with a custom solution.  Further post will show how to add custom recipes to specific solution folders.

Technorati Tags: , ,

I was working on creating a GAT Package.  Somewhere in the process unregister recipe failed to work.   What a pain it was to figure out all the places that the GAT package resides.  Fortunately there was a post by Tom Hollander and in the comments there are a series of steps to take to manually unregister the  GAT and any other GAT item.

I have put this into a PowerShell script for future use.  There is still a step that I haven’t automated yet:

  1. Edit the RecipeFramework.xml document to remove any <GuidancePackage> and save the file.  The file is normally located at c:\Documents and Settings\All Users\Application Data\Microsoft\Recipe Framework\RecipeFramework.xml

  2. Run the following script

 

##########################
# Use at your own risk.  This modifies the registry
#
# You will need the following information from the configuration file for the GAT
# under the GuidancePackage node:
#
# Guid – Set the guid variable to the guid attribute
# Name – Set the packageName variable to the Name attribute
#
# One of the things that I did was wild carded the packageName and the guid.  That way no errors will occur when looking for an exact match.
# Some registry keys may not be populated depending on the state of the GAT.
#################################

$guid = “{f0f92643-a3dd-4f51-a4b0-7c76b3f92207}”
$packageName = “Foo.Bar*”

#Placed the following key value in a temporary variable – Was getting a bad numeric constant error (bug in powershell)
$registryKey = “{77d93a80-73fc-40f8-87db-acd3482964b2}”

remove-item HKLM:\SOFTWARE\Microsoft\VisualStudio\8.0\Packages\$registryKey\Templates\$guid -recurse
remove-item HKLM:\SOFTWARE\Microsoft\VisualStudio\8.0\NewProjectTemplates\PseudoFolders\$guid -recurse
remove-item HKLM:\SOFTWARE\Microsoft\VisualStudio\8.0\NewProjectTemplates\TemplateDirs\$guid -recurse
remove-item HKLM:\SOFTWARE\Microsoft\VisualStudio\8.0\Packages\$guid -recurse
remove-item HKLM:\SOFTWARE\Microsoft\VisualStudio\8.0\Projects\$guid -recurse

remove-itemproperty -path HKLM:\SOFTWARE\Microsoft\VisualStudio\8.0\Languages\CodeExpansions\CSharp\Paths -Name $packageName
remove-itemproperty HKLM:\SOFTWARE\Microsoft\VisualStudio\8.0\Menus -Name $packageName

 

A couple of notes:

The whole $registryKey value thing kicked my butt.  This is a constant value in the registry and shouldn’t change, but don’t quote me.

Any improvements, let me know.

 

Technorati Tags: , , ,

Here is a couple of lines to that can be used to clear out the MRU list in Visual Studio.  I create many demo projects and prototypes that I like from time to time to clear the list.  In researching how to do this it has given me some more ideas in automation to clean my system.  The way that PowerShell uses the registry is pretty cool.  It basically treats it like a folder structure.

 

Code:

cd HKCU:\Software\Microsoft\VisualStudio\8.0\ProjectMRUList
remove-itemproperty . -Name “File*”

 

The key to this is to browser to the registry directory, then remove any entry that starts with File (note the wildcard).  Visual Studio stores each item in the MRU List as a separate entry.

 

Technorati Tags: , , ,

I am just starting to explore PowerShell more.  I wanted to be able to edit my $profile, but kept getting an error (The system cannot find the path specified).

image

 

In order to find out where your default profile should live bring up a PowerShell window and type $profile, this will give you the path where PowerShell expects your default profile to be.

In order to edit your profile, just type in notepad $profile

 

Technorati Tags: ,

Yesterday, I ran across a great webcast by Michele Leroux Bustamante about a year ago on Globalization and Localization.  One of the items that I never ran across was the Localize Web Server Control.  This will really come in handy as work with the business on templating content for the site.  Michele also has an excellent white paper on extending the Resource Provider

 

Check these resources out on localization.  Good Stuff!!!

http://msdn2.microsoft.com/en-us/library/ms379546(VS.80).aspx

http://www.asp.net/learn/videos/video-40.aspx

http://msdn2.microsoft.com/en-us/library/aa905797.aspx

 

 

One of the tasks that I am currently doing is providing some recommendations on implementing Continuous Integration.  CI covers many areas in the software development world, and frankly, it is more a cultural change than anything else.  The best processes can be stated but if they are not followed, CI will not be as effective as it possibly could.

Here are some main areas that I am focusing on in no particular order:

Defining Continuous integration

Of course, this is the first step right?  Each company will have a different definition of CI, however, I believe there are some best practices out there.  Check out Martin Fowler’s article on Continuous Integration

Consistency in solutions and projects

 CodePlex has a great tutorial and project on this subject by building a “developer tree”. CodePlex – Tree Surgeon project.  Also, I am looking at ways to implement recipes using the Guidance Automation Toolkit (GAT) to simplify the developers life.

Source Code Control

Managing Source Code is a task that is not for the faint at heart. I believe Eric Sink, who IMHO is a leader in SCC gives an excellent tutorial on his blog .

Tools

Of course understanding MSBuild, NAnt, CruiseControl, TeamBuild, and others are invaluable resources.  One tool I particularly like is a tool from Jay Flowers,  

CI Factory.  His ideas on continuous integration are absolutely wonderful.

 

 

I was trying to resolve a reference in a project that could not be found.  Microsoft.Web.Services.  I went to get the latest and greatest WSE from Microsoft and download it.  After I installed it, I still had the reference problem.  It ended up being a reference to WSE 1.0.  After getting the WSE 1.0 install, no problem.

This is a perfect example, IMHO, of not thinking about usability.  Should the WSE 2.0 download have included the 1.0 bits?  Your thoughts?

 

Technorati Tags: ,

Next Page »