Попытка привести проект DTE к VCProject вызывает исключение, говорящее, что DLL не зарегистрирована
Я использую VS 2017 для написания кода C#, который использует DTE API для генерации решения Visual Studio с набором проектов cpp (vcxproj). Я могу создать файлы sln и vcxproj нормально, используя шаблон vcxproj (из примеров VS 2017). Но когда я пытаюсь привести EnvDTE.Project к VCProject (пространство имен Microsoft.VisualStudio.VCProjectEngine), я получаю сообщение об ошибке, в котором говорится, что интерфейс VCProject не зарегистрирован:
{"Невозможно привести объект COM типа 'System.__ComObject' к типу интерфейса 'Microsoft.VisualStudio.VCProjectEngine.VCProject'. Эта операция завершилась неудачно, поскольку вызов QueryInterface для компонента COM для интерфейса с IID '{DBF177F2-06DB-4A47-8AAD-C8E12BFD6C86}'не удалось из-за следующей ошибки: Интерфейс не зарегистрирован (Исключение из HRESULT: 0x80040155)."}
Мой проект на C# ссылается на расширение DLL Microsoft.VisualStudio.ProjectEngine, в котором определен VCProject, и он прекрасно компилируется. (Другое доступное расширение DLL - это Microsoft.VisualStudio.VCProject, но оно не содержит сам VCProject, и ссылки на него для меня не действуют).
Мой вопрос, это нормальное поведение для EnvDTE/VCProject? Если ваша программа на C# использует VCProject, должна ли программа сначала программно зарегистрировать VCProject DLL, если это необходимо, чтобы она могла работать на любом компьютере с Windows? Я нашел другие вопросы о незарегистрированном исключении DLL, но ответом всегда является регистрация DLL. Зачем ссылочная сборка должна быть зарегистрирована? Мой код выглядит следующим образом.
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.VCProjectEngine;
Type type = Type.GetTypeFromProgID("VisualStudio.DTE.15.0");
Object obj = System.Activator.CreateInstance(type, true);
EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)obj;
dte.SuppressUI = true;
EnvDTE100.Solution4 solution = (EnvDTE100.Solution4)dte.Solution;
solution.Create(@"C:\Test\", "Test");
// create the cpp project
string cppTemplateFile = @"C:\Test\Cpp\DLL.vstemplate";
solution.AddFromTemplate(cppTemplateFile, @"C:\Test", projNameCpp, false);
foreach (Project project in solution.Projects)
{
// this throws an exception about VCProject not registered:
VCProject vcProject = project.Object as VCProject;
// same exception happens with direct casting:
//VCProject vcProject = (VCProject)project.Object;
}