2010-07-09 7 views
4

Silverlight 응용 프로그램을로드하는 웹 브라우저 컨트롤이 포함 된 WPF 응용 프로그램을 개발 중입니다. 나는 Visual Studio (F5)에서 응용 프로그램을 시작하고 디버거가 실버 코드에 첨부되도록하고 싶습니다. 그러나, 나는 이것에 어떤 운도 가지지 않고 있었다.WPF 응용 프로그램에서 silverlight 디버깅

현재 내가 할 수있는 최선의 방법은 첨부하지 않고 앱을 실행 한 다음 일단 실행되고 나면 디버깅 할 코드 유형으로 Silverlight를 수동으로 프로세스에 연결하면됩니다. (웹 브라우저 컨트롤에서 실버 라이트 앱을로드하게되면 실버 라이트 코드의 중단 점에 도달합니다). 나는이 런칭/부착을 자동화하기 위해 약간의 매크로를 작성했지만 여전히 최선은 아니다.

실버 라이트 앱을 실행/디버깅 할 때 실행할 외부 프로그램으로 WPF 앱을 지정하려고 시도했지만 Visual Studio가 관리되는 .NET 코드를 디버깅하려는 프로세스에 연결됩니다.

아이디어가 있으십니까? 이상적으로는 프로세스에 연결하고 관리되는 .NET 코드와 Silverlight 코드를 모두 디버그하는 것이 좋겠지 만 이것이 가능하지 않다고 생각합니다. 로드시 발생하는 문제를 포함하여 Silverlight 앱으로 모든 문제를 쉽게 디버깅 할 수 있도록 출시 할 때 Silverlight 코드에 자동으로 첨부하고 싶습니다.

+0

당신은 나는 그것이 모든 브라우저가 아닌 경우 디버깅하는 WPF 응용 프로그램으로 가정한다해서 생각, 연결 MS의 기능이나 버그로보고 할 수 있습니다

여기 내 코드입니다. –

답변

1

감사를 두 프로젝트를로드합니다. Brandorf는 내가 가고 싶었던 곳으로 거의 나를 데려다 주지만, 내 SL 응용 프로그램은 스스로 실행할 수 있어야합니다. 난 정말 하나의 애플 리케이션을 가지고 싶어, 모두 SLP 측면 디버깅되고, WPF와 실버 라이트입니다.

내가이 질문을 한 후 오랜 시간이 지났지 만 (사실 내가 여기서 물어 보았다는 사실을 잊어 버렸습니다.), 나는 실제로 내가 정말로 만족하는 해결책을 함께 제시했습니다. 나는 비주얼 스튜디오의 모든 실행중인 인스턴스를 찾기 위해 내 응용 프로그램의 WPF/.NET 측면에서 시각적 스튜디오 자동화를 사용하고 어느 것이 내 exe를 생성했는지 (보통 vcproj/sln 폴더 아래에있는 폴더에 있기 때문에) Visual Studio 자동화를 사용하여 해당 VS를 앱에 연결하고 실버 라이트 코드를 디버깅합니다. 이 작업이 끝나면 실버 라이트 콘텐츠를로드합니다.

정말 잘 작동합니다. 결국 앱이 실행되고 실행될 때마다 디버거가 연결될 수 있습니다 (따라서 디버그 빌드에서만이 코드를 원하거나 꺼져 버릴 수도 있습니다). 따라서 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 
0

어둠 속에서 약간의 장면이지만 실버 라이트 앱이 독자적으로 실행될 수 있다고 가정하면 솔루션 설정에서 Visual Studio를 설정하여 두 앱을 함께 시작해야합니다. 둘 다.

관련 문제