15

我希望我的应用程序可以作为单个 .exe 文件分发,但我希望能够获得带有源代码行号的漂亮错误报告(exception.ToString()当发生未处理的异常时,应用程序只需发送电子邮件和一些附加信息)。

有没有办法将 .pdb 嵌入到程序集中?

4

3 回答 3

8

使用 MiniDumps 而不是“exception.ToString()”。它将为您提供更多信息,并且不需要将 .pdb 与 .exe 一起分发。

有用的链接:使用 Minidumps 和 Visual Studio .NET 对您的应用程序进行事后调试

于 2009-10-05T07:15:12.453 回答
5

我使用了以下AssemblyResolve处理程序,然后嵌入了dll任何pdb程序集。您可以将其设置为在需要依赖项之前在应用程序中首先运行的任何内容。

    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;
        }
    }
于 2014-02-18T10:12:28.590 回答
3

您可以编写一个存根可执行文件,其中包含作为嵌入式资源的实际可执行文件及其 pdb 文件。启动 staub 可执行文件后,它将真正的可执行文件和 pdb 提取到一个临时目录中并启动它。

就像某些安装程序或其他应用程序一样。

我不确定是否值得付出额外的努力。

于 2009-10-06T11:25:17.167 回答