Question

I followed this Stack Overflow post regarding how to create a project for VS2010, hoping that it would point me in the correct direction, but it doesn't cover creating a VS2012 project or solution.

I also explored using SLNTools, but I don't see how to create a new solution from scratch.

Ultimately, I would like to create 3-4 VS2012 projects programmatically and then add them to a solution which is also created programmatically.


I attempted a solution based on this Stack Overflow post, but I get an odd error. Here is the code:

    Type typeDTE = Type.GetTypeFromProgID("VisualStudio.DTE.11.0");
    var dte = (DTE)Activator.CreateInstance(typeDTE, true);
    var sln = (Solution2)dte.Solution;
    sln.Create(@"D:\Visual Studio\Projects","Test");

And here is the error:

enter image description here

Was it helpful?

Solution

This works for me (VS2012 Ultimate):

static void Main(string[] args)
{
    System.Type type = System.Type.GetTypeFromProgID("VisualStudio.DTE.11.0");
    Object obj = System.Activator.CreateInstance(type, true);
    EnvDTE.DTE dte = (EnvDTE.DTE)obj;
    dte.MainWindow.Visible = true; // optional if you want to See VS doing its thing

    // create a new solution
    dte.Solution.Create(@"C:\NewSolution\", "NewSolution");
    var solution = dte.Solution;

    // create a C# WinForms app
    solution.AddFromTemplate(@"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\ProjectTemplatesCache\CSharp\Windows\1033\WindowsApplication\csWindowsApplication.vstemplate",
        @"C:\NewSolution\WinFormsApp", "WinFormsApp");

    // create a C# class library
    solution.AddFromTemplate(@"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\ProjectTemplatesCache\CSharp\Windows\1033\ClassLibrary\csClassLibrary.vstemplate",
        @"C:\NewSolution\ClassLibrary", "ClassLibrary");

    // save and quit
    dte.ExecuteCommand("File.SaveAll");
    dte.Quit();
}

[Edit:] Looking under HKCR, it looks like there's a VisualStudio.DTE (without the .11.0) that will point to the latest version of VS. So on my machine with VS2012 and VS2013, it will use the latter.

OTHER TIPS

Tested and working using .NET4 Winforms, and a reference to EnvDTE100.dll (which should also add references to EnvDTE90.dll, EnvDTE80.dll, and EnvDTE.dll)

Type type = Type.GetTypeFromProgID("VisualStudio.DTE.11.0");
Object obj = System.Activator.CreateInstance(type, true);
EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)obj;
EnvDTE100.Solution4 _solution = (EnvDTE100.Solution4)dte.Solution;
_solution.Create(@"C:\Test\", "Test");
_solution.SaveAs(@"C:\Test\Test.sln");

Both solutions below by Jimmy and Xenolightining work, however, I still had the problem of the aforementioned error. So, in case anyone else encounters that error, see this link:

http://msdn.microsoft.com/en-us/library/ms228772(v=vs.80).aspx

To summarize the link above (or in case it is ever broken), here is what you do. Add this class to your solution:

 public class MessageFilter : IOleMessageFilter
    {
        //
        // Class containing the IOleMessageFilter
        // thread error-handling functions.

        // Start the filter.
        public static void Register()
        {
            IOleMessageFilter newFilter = new MessageFilter(); 
            IOleMessageFilter oldFilter = null; 
            CoRegisterMessageFilter(newFilter, out oldFilter);
        }

        // Done with the filter, close it.
        public static void Revoke()
        {
            IOleMessageFilter oldFilter = null; 
            CoRegisterMessageFilter(null, out oldFilter);
        }

        //
        // IOleMessageFilter functions.
        // Handle incoming thread requests.
        int IOleMessageFilter.HandleInComingCall(int dwCallType, 
          System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr 
          lpInterfaceInfo) 
        {
            //Return the flag SERVERCALL_ISHANDLED.
            return 0;
        }

        // Thread call was rejected, so try again.
        int IOleMessageFilter.RetryRejectedCall(System.IntPtr 
          hTaskCallee, int dwTickCount, int dwRejectType)
        {
            if (dwRejectType == 2)
            // flag = SERVERCALL_RETRYLATER.
            {
                // Retry the thread call immediately if return >=0 & 
                // <100.
                return 99;
            }
            // Too busy; cancel call.
            return -1;
        }

        int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, 
          int dwTickCount, int dwPendingType)
        {
            //Return the flag PENDINGMSG_WAITDEFPROCESS.
            return 2; 
        }

        // Implement the IOleMessageFilter interface.
        [DllImport("Ole32.dll")]
        private static extern int 
          CoRegisterMessageFilter(IOleMessageFilter newFilter, out 
          IOleMessageFilter oldFilter);
    }

    [ComImport(), Guid("00000016-0000-0000-C000-000000000046"), 
    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    interface IOleMessageFilter 
    {
        [PreserveSig]
        int HandleInComingCall( 
            int dwCallType, 
            IntPtr hTaskCaller, 
            int dwTickCount, 
            IntPtr lpInterfaceInfo);

        [PreserveSig]
        int RetryRejectedCall( 
            IntPtr hTaskCallee, 
            int dwTickCount,
            int dwRejectType);

        [PreserveSig]
        int MessagePending( 
            IntPtr hTaskCallee, 
            int dwTickCount,
            int dwPendingType);
    }

Now wrap the code-generation code (from answers below) with these statements:

MessageFilter.Register();
//INSERT YOUR CODE HERE
MessageFilter.Revoke();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top