2009-10-05 20 views
13

Quiero que mi aplicación sea distribuible como solo archivo .exe pero quiero poder obtener buenos informes de errores con los números de línea del código fuente (la aplicación simplemente envía correos electrónicos con exception.ToString() y alguna información adicional cuando ocurre una excepción no controlada).Incrustar pdb en el ensamblado

¿Hay alguna forma de insertar .pdb en el ensamblaje?

Respuesta

8

Use MiniDumps en lugar de "exception.ToString()". Le dará mucha más información y no necesita el .pdb para ser distribuido con el .exe.

Enlace útil: Post-Mortem Debugging Your Application with Minidumps and Visual Studio .NET

+0

Absolutamente, sin embargo es necesario para mantener los PDBs de cada generación se envía para que eso funcione de forma fiable - la mejor manera de configurar un servidor de símbolos internamente (ver http://msdn.microsoft.com/en-us/library /ms680693(VS.85).aspx) –

+0

¿Puedo hacer un minivolcado de una aplicación en ejecución? Por ejemplo, si obtengo una excepción no controlada en WinForms, mostraré un diálogo de error al usuario con una opción para enviar un informe de errores y ** continuar ** trabajando con la aplicación (a diferencia de la aplicación de terminación). –

+0

Sí, lea el artículo vinculado. –

3

se podría escribir un archivo ejecutable de código auxiliar, que contiene como recursos incrustados, tanto el ejecutable real y su archivo PDB. Al iniciar el ejecutable staub, extrae el ejecutable real y el pdb en un directorio temporal y lo inicia.

Como lo hacen algunos instaladores u otras aplicaciones.

No estoy seguro si vale la pena el esfuerzo extra.

+0

También tuve esta idea. Esto también me permitirá aplicar compresión a mis binarios y hacer .exe más pequeño. El inconveniente es un tiempo de arranque más largo. Solo espero que haya una manera más simple de hacer esto. –

3

He utilizado el siguiente controlador AssemblyResolve y luego he incluido dll y pdb de cualquier conjunto. Puede configurar esto como algo que se ejecuta primero en la aplicación antes de que se necesiten dependencias.

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

He hecho una breve publicación en el blog con esto también en: http://www.codingmurmur.com/2014/02/embedded-assembly-loading-with-support.html – nietras

+0

Woah. Sabía que podías hacerlo con archivos dll, pero ¿esto también funciona con archivos pdb? Ordenado. Esto significa que, para usar esto para hacer un proyecto en una distribución de un solo archivo, necesitarías poner tu aplicación principal en un proyecto dll externo. – Nyerguds

+0

Bueno solo si no desea que la aplicación principal pdb esté al lado del exe. Podemos vivir con eso. – nietras

Cuestiones relacionadas