2009-10-05 36 views
13

我想我的應用程序是可分配爲單個exe文件但我希望能夠獲得源代碼行數友好的錯誤報告(應用程序只發送電子郵件exception.ToString()和一些附加信息當發生未處理的異常時)。PDB嵌入到裝配

有沒有什麼辦法可以將.pdb嵌入到程序集中?

回答

8

使用MiniDumps代替「exception.ToString()」。它會給你更多的信息,並不需要.pdb與.exe一起發佈。

有用的鏈接:Post-Mortem Debugging Your Application with Minidumps and Visual Studio .NET

+0

當然,不過你需要保持PDBS的每一個建立你船爲可靠地工作 - 最好設置一個符號服務器內部(見http://msdn.microsoft.com/en-us/library /ms680693(VS.85).aspx) – 2009-10-06 11:27:22

+0

我可以使正在運行的應用程序的minidump?例如,如果我在WinForms中遇到未處理的異常,我將向用戶顯示錯誤對話框,並提供發送錯誤報告和** continue **與應用程序(與終止應用程序相反)的選項。 – 2009-10-06 18:29:53

+0

是的,閱讀鏈接的文章。 – 2009-10-12 13:08:05

3

你可以寫一個存根可執行文件,它包含嵌入的資源,無論是實際的可執行文件和PDB文件。在啓動staub可執行文件時,它將真正的可執行文件和pdb提取到臨時目錄中並啓動它。

就像一些安裝程序或其他應用程序一樣。

雖然我不確定是否值得花費額外的努力。

+0

我也有這個想法。這也讓我能夠將壓縮應用到我的二進制文件,並使得.exe更小。缺點是啓動時間較長。我只希望有一個更簡單的方法來做到這一點。 – 2009-10-06 18:25:51

3

我已經使用了以下AssemblyResolve處理程序,然後嵌入任何程序集的dllpdb。您可以將其設置爲在需要依賴關係之前在應用程序中首先運行的任何東西。

private static void SetupEmbeddedAssemblyResolve() 
    { 
     // Based on http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx 
     AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
     { 
      var name = args.Name; 
      var asmName = new AssemblyName(name); 

      // Any retargetable assembly should be resolved directly using normal load e.g. System.Core issue: 
      // http://stackoverflow.com/questions/18793959/filenotfoundexception-when-trying-to-load-autofac-as-an-embedded-assembly 
      if (name.EndsWith("Retargetable=Yes")) 
      { 
       return Assembly.Load(asmName); 
      } 

      var executingAssembly = Assembly.GetExecutingAssembly(); 
      var resourceNames = executingAssembly.GetManifestResourceNames(); 

      var resourceToFind = asmName.Name + ".dll"; 
      var resourceName = resourceNames.SingleOrDefault(n => n.Contains(resourceToFind)); 

      if (string.IsNullOrWhiteSpace(resourceName)) { return null; } 

      var symbolsToFind = asmName.Name + ".pdb"; 
      var symbolsName = resourceNames.SingleOrDefault(n => n.Contains(symbolsToFind)); 

      var assemblyData = LoadResourceBytes(executingAssembly, resourceName); 

      if (string.IsNullOrWhiteSpace(symbolsName)) 
      { 
       Trace.WriteLine(string.Format("Loading '{0}' as embedded resource '{1}'", resourceToFind, resourceName)); 

       return Assembly.Load(assemblyData); 
      } 
      else 
      { 
       var symbolsData = LoadResourceBytes(executingAssembly, symbolsName); 

       Trace.WriteLine(string.Format("Loading '{0}' as embedded resource '{1}' with symbols '{2}'", resourceToFind, resourceName, symbolsName)); 

       return Assembly.Load(assemblyData, symbolsData); 
      } 
     }; 
    } 

    private static byte[] LoadResourceBytes(Assembly executingAssembly, string resourceName) 
    { 
     using (var stream = executingAssembly.GetManifestResourceStream(resourceName)) 
     { 
      var assemblyData = new Byte[stream.Length]; 

      stream.Read(assemblyData, 0, assemblyData.Length); 

      return assemblyData; 
     } 
    } 
+1

我已經做了一個簡短的博客文章以及:http://www.codingmurmur.com/2014/02/embedded-assembly-loading-with-support.html – nietras 2014-02-18 10:56:58

+0

Woah。我知道你可以用dll文件來做,但是這也適用於pdb文件?整齊。這確實意味着,要使用它將項目製作爲單個文件分發版,您需要將主應用程序放入外部dll項目中。 – Nyerguds 2017-01-02 10:49:52

+0

只有當你不希望主應用程序pdb在exe旁邊。我們可以忍受這一點。 – nietras 2017-01-03 11:25:03