Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) in VS Extensibility walkthrough

Marty picture Marty · May 30, 2014 · Viewed 12.9k times · Source

I am using the Walkthrough: Part 1 - Creating a Basic Project System exactly as written from the website http://msdn.microsoft.com/en-us/library/cc512961.aspx and the Managed Package Framework for Projects exactly as downloaded from http://mpfproj11.codeplex.com/. I have tested the walkthrough on multiple development machines in Visual Studio 2013. I also tested this in Visual Studio 2010 and 2012 using their respective SDK’s. The same issues to follow presented themselves in each of the tests.

Issue: I am receiving the exception- An exception of type 'System.FormatException' occurred in mscorlib.dll but was not handled in user code Additional information: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) in the ProjectNode class method:

private void SetProjectGuidFromProjectFile()
        {
            string projectGuid = this.GetProjectProperty(ProjectFileConstants.ProjectGuid);
            if (String.IsNullOrEmpty(projectGuid))
            {
                this.projectIdGuid = Guid.NewGuid();
            }
            else
            {
                Guid guid = new Guid(projectGuid);
                if (guid != this.projectIdGuid)
                {
                    this.projectIdGuid = guid;
                }
            }
        }

On the line Guid guid = new Guid(projectGuid);

projectGuid is returning the string “$guid1$” which is from <ProjectGuid>$guid1$</ProjectGuid> in SimpleProject.myproj.

Break points in the Load method of the ProjectNode class shows that

this.projectIdGuid = Guid.NewGuid();

returns a new guid such as {6d4b8668-51ca-40eb-b013-9e7f96b82b68}.

In the Reload method of the ProjectNode class the method this.SetProjectGuidFromProjectFile() is fired and then the exeption is thrown as shown above. If I take out <ProjectGuid>$guid1$</ProjectGuid> in SimpleProject.myproj, I get through to the application without exception but you will have no guid associated with the application and will receive an error if an attempt to access the properties page of the newly created application. .myproj may not be registering correctly? I have spent a week researching this topic through various blogs and forums.

Answer

Simon Mourier picture Simon Mourier · Jun 10, 2014

The problem comes from the fact the MPF (which is a serious crappy piece of code - unfortunately, it's the only full-blown sample available) implements a custom template parameter replacement process (a Visual Studio-specific process described here: http://msdn.microsoft.com/en-us/library/eehb4faa.aspx) that only supports replacement for all project (sub) items, but not for the project item itself. So, you cannot use $guid1$ or any other $thingy$ in the xxxx.myproj file.

As you found out, the easiest way is to just remove this $guid1$ parameter, and let it blank, as the MPF does support a blank one:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    ...
    <ProjectGuid></ProjectGuid>
    ...
  </PropertyGroup>
  ...
</Project>

Now, contrary to your belief :) this works fine. This sets the ProjectIDGuid ProjectNode's property.

The property page you're also after is a totally different beast. To simplify, Visual Studio will query your hierarchy for the __VSHPROPID2.VSHPROPID_PropertyPagesCLSIDList property. By default, the MPF implements it like this:

    /// <summary>
    /// List of Guids of the config independent property pages. It is called by the GetProperty for VSHPROPID_PropertyPagesCLSIDList property.
    /// </summary>
    /// <returns></returns>
    protected virtual Guid[] GetConfigurationIndependentPropertyPages()
    {
        return new Guid[] { Guid.Empty };
    }

Guid.Empty is a poor choice (they could just send an empty array), because it will raise the following error which is hard to diagnose with the standard empty guid we don't known where it comes from:

enter image description here

So, what you need to do is override GetConfigurationIndependentPropertyPages and give it another Guid that correspond to a class that derive from SettingsPage, etc. but that's another story.