【问题标题】:Use EnvDTE in a vsix extension to add a reference to a shared project in a multi-project template solution在 vsix 扩展中使用 EnvDTE 在多项目模板解决方案中添加对共享项目的引用
【发布时间】:2021-08-01 02:17:26
【问题描述】:

我创建了一个Visual Studio multi-project template,其中一个是“共享”项目,另一个是普通“资源”项目。其他 5 个普通项目每个都需要引用“共享”和“资源”项目。

然后我在一个单独的解决方案上 create a VISX extension to implement a wizard,但不是将 .vsixmanifest 资产指向“当前解决方案中的项目”,而是指向我创建的 .zip 多项目模板。

我的意图是然后使用 vsix 向导添加必要的项目引用。 I've already done so with envDTE,而且效果很好……主要是。

添加对“资源”项目的引用没有问题。问题在于尝试添加“共享”项目作为参考。我尝试使用 (Project) 和 (Filename.shproj) 参数。

    DTE VS = automationObject as DTE;

    // This method is called after the solution is created.
    public void RunFinished()
        DTE VS = automationObject as DTE;
    {
        Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread();

        Project sharedProj = null;
        Project resourceProj = null;
        List<Project> versionProjs = new List<Project>();
        foreach (Project project in VS.Solution.Projects)
        {
            if (project.Name.Contains("Resources")) { resourceProj = project; }
            else if (project.Name.Contains("Shared")) { sharedProj = project; }
            else { versionProjs.Add(project); }
        }

        foreach (Project version in versionProjs)
        {
            // Add reference to shared project
            VSProject vsProj = (VSProject)version.Object;
            if (sharedProj != null)
            {
                // !!! Shared project should be added as a reference here, but it is causing a critical error. !!!

                //BuildDependency bldDepends = VS.Solution.SolutionBuild.BuildDependencies.Item(version.UniqueName);
                //bldDepends.AddProject(sharedProj.FileName);
                //vsProj.References.Add(sharedProj.FileName);

                //vsProj.References.AddProject(sharedProj);
            }

            // Add reference to the Resources project
            if (resourceProj != null) { vsProj.References.AddProject(resourceProj); }
        }
    }

AddProject(Project) 结果:

抛出异常:'System.Runtime.InteropServices.COMException' in 模板扩展.dll

灾难性故障(HRESULT 异常: 0x8000FFFF (E_UNEXPECTED))

AddProject(Filename.shproj) 结果:

抛出异常:“System.Runtime.InteropServices.COMException”在 模板扩展.dll

请确保该文件是可访问的, 并且它是一个有效的程序集或 COM 组件。


编辑 1

我决定将我的项目向公众开放。这个问题的源代码可以在这里找到:https://github.com/theBIMdev/RevitExtension

违规代码具体在Wizard.cs file. 注释掉的部分代表 3 种不同的尝试。

  • 将项目添加到依赖项中
  • vsProj.References.Add(sharedProj.FileName);
  • vsProj.References.AddProject(sharedProj);

编辑 2

这个问题已经引起了一些关注,并被微软here上报。

【问题讨论】:

    标签: visual-studio templates vsix envdte vs-extensibility


    【解决方案1】:

    如果没有通过 repro 进行调试,我最初的怀疑是共享项目类型可能不支持该特定操作。

    话虽如此,您可以将项目引用添加到需要它们的模板化项目文件中,而不是以编程方式尝试添加引用。

    几年前我做过类似的事情,我利用 ReplacementsDictionary 将我需要的自定义项目名称交换到各种项目文件中。遗憾的是,我在一段时间前丢失了该代码,但这可能会给您提供一个可选的解决方案来追求。即,考虑通过模板化项目文件添加对共享项目的引用。

    此致,

    【讨论】:

    • 这个解决方案是我考虑的事情之一。我可以轻松地将 $sharedprojname$ 添加到 ReplacementsDictionary,但是回到每个“真实”项目的模板中,我看不到如何用 $sharedprojname$ 替换对共享项目的引用。我什至尝试创建一个名为 $sharedprojname$ 的新共享项目,但即便如此,导入也无法找到“AppData/Temp/somefolder/SharedProjectName.projitems”。这将是一个很好的解决方法,如果你能记住你必须做什么才能让它工作。
    • 我将同一个 IWizard 关联到所有模板,并使用 customParams[0] 参数来确定正在调用哪个模板 myIWizard.RunStarted。基于 .vstemplate 的文件名,我将所需的项目名称存储在私有静态字符串中,并在被另一个 .vstemplate 调用时检索它并交换到替换字典中。
    • 那么,在您的解决方案中,用户在创建新项目时是否有多个模板可供选择?我没有在 vsix 解决方案中单独包含模板项目。我正在创建一个多项目模板,并将该 zip 文件添加到 vsix 解决方案中。我的想法是,如果我将每个模板单独添加到 vsix 项目中(并在 .vsixmanifest 资产选项卡中选择“解决方案中的项目”),我最终会得到多个单独的模板供用户选择,这是我不想要的.检索项目名称本身不是问题,它告诉嵌套模板参考。
    • 我选择只显示一个模板,并通过隐藏模板以编程方式添加其他项目,如下所述:docs.microsoft.com/en-us/archive/blogs/vsx/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    相关资源
    最近更新 更多