调试Silverlight中的WPF应用程序

调试Silverlight中的WPF应用程序

问题描述:

我正在开发包含加载Silverlight应用程序WebBrowser控件一个WPF应用程序。我希望能够从Visual Studio(F5)启动应用程序,并将调试器附加到silverlight代码。不过,我没有任何运气。调试Silverlight中的WPF应用程序

我目前能做的最好是启动应用程序不附加,那么一旦它运行起来,使用Silverlight作为调试的指定类型的代码手动附加到这个过程中,这一点也适用。 (当我导致Web浏览器控件加载Silverlight应用程序时,它会在我的Silverlight代码中达到断点)。我已经编写了一些宏来实现这个启动/附加的自动化,但它仍然不是最好的。

我已经试过指定WPF应用程序作为外部程序启动/调试Silverlight应用程序时运行,但Visual Studio的重视想要调试托管.NET代码的过程。

任何想法?理想情况下,我真的想附加到进程并调试托管的.NET和Silverlight代码,但我认为这是不可能的。我真的很想在启动时自动附加到Silverlight代码,这样我就可以轻松地调试Silverlight应用程序的所有问题,包括加载时发生的问题。

+0

您可以举报此作为微软的一个功能或者错误连接,我觉得这只是因为它是假设它为WPF应用程序进行调试,如果它不是任何浏览器。 – 2011-07-14 16:51:24

感谢您的想法Brandorf和脂肪。 Brandorf几乎把我带到了我想去的地方,但确实需要我的SL应用程序能够独立运行。我真的希望只有一个应用程序,它是wpf和silverlight,SL端正在调试。

很长一段时间后,我问这个问题(我忘了我曾问在这里),我居然拼凑起来,我很快乐的事情的解决方案。我在我的应用程序的WPF/.NET一侧使用Visual Studio自动化来查找Visual Studio的所有正在运行的实例,找出哪一个产生了我的exe(因为它通常位于vcproj/sln文件夹下面的文件夹中),然后使用Visual Studio自动化将VS附加到应用程序,调试silverlight代码。完成后,我再加载我的silverlight内容。

它工作得很好。你最终会得到一个应用程序,它会在每次运行时发现一个调试器附加到它自己(所以你可能只需要在调试版本中或者某种程度上可以关闭该代码)。所以,只要你想调试silverlight端,你就可以通过Visual Studio的ctrl-F5启动应用程序(无需调试即可启动)。

这里是我的代码:

#if DEBUG 

using System; 
using System.Collections.Generic; 
using System.Collections; 
using System.Runtime.InteropServices; 
using System.IO; 

namespace Launcher 
{ 
    //The core methods in this class to find all running instances of VS are 
    //taken/inspired from 
    //http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx 
    class DebuggingAutomation 
    { 
     [DllImport("ole32.dll")] 
     private static extern int GetRunningObjectTable(int reserved, 
            out UCOMIRunningObjectTable prot); 

     [DllImport("ole32.dll")] 
     private static extern int CreateBindCtx(int reserved, 
             out UCOMIBindCtx ppbc); 
     ///<summary> 
     ///Get a snapshot of the running object table (ROT). 
     ///</summary> 
     ///<returns> 
     ///A hashtable mapping the name of the object 
     ///in the ROT to the corresponding object 
     ///</returns> 
     private static Hashtable GetRunningObjectTable() 
     { 
      Hashtable result = new Hashtable(); 

      int numFetched; 
      UCOMIRunningObjectTable runningObjectTable; 
      UCOMIEnumMoniker monikerEnumerator; 
      UCOMIMoniker[] monikers = new UCOMIMoniker[1]; 

      GetRunningObjectTable(0, out runningObjectTable); 
      runningObjectTable.EnumRunning(out monikerEnumerator); 
      monikerEnumerator.Reset(); 

      while (monikerEnumerator.Next(1, monikers, out numFetched) == 0) 
      { 
       UCOMIBindCtx ctx; 
       CreateBindCtx(0, out ctx); 

       string runningObjectName; 
       monikers[0].GetDisplayName(ctx, null, out runningObjectName); 

       object runningObjectVal; 
       runningObjectTable.GetObject(monikers[0], out runningObjectVal); 

       result[runningObjectName] = runningObjectVal; 
      } 

      return result; 
     } 

     /// <summary> 
     /// Get a table of the currently running instances of the Visual Studio .NET IDE. 
     /// </summary> 
     /// <param name="openSolutionsOnly"> 
     /// Only return instances that have opened a solution 
     /// </param> 
     /// <returns> 
     /// A list of the ides (as DTE objects) present in 
     /// in the running object table to the corresponding DTE object 
     /// </returns> 
     private static List<EnvDTE.DTE> GetIDEInstances(bool openSolutionsOnly) 
     { 
      var runningIDEInstances = new List<EnvDTE.DTE>(); 
      Hashtable runningObjects = GetRunningObjectTable(); 

      IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator(); 
      while (rotEnumerator.MoveNext()) 
      { 
       string candidateName = (string)rotEnumerator.Key; 
       if (!candidateName.StartsWith("!VisualStudio.DTE")) 
        continue; 

       EnvDTE.DTE ide = rotEnumerator.Value as EnvDTE.DTE; 
       if (ide == null) 
        continue; 

       if (openSolutionsOnly) 
       { 
        try 
        { 
         string solutionFile = ide.Solution.FullName; 
         if (!String.IsNullOrEmpty(solutionFile)) 
         { 
          runningIDEInstances.Add(ide); 
         } 
        } 
        catch { } 
       } 
       else 
       { 
        runningIDEInstances.Add(ide); 
       } 
      } 
      return runningIDEInstances; 
     } 

     internal static void AttachDebuggerIfPossible() 
     { 
      if (System.Diagnostics.Debugger.IsAttached) 
      { 
       //Probably debugging host (Desktop .NET side), so don't try to attach to silverlight side 
       return; 
      } 
      var ides = GetIDEInstances(true); 
      var fullPathToAssembly = System.Reflection.Assembly.GetExecutingAssembly().Location; 
      var potentials = new List<EnvDTE.DTE>(); 
      foreach (var ide in ides) 
      { 
       var solutionPath = ide.Solution.FullName; 
       var topLevelSolutionDir = Path.GetDirectoryName(solutionPath); 
       var assemblyName = fullPathToAssembly; 
       if (assemblyName.StartsWith(topLevelSolutionDir, StringComparison.OrdinalIgnoreCase)) 
       { 
        potentials.Add(ide); 
       } 
      } 

      EnvDTE.DTE chosenIde = null; 
      //If you have multiple ides open that can match your exe, you can come up with a scheme to pick a particular one 
      //(eg, put a file like solution.sln.pickme next to the solution whose ide you want to debug). If this is not a 
      //concern, just pick the first match. 
      if (potentials.Count > 0) 
      { 
       chosenIde = potentials[0]; 
      } 
      var dbg = chosenIde != null ? (EnvDTE80.Debugger2)chosenIde.Debugger : null; 

      if (dbg != null) 
      { 
       var trans = dbg.Transports.Item("Default"); 

       var proc = (EnvDTE80.Process2)dbg.GetProcesses(trans, System.Environment.MachineName).Item(Path.GetFileName(fullPathToAssembly)); 
       var engines = new EnvDTE80.Engine[1]; 
       engines[0] = trans.Engines.Item("Silverlight"); 

       proc.Attach2(engines); 
      } 
     } 
    } 
} 
#endif 

这有点在黑暗中拍摄的,但假设你的Silverlight应用程序能够在它自己的运行,你可以在你的解决方案设置,设置Visual Studio来启动这两个应用程序一起,你应附两个都。

如果您不能添加Silverlight项目到解决方案(将自动启动调试),您可能能够使用这个技巧的。这将同时加载这两个项目

http://saraford.net/2008/07/28/did-you-know-you-can-start-debugging-multiple-projects-268/