Вставить pdb в сборку
Я хочу, чтобы мое приложение распространялось как один файл .exe, но я хочу получать хорошие отчеты об ошибках с номерами строк исходного кода (приложение просто отправляет электронную почту с помощью exception.ToString()
и некоторой дополнительной информацией при возникновении необработанного исключения).
Есть ли способ встраивать .pdb в сборку?
Ответы
Ответ 1
Используйте MiniDumps вместо "exception.ToString()". Это даст вам гораздо больше информации и не нуждается в .pdb для распространения с помощью .exe.
Полезная ссылка: Post-Mortem Отладка вашего приложения с помощью Minidumps и Visual Studio.NET
Ответ 2
Вы можете написать исполняемый файл заглушки, который содержит встроенные ресурсы, как ваш фактический исполняемый файл, так и его файл pdb. После запуска исполняемого файла staub он извлекает реальный исполняемый файл и pdb во временный каталог и запускает его.
Как и некоторые установщики или другие приложения.
Я не уверен, что это стоит дополнительных усилий.
Ответ 3
Я использовал следующий обработчик 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/info/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;
}
}