【问题标题】:Using C#, how do I create a new Visual Studio 2012 Solution programmatically?使用 C#,如何以编程方式创建新的 Visual Studio 2012 解决方案?
【发布时间】:2014-01-02 21:58:16
【问题描述】:

我关注this Stack Overflow post关于如何为 VS2010 创建项目,希望它能为我指明正确的方向,但不包括创建 VS2012 项目或解决方案。 p>

我也探索过使用SLNTools,但我不知道如何从头开始创建新的解决方案。

最终,我想以编程方式创建 3-4 个 VS2012 项目,然后将它们添加到同样以编程方式创建的解决方案中。


我尝试了一个基于this Stack Overflow post 的解决方案,但出现了一个奇怪的错误。代码如下:

    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");

这是错误:

【问题讨论】:

  • 出于好奇,为什么?这似乎是你很少做的事情,为什么要为它创建一个程序?
  • 我有一些特定的要求实际上会经常重复,但是为了简化使用一个抽象的例子,假设我有 20 个不同的开发人员都在为我工作——我希望他们用基本项目信息填写一个简单的winform,然后使用正确的图层、实用程序类、保存位置、发布设置等自动(一致地)生成解决方案。它实际上比这更复杂,所以如果离线请告诉我你想要更多细节。
  • @Xenolightning--谢谢,我之前确实看过那个,但它没有提供创建和保存解决方案的完整示例。
  • @MatthewPatrickCashatt Ahh 抱歉,您在创建解决方案之后。两者都没有涵盖。 This 可以帮助你。 Solution4.SaveAs 看起来像是创建解决方案文件的候选人。

标签: c# visual-studio visual-studio-2012 com-interop


【解决方案1】:

这对我有用(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();
}

[编辑:] 在 HKCR 下查看,似乎有一个 VisualStudio.DTE(没有 .11.0)将指向最新版本的 VS。所以在我有VS2012和VS2013的机器上,会使用后者。

【讨论】:

    【解决方案2】:

    使用 .NET4 Winforms 测试和工作,以及对 EnvDTE100.dll 的引用(还应添加对 EnvDTE90.dll、EnvDTE80.dll 和 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");
    

    【讨论】:

    • 通过 NuGet 添加对 EnvDTE 的引用。然后你就没有依赖关系了。
    【解决方案3】:

    Jimmy 和 Xenolightining 下面的两种解决方案都有效,但是,我仍然遇到上述错误的问题。因此,如果其他人遇到该错误,请参阅此链接:

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

    总结上面的链接(或者如果它曾经被破坏),这就是你所做的。将此类添加到您的解决方案中:

     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);
        }
    

    现在用这些语句包装代码生成代码(来自下面的答案):

    MessageFilter.Register();
    //INSERT YOUR CODE HERE
    MessageFilter.Revoke();
    

    【讨论】:

      【解决方案4】:

      我没有 Visual Studio 2012 IDE,所以我正在尝试使用 Visual Studio 2013

      使用 C#,我以编程方式创建了一个新的 Visual Studio 2013 解决方案

      第一步:首先,创建窗体应用程序,然后在默认窗体1中创建名称为create的按钮。

      Step2:接下来,在创建按钮点击事件中编写如下代码。

      private void btn_Create_Click(object sender, EventArgs e)
            {
                try
                {
                    //// Get an instance of the currently running Visual Studio IDE.
                    System.Type type = System.Type.GetTypeFromProgID("VisualStudio.DTE.12.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 12.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 12.0\Common7\IDE\ProjectTemplatesCache\CSharp\Windows\1033\ClassLibrary\csClassLibrary.vstemplate",
                        @"C:\NewSolution\ClassLibrary", "ClassLibrary");
      
                    // save and quit
                    dte.ExecuteCommand("File.SaveAll");
                    dte.Quit();
                }
                catch (Exception ex)
                {
                    throw;
                }
            }  
      

      Step3:完成这些步骤后,在项目引用中添加envdte.dll引用并构建它。
      (从系统路径“C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies”获取 envdte.dll / 从网络下载)

      步骤 4:如果您完整填写所有步骤,那么您将成功地以编程方式创建解决方案。

      【讨论】:

        猜你喜欢
        • 2010-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-03
        相关资源
        最近更新 更多