【问题标题】:Debugging silverlight in a WPF app在 WPF 应用程序中调试 silverlight
【发布时间】:2011-03-13 22:26:36
【问题描述】:

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

我目前能做的最好的事情是在不附加的情况下启动应用程序,然后在它启动并运行后,使用 silverlight 作为要调试的指定代码类型手动附加到进程,这样就可以了。 (当我让 Web 浏览器控件加载 silverlight 应用程序时,它会在我的 silverlight 代码中遇到断点)。我编写了一些宏来自动启动/附加,但它仍然不是最好的。

我尝试将 WPF 应用程序指定为在启动/调试 silverlight 应用程序时运行的外部程序,但 Visual Studio 附加到要调试托管 .NET 代码的进程。

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

【问题讨论】:

  • 您可以在 Microsoft connect 上将其报告为功能或错误,我认为这只是因为它假设它是 WPF 应用程序来调试,如果它不是任何浏览器。

标签: wpf silverlight debugging visual-studio-2010


【解决方案1】:

这有点摸不着头脑,但假设您的 silverlight 应用程序能够独立运行,您可以在解决方案设置下将 Visual Studio 设置为同时启动两个应用程序,并且您应该同时连接到这两个应用程序其中。

【讨论】:

    【解决方案2】:

    如果您无法将 Silverlight 项目添加到您的解决方案中(它将自动开始调试),您或许可以利用此技巧。它将同时加载两个项目

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

    【讨论】:

      【解决方案3】:

      感谢您的想法 Brandorf 和 fat。 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 
      

      【讨论】:

        猜你喜欢
        • 2010-12-29
        • 1970-01-01
        • 1970-01-01
        • 2011-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-13
        • 1970-01-01
        相关资源
        最近更新 更多