See the question and my original answer on StackOverflow

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.