Guillaume VARA
Guillaume VARA

Reputation: 31

Visual Studio Multi Project Template : Project Reference Issues

Context : I'm currently working on a VB.NET multi-project template with cross-references between them, which works almost fine.

Problem : VS generates new GUIDs for each project generated and updates them into the new .sln and each new .vbproj but never updates the project references into the .vbproj the same way.

Here is a .vbproj example :

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <ProductVersion>
    </ProductVersion>
    <SchemaVersion>
    </SchemaVersion>
    <ProjectGuid>{_NewGUIDGeneratedByVS_}</ProjectGuid>
    <OutputType>Library</OutputType>
    <RootNamespace>Template.DataModel</RootNamespace>
    <AssemblyName>Template.DataModel</AssemblyName>
    <FileAlignment>512</FileAlignment>
    <MyType>Windows</MyType>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
  </PropertyGroup>

...And further in another generated .vbproj which refers to the previous project :

<ProjectReference Include="..\Template.DataModel\Template.DataModel.vbproj">
          <Project>{_OldBoringGUID_}</Project>
          <Name>Template.DataModel</Name>
        </ProjectReference>

Some Clues : I already tried to force specific GUID replacements via replacementsDictionary in my IWizard Root and Child derived classes, but VS keeps replacing old GUIDs :

Here, the $Sguid6$ tag will be ignored by VS and will be replaced by a new shiny GUID !

<ProductVersion>8.0.50727</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{$Sguid6$}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <StartupObject>$safeprojectname$.My.MyApplication</StartupObject>        <RootNamespace>$safeprojectname$</RootNamespace>
    <AssemblyName>$safeprojectname$</AssemblyName>

Then again in another .vbproj : the $Sguid6$ will take the GUID i told him to take in my replacementsDictionary, as expected.

<ProjectReference Include="..\$safeprojectname$.DataModel\$safeprojectname$.DataModel.vbproj">
  <Project>{$Sguid6$}</Project>
  <Name>$safeprojectname$.DataModel</Name>
  <Private>True</Private>
</ProjectReference>

Question : How could i tell VS to swap correctly all these GUID, or at least not to change them ?

Upvotes: 1

Views: 1183

Answers (2)

Guillaume VARA
Guillaume VARA

Reputation: 31

I found an alternative : we need to set the project references manually via IWizard. Just add/edit your ProjectFinishedGenerating method in your RootIWizard :

    public void ProjectFinishedGenerating(EnvDTE.Project project)
    {
        // will store all references related to the template
        Dictionary<String, Project> lReferences = new Dictionary<string, Project>();

        foreach (Project p in pDTE.Solution.Projects.Cast<Project>())
        {
            lReferences.Add(p.Name, p);
        }

        // will add all needed references for each specific project invoked from the template
        foreach (Project p in pDTE.Solution.Projects)
        {
            VSLangProj80.VSProject2 vsproj = (VSLangProj80.VSProject2)p.Object;

            if (p.Name.IsMatchProjectName("Services"))
            {
                vsproj.References.AddProject(lReferences.Single(f => f.Key.IsMatchProjectName("DataModel")).Value);
                vsproj.References.AddProject(lReferences.Single(f => f.Key.IsMatchProjectName("WS")).Value);
            }
            else if (p.Name.IsMatchProjectName("Web"))
            {
                vsproj.References.AddProject(lReferences.Single(f => f.Key.IsMatchProjectName("DataModel")).Value);
                vsproj.References.AddProject(lReferences.Single(f => f.Key.IsMatchProjectName("WS")).Value);
                vsproj.References.AddProject(lReferences.Single(f => f.Key.IsMatchProjectName("Services")).Value);
            }
            else if (p.Name.IsMatchProjectName("WinForms"))
            {
                vsproj.References.AddProject(lReferences.Single(f => f.Key.IsMatchProjectName("DataModel")).Value);
                vsproj.References.AddProject(lReferences.Single(f => f.Key.IsMatchProjectName("WS")).Value);
                vsproj.References.AddProject(lReferences.Single(f => f.Key.IsMatchProjectName("Services")).Value);
                vsproj.References.AddProject(lReferences.Single(f => f.Key.Contains("SortableBindingList")).Value);
            }

            vsproj.Refresh();
            vsproj.Project.Save();
        }

        pDTE.Solution.SolutionBuild.Build(true);
    }

Upvotes: 1

Creepin
Creepin

Reputation: 509

I also ran into this problem (but using C#!) and I simply solved it by removing the <Project>{GUID}</Project> within the <ProjectReference> Tag within the template project file.

The reference is resolved by the path and the name.

More discussion could be found here: MSDN where it is also stated, that the <Project> does not matter. Hoewever, it does not seem to work with Azure projects, as another user stated.

Upvotes: 0

Related Questions