Пример #1
0
 public void DetachAll()
 {
     _debugger.DetachAll();
 }
Пример #2
0
    static void Main(string[] args)
    {
        String                prjTemplDir    = Path.Combine(vsInstallPath, @"Common7\IDE\ProjectTemplates");
        List <String>         vsTemplates    = Directory.GetFiles(prjTemplDir, "*.vstemplate", SearchOption.AllDirectories).Select(x => x.Substring(prjTemplDir.Length + 1)).ToList();
        Regex                 re             = new Regex("^(.*?)" + Regex.Escape(@"\"));
        Func <String, String> untilBackSlash = (s) => { return(re.Match(s).Groups[1].ToString()); };
        List <String>         languages      = vsTemplates.Select(x => untilBackSlash(x)).ToList();
        List <String>         vsNames        = new List <string>();

        for (int i = 0; i < vsTemplates.Count; i++)
        {
            bool   keep = true;
            String lang = languages[i];
            if (lang != "CSharp" && lang != "VC" && lang != "Javascript")
            {
                keep = false;
            }

            if (
                vsTemplates[i].Contains("WebTemplate")  // has wizard
                ||
                vsTemplates[i].Contains("WapProj")      // hangs
                )
            {
                keep = false;
            }

            if (!keep)
            {
                vsTemplates.RemoveAt(i);
                languages.RemoveAt(i);
                i--;
                continue;
            }
            vsTemplates[i] = vsTemplates[i].Substring(languages[i].Length + 1);
            vsNames.Add(vsTemplates[i].Replace("\\", "_").Replace("1033_", "").Replace(".vstemplate", "").Replace(".", ""));
        }

        //var procs = System.Diagnostics.Process.GetProcesses().Where(x => x.ProcessName == "devenv").ToArray();
        //String devenvPath = @"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\devenv.exe";
        //Assembly asm = Assembly.LoadFile(devenvPath);

        DTE2 dte = null;

        try
        {
            //String[] allPaths = {
            //    Path.Combine(vsInstallPath, @"Common7\IDE\PublicAssemblies"),
            //    // VCProjectShim is here.
            //    Path.Combine(vsInstallPath, @"Common7\IDE\CommonExtensions\Microsoft\VC\Project")
            //};

            //AppDomain.CurrentDomain.AssemblyResolve += (s, asmArgs) =>
            //{
            //    String dllName = new AssemblyName(asmArgs.Name).Name + ".dll";

            //    foreach (String dir in allPaths)
            //    {
            //        string path = Path.Combine(dir, dllName);

            //        if (!File.Exists(path))
            //            continue;

            //        return Assembly.LoadFrom(path);
            //    }

            //    Console.WriteLine("Warning: Required assembly not found: " + dllName);
            //    return null;
            //};

            //dte = (DTE)Activator.CreateInstance(Type.GetTypeFromProgID("VisualStudio.DTE.10.0"), true);
            //dte = (DTE)Activator.CreateInstance(Type.GetTypeFromProgID("VisualStudio.DTE.12.0"), true);
            //dte = (DTE)Activator.CreateInstance(Type.GetTypeFromProgID("VisualStudio.DTE.16.0"), true);

            bool bNormalStart = false;

            MessageFilter.Register();
            if (bNormalStart)
            {
                dte = (DTE2)Activator.CreateInstance(Type.GetTypeFromProgID(vsId), true);
            }
            else
            {
                //Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider.GetService()
                bool     bAttached         = false;
                int      processId         = 0;
                Process2 processToAttachTo = null;

                for (int iTry = 0; iTry < 2; iTry++)
                {
                    dte = (DTE2)Marshal.GetActiveObject(debuggerVsId);

                    var       processes = dte.Debugger.LocalProcesses.Cast <EnvDTE.Process>().ToArray();
                    Debugger2 debugger2 = (Debugger2)dte.Debugger;

                    //
                    // https://varionet.wordpress.com/tag/debug/
                    // Attach2 sometimes triggers error: 8971001E, need to detach from all processes.
                    // Something to do debugging multiple processes?
                    //
                    debugger2.DetachAll();

                    int       c         = debugger2.Transports.Count;
                    Transport transport = debugger2.Transports.Item(1 /* Default transport */);
                    //foreach (var ix in transport.Engines)
                    //{
                    //    Engine e = ix as Engine;

                    //    String name = e.Name;
                    //    Console.WriteLine("'" + name + "'");
                    //}

                    // Otherwise will get timeout while trying to evaluate any com object in visual studio watch window
                    String debuggerType = "Managed (v3.5, v3.0, v2.0)";
                    //String debuggerType = "Managed (v4.6, v4.5, v4.0)";
                    //String debuggerType = "Managed";
                    Engine[] engines = new Engine[] { transport.Engines.Item(debuggerType) };

                    foreach (var process in processes)
                    {
                        String name = Path.GetFileNameWithoutExtension(Utils.call(() => (process.Name))).ToLower();
                        if (name != "devenv")
                        {
                            continue;
                        }

                        processId = Utils.call(() => (process.ProcessID));
                        String cmdArgs = GetProcessCommandLine(processId);

                        if (cmdArgs == null || !cmdArgs.Contains("-Embedding"))
                        {
                            continue;
                        }

                        processToAttachTo = process as Process2;
                        //Console.ReadKey();
                        Console.WriteLine("Attaching to: " + processId);
                        Utils.callVoidFunction(() => { processToAttachTo.Attach2(engines); });
                        // Apparently it takes some time for debugger to attach to process, otherwise missing breakpoints.
                        // Not sure if some sort of wait could be triggerred.
                        //System.Threading.Thread.Sleep(2000);
                        bAttached = true;
                        break;
                    }

                    if (bAttached)
                    {
                        break;
                    }

                    {
                        if (iTry == 1)
                        {
                            Console.WriteLine("Error: Failed to launch vs2017/2019.");
                            return;
                        }

                        // Analogue of
                        // Activator.CreateInstance(Type.GetTypeFromProgID(vsId), true);
                        // only with  experimental visual studio version.
                        Start_devenv_Embedded();
                    }
                }

                dte = (DTE2)GetDTE(processId, 120);
                //dte = null;
            }

            String edition = dte.Edition;
            Console.WriteLine("Edition: " + edition);
            Console.WriteLine("-----------------------------------------------");

            // Make it visible.
            if (!dte.MainWindow.Visible)
            {
                dte.MainWindow.Visible = true;
                dte.UserControl        = true;
            }

            Solution2 sln2 = (Solution2)dte.Solution;
            //sln2.Open(@"C:\PrototypingQuick\ProjectGen\Solution2.sln");
            //sln2.Open(@"C:\PrototypingQuick\ProjectGen\Solution.sln");
            //sln2.Open(@"C:\PrototypingQuick\ProjectGen\Solution1.sln");
            //sln2.Close();

            // Add existing project to solution
            //String projPath = @"D:\PrototypingQuick\ProjectGen\Dll1\Dll1.vcxproj";
            //String projPath = @"D:\PrototypingQuick\ProjectGen\Dll1\Dll2.vcxproj";
            //sln2.AddFromFile(projPath);
            //sln2.SolutionBuild.Build();

            //Microsoft.VisualStudio.OLE.Interop.IServiceProvider serv = (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte;
            //dte.ExecuteCommand("File.InvokeOpenSyncProjectFile", "args");
            //dte.ExecuteCommand("File.InvokeOpenSyncProjectFile");
            //dte.ExecuteCommand("File.InvokeOpenSyncProjectFile", "thisIsArg1");
            //dte.ExecuteCommand("Tools.InvokeExecuteScript", @"D:\Prototyping\cppscriptcore\Tools\vsDev\bin\Debug\vsDev.dll");
            //int cmdCount = Utils.call(() => (dte.Commands.Count));


            //for( int i = 1; i <= cmdCount; i++)
            //{
            //    Command c = Utils.call(() => dte.Commands.Item(i));
            //    Console.WriteLine(Utils.call(() => c.Name));
            //    Console.WriteLine( "    " + Utils.call(() => c.ID));
            //    Console.WriteLine( "    " + Utils.call(() => c.Guid.ToString()) );
            //    Console.WriteLine();
            //}

            //Guid service = new Guid("89BE061A-1103-4D1D-8293-A51F8480E202");
            //Guid serviceApi = new Guid("89BE061A-1103-4D1D-8293-A51F8480E201");
            //IntPtr obj = IntPtr.Zero;
            //int r = serv.QueryService(ref service, ref serviceApi, out obj);

            //Console.WriteLine("[ Press any key to close ... ]");
            //Console.ReadKey();

            /*
             * // Generate huge amount of temporary projects.
             * Solution2 sln2 = (Solution2)dte.Solution;
             * String mainDir = @"d:\Prototyping\testsln";
             * String slnTempDir = Path.Combine(mainDir, "slnTemp");
             *
             *
             * for (int i = 0; i < vsTemplates.Count; i++)
             * {
             *  String name = vsNames[i];
             *  String dir = Path.Combine(mainDir, name);
             *  bool bKeepProject = true;
             *
             *  if (Directory.Exists(dir))
             *      Directory.Delete(dir, true);
             *
             *  Console.Write("Project '" + name + "... " );
             *  Directory.CreateDirectory(dir);
             *  sln2.Create(slnTempDir, name);
             *
             *  try
             *  {
             *      string csTemplatePath = sln2.GetProjectTemplate(vsTemplates[i], languages[i]);
             *      sln2.AddFromTemplate(csTemplatePath, dir, name, false);
             *      Console.WriteLine("ok." );
             *  }
             *  catch (Exception ex)
             *  {
             *      Console.WriteLine("Project '" + name + ": " + ex.Message);
             *      bKeepProject = false;
             *  }
             *  if(bKeepProject)
             *      sln2.SaveAs(Path.Combine(dir, name + ".sln"));
             *  sln2.Close(bKeepProject);
             *
             *  if (!bKeepProject)
             *      Directory.Delete(dir, true);
             * }
             */


            Solution sln = dte.Solution;

            /*
             * String slnPath = @"c:\Prototyping\testsln";
             * if( !sln.IsOpen )
             *  sln.Create(slnPath, "test");
             * Solution2 sln2 = (Solution2) sln;
             * Solution3 sln3 = (Solution3) sln;
             *
             * int nCount = sln.Projects.Count;
             *
             * dte.Events.SolutionEvents.ProjectAdded += SolutionEvents_ProjectAdded;
             * dte.Events.SolutionItemsEvents.ItemAdded += SolutionItemsEvents_ItemAdded;
             * dynamic events = dte.Events.GetObject("CSharpProjectItemsEvents");
             * //Events2 events2 = dte.Events as Events2;
             * //events2.ProjectItemsEvents.ItemAdded += Pievents_ItemAdded;
             * pievents = events as ProjectItemsEvents;
             * pievents.ItemAdded += Pievents_ItemAdded;
             *
             *
             * if (nCount <= 0)
             * {
             *  string csTemplatePath = sln2.GetProjectTemplate(@"Windows\1033\ConsoleApplication\csConsoleApplication.vstemplate", "CSharp");
             *  sln.AddFromTemplate(csTemplatePath, slnPath + "\\prj", "Foo", false);
             *  dte.ExecuteCommand("File.SaveAll");
             * }
             */

            //sln.Open(@"D:\PrototypingQuick\ConsoleApplication2\ConsoleApplication2.sln");
            while (sln.Projects.Count == 0)
            {
                Console.WriteLine("Please open solution in newly opened visual studio and then press enter to continue...");
                Console.ReadLine();
            }

            // Enumerate available configurations within a project
            Project p = sln2.Projects.Item(1);

            //
            // Get / set .NET framework version, https://blogs.msdn.microsoft.com/visualstudio/2010/02/25/how-to-retarget-a-project-using-dte/
            //
            // ".NETFramework,Version=v4.7.2"
            //
            String DotNetVersion = p.Properties.Item("TargetFrameworkMoniker").Value;


            var oConfs = p.ConfigurationManager.Cast <Configuration>().ToArray();
            var confs  = oConfs.Select(x => x.ConfigurationName + "|" + x.PlatformName).ToArray();

            foreach (String c in confs)
            {
                Console.WriteLine("- " + c);
            }

            // C#/C++ project properties scanning
            //Project p = sln.Projects.Item(1);
            //Dictionary<String, Object> d = new Dictionary<string, object>();
            //foreach (Property prop in p.Properties)
            //{
            //    try
            //    {
            //        d[prop.Name] = prop.Value;
            //    }
            //    catch (Exception)
            //    {
            //    }
            //}

            // C++ project model scanning
            //VCProject vcProject = p.Object as VCProject;
            //VCProject vcProject = (VCProject)p.Object;

            //if (vcProject == null)
            //{
            //    MessageFilter.Revoke();
            //    Console.WriteLine("Not a C++ project or vs2017 or later (registry moved to file problem).");
            //    Console.WriteLine("[Press any key to close]");
            //    Console.ReadLine();
            //    return;
            //}

            //VCProjectEngine peng2 = vcProject.VCProjectEngine as VCProjectEngine;
            //VCProjectEngineShim peng = peng2 as VCProjectEngineShim;
            //var sp = peng.VsServiceProvider;

            // Scan for all subprojects.
            List <Project> projects = GetProjects(sln);
            foreach (Project genProj in projects)
            {
#if !OLD_VS
                VSProject2 sharpProj = genProj.Object as VSProject2;
#else
                VSProject2 sharpProj = genProj.Object as VSProject2;
                //VSProject3 sharpProj = genProj.Object as VSProject3;
                //VSProject4 sharpProj = genProj.Object as VSProject4;
#endif
                VCProject cppProj = genProj.Object as VCProject;

                String name = genProj.Name;
                Console.Write("Project: " + name + " - language( ~" + genProj.Kind + "): ");
                if (sharpProj == null && cppProj == null)
                {
                    Console.WriteLine("Unknown");
                    continue;
                }

                if (sharpProj != null)
                {
                    Console.WriteLine("C#");
                }

                if (cppProj != null)
                {
                    Console.WriteLine("C++ ");
                }

                //foreach (Reference r in ((References)vsp2.References).Cast<Reference>())
                //{
                //    Console.WriteLine(r.Path);
                //    Console.WriteLine("CopyLocal = " + r.CopyLocal);
                //}
            }

            Console.WriteLine("[Press any key to close]");
            Console.ReadLine();

            // Get project GUID
            //IVsSolution service = GetService( dte, typeof(IVsSolution)) as IVsSolution;

            //String uname = p.UniqueName;
            //IVsHierarchy hierarchy;
            //service.GetProjectOfUniqueName(uname, out hierarchy);
            //Guid projectGuid;
            //hierarchy.GetGuidProperty(Microsoft.VisualStudio.VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ProjectIDGuid, out projectGuid);

            //Console.WriteLine("Project guid: " + projectGuid.ToString());

            // Add file in programming language independent manner.
            //p.ProjectItems.AddFromFile(@"D:\Prototyping\cppscriptcore\cppscript\cppscript.cpp");

            //if (vcProject != null)
            //{
            //foreach (object oFile in (IVCCollection)vcProject.Files)
            //{
            //    VCFile file = oFile as VCFile;
            //    Console.WriteLine(file.Name);
            //    Console.WriteLine(" " + file.RelativePath);

            //    foreach (var _conf in (IVCCollection)file.FileConfigurations)
            //    {
            //        VCFileConfiguration conf = _conf as VCFileConfiguration;
            //        Console.WriteLine(conf.Name);

            //        VCCLCompilerTool compilerTool = conf.Tool as VCCLCompilerTool;
            //        if (compilerTool == null)
            //            continue;

            //        Console.WriteLine("Defines: " + compilerTool.PreprocessorDefinitions);
            //    }
            //}


            //VCFilter f = null;
            //foreach (object oItem in (IVCCollection)vcProject.Items)
            //{
            //    VCFile file = oItem as VCFile;
            //    VCFilter fitem = oItem as VCFilter;

            //    if (fitem != null && fitem.Name == "Test1")
            //        f = fitem;
            //}

            //if( f == null )
            //    f = vcProject.AddFilter("Test1") as VCFilter;
            //f.AddFile(@"D:\Prototyping\cppscriptcore\cppscript\cppscript.cpp");


            // Recursive files / folder adding / C++ project
            //String fromDir = @"C:\Prototyping\vlc-3.0.2";

            //List<String> files = Directory.GetFiles(fromDir, "*.c", SearchOption.AllDirectories).ToList();
            //files.AddRange(Directory.GetFiles(fromDir, "*.h", SearchOption.AllDirectories));
            //files = files.Select(x => x.Substring(fromDir.Length + 1)).ToList();

            //Stopwatch sw = Stopwatch.StartNew();

            //foreach (String file in files)
            //{
            //    String[] pp = file.Split('\\');
            //    IVCCollection items = (IVCCollection)vcProject.Items;
            //    VCFilter parent = null;
            //    VCFilter filter = null;

            //    for (int i = 0; i < pp.Length - 1; i++)
            //    {
            //        filter = items.OfType<VCFilter>().Where(x => x.Name == pp[i]).FirstOrDefault();
            //        if (filter == null)
            //            if (i == 0)
            //                filter = (VCFilter)vcProject.AddFilter(pp[i]);
            //            else
            //                filter = (VCFilter)parent.AddFilter(pp[i]);

            //        parent = filter;
            //        items = (IVCCollection)parent.Items;
            //    }

            //    String fullpath = Path.Combine(fromDir, file);
            //    if (filter == null)
            //        vcProject.AddFile(fullpath);
            //    else
            //        filter.AddFile(fullpath);
            //}

            //sw.Stop();
            //Console.WriteLine(sw.ElapsedMilliseconds);
            //}

            MessageFilter.Revoke();
            //Console.WriteLine();
            //Console.ReadKey();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            Console.WriteLine("Stack trace: " + ex.StackTrace);
            Console.ReadKey();
        }
        finally
        {
            // Need to close solution, so devenv.exe would not remain hanging in memory.
            //if (dte != null)
            //    dte.Solution.Close();
        }
    }