1

上下文:我目前正在开发一个 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在我的IWizardRoot 和 Child 派生类中强制执行特定的 GUID 替换,但是 VS 一直在替换旧的 GUID:

在这里,$Sguid6$标签将被 VS 忽略,并被新的闪亮 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,或者至少不要更改它们?

4

2 回答 2

1

我找到了一个替代方案:我们需要通过手动设置项目引用IWizard。只需ProjectFinishedGenerating在您的添加/编辑您的方法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);
    }
于 2014-07-07T09:18:17.520 回答
0

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

引用由路径和名称解析。

可以在此处找到更多讨论:MSDN也指出,这<Project>无关紧要。然而,正如另一位用户所说,它似乎不适用于 Azure 项目。

于 2017-11-03T13:07:48.530 回答