2009-10-05 12 views
13

単一の.exeファイルとしてアプリケーションを配布可能にしたいのですが、ソースコードの行番号でエラーレポートを入手したいと考えています(アプリケーションは単にexception.ToString()といくつかの追加情報で電子メールを送信します)。未処理の例外が発生したとき)。アセンブリにpdbを埋め込む

アセンブリに.pdbを埋め込む方法はありますか?

答えて

8

"exception.ToString()"の代わりにMiniDumpsを使用してください。それはあなたにもっと多くの情報を与え、.pdbを.exeで配布する必要はありません。

便利なリンク:Post-Mortem Debugging Your Application with Minidumps and Visual Studio .NET

+0

絶対に、しかし、あなたはそれが確実に動作するためにあなたが出荷構築ごとののPDBを維持する必要がある - (内部的​​に設定するために最善のシンボルサーバーをhttp://msdn.microsoft.com/en-us/libraryを参照してください/ms680693(VS.85).aspx) –

+0

実行中のアプリケーションのミニダンプを作成できますか?たとえば、WinFormsで処理されない例外が発生した場合は、エラー報告を送信し、**アプリケーションを終了する**処理を継続する**オプションを使用して、ユーザーにエラーダイアログを表示します(アプリケーションの終了とは対照的です)。 –

+0

はい、リンクされた記事を読んでください。 –

3

あなたが埋め込まれたリソース、あなたの実際の実行可能ファイルとそのPDBファイルの両方に含まれているスタブ実行可能ファイルを、書くことができます。 staub実行ファイルを起動すると、実際の実行ファイルとpdbが一時ディレクトリに抽出され、起動されます。

インストーラや他のアプリケーションと同じように、

私はそれが余分な努力の価値があるかどうかは分かりません。

+0

私もこの考えがありました。これにより私のバイナリに圧縮を適用し、.exeを小さくすることもできます。欠点は起動時間が長くなることです。私はこれを行う簡単な方法があることを願っています。 –

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

+0

Woah。私はあなたがdllファイルでそれを行うことができると知っていましたが、これもpdbファイルで動作しますか?きちんとしたこれは、これを使ってプロジェクトを単一のファイル配布にするためには、主なアプリケーションを外部のDLLプロジェクトに入れる必要があることを意味します。 – Nyerguds

+0

メインアプリケーションのpdbをexeの隣に置かないようにしたい場合にのみ。私たちはそれで生きることができます。 – nietras

関連する問題