Visual Studio多项目模板:项目参考问题

时间:2014-06-26 11:45:17

标签: visual-studio-2010 visual-studio templates msbuild multi-project

上下文:我目前正在开发一个VB.NET多项目模板,它们之间有交叉引用,几乎可以正常工作。

问题: VS为生成的每个项目生成新的GUID,并将它们更新为新的.sln和每个新的.vbproj,但从不以相同的方式将项目引用更新为.vbproj。

这是一个.vbproj示例:

<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>

...还有另一个生成的.vbproj引用了上一个项目:

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

一些线索:我已经尝试在我的replacementsDictionary Root和Child派生类中通过IWizard强制执行特定的GUID替换,但VS一直在替换旧的GUID:

此处,VS将忽略$Sguid6$标记,并将替换为新的闪亮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>

然后又在另一个.vbproj中:$Sguid6$将采用我告诉他的GUID,按预期接受replacementsDictionary

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

问题:我如何告诉VS正确交换所有这些GUID,或者至少不要更改它们?

2 个答案:

答案 0 :(得分:1)

我找到了另一种选择:我们需要通过IWizard手动设置项目参考。只需在RootIWizard中添加/编辑ProjectFinishedGenerating方法:

    public void ProjectFinishedGenerating(EnvDTE.Project project)
    {
        //Will Store all referencies 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 for particular projects in the template all needed referencies
        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);
    }

答案 1 :(得分:0)

我也遇到了这个问题(但是使用了C#!)我只是通过删除模板项目文件中<Project>{GUID}</Project>标签内的<ProjectReference>来解决它。

引用由路径和名称解析。

可以在此处找到更多讨论:MSDN还说明<Project>并不重要。 Hoewever,它似乎不适用于Azure项目,正如另一位用户所说。