0

I am using VS 2017 to write C# code that uses the DTE API to generate a Visual Studio solution with a set of cpp (vcxproj) projects. I can create the sln and vcxproj files ok, using a vcxproj template (from the VS 2017 samples). But when I try to cast a EnvDTE.Project to a VCProject (namespace Microsoft.VisualStudio.VCProjectEngine), I get an error saying that the VCProject's interface is not registered:

{"Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.VisualStudio.VCProjectEngine.VCProject'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{DBF177F2-06DB-4A47-8AAD-C8E12BFD6C86}' failed due to the following error: Interface not registered (Exception from HRESULT: 0x80040155)."}

My C# project references extension DLL Microsoft.VisualStudio.ProjectEngine, which is where VCProject is defined, and it compiles fine. (Another available extension DLL is Microsoft.VisualStudio.VCProject, but it doesn't contain the VCProject itself, and referencing it has no effect for me).

My question is, is this normal behavior for EnvDTE/VCProject? If your C# program uses VCProject, is the program expected to first programmatically register the VCProject DLL if necessary, so it can run on any Windows machine? I've found other questions about the unregistered DLL exception, but the answer is always to register the DLL. Why would a referenced assembly need to be registered? My code is as follows.

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;
}
Gordon Dakin
  • 51
  • 1
  • 3
  • Actually, the project containing my code is a class library project, and it is called from a WPF windows application. Would that account for problem, as a console app would? – Gordon Dakin Oct 23 '17 at 18:33
  • It doesn't use threading. – Gordon Dakin Oct 23 '17 at 18:49
  • Ah, this is the VS2017-specific flavor of VCProject. It is indeed not registered, VS2017 keeps all registration info separate [in the privateregistry.bin file](https://stackoverflow.com/questions/41119996/where-does-visual-studio-2017-store-its-config). Works inside VS but not outside of it. No workaround afaik. – Hans Passant Oct 23 '17 at 19:04
  • If I understand correctly, my exception is due to the VCProject DLL not being found in the actual registry, because it would be in the private registry (if anywhere). As a workaround, would it make sense for my program to add the entry to the actual registry, before trying to cast to a VCProject? Only problem is, I don't know what registry item path and contents to use (I followed directions in the link and checked the user registry, but the guid's entry is not there either). – Gordon Dakin Oct 23 '17 at 20:01

0 Answers0