internal ErrorDialog(ICore core, UnhandledExceptionHandingOptions options, Exception e) { this.core = core; var resourceName = Alt.Resource?.Name ?? "unknown"; Config.WindowTitle = "Exception in \"" + resourceName + "\""; Config.MainInstruction = "Unhandled C# exception"; Config.Content = "There was an unhandled exception in resource \"" + resourceName + "\"."; if (options.ShowExceptionBasicInfo) { if (e == null) { Config.Content += "\r\nException is null."; } else { Config.Content += "\r\n" + e.GetType().FullName + ": " + e.Message; } } if (options.CustomMessage != null) { Config.Content += "\r\n" + options.CustomMessage; } Config.Content += "\r\nThe game will be closed."; if (options.ShowStacktrace) { Config.ExpandedInformation = e?.ToString() ?? "No stacktrace available"; Config.ExpandedControlText = "Show stacktrace"; } Config.CommonButtons = TaskDialogCommonButtonFlags.OK; Config.Flags |= TaskDialogFlags.SizeToContent; if (options.ShowLinkToDocs) { Config.Footer = "<a href=\"docs\">C# module documentation</a>"; Config.FooterIconHandle = new IntPtr(unchecked ((ushort)-3)); Config.Flags |= TaskDialogFlags.EnableHyperlinks; } var buttons = new List <TaskDialogButton>(); if (options.ShowOpenLogsFolderButton) { buttons.Add(new TaskDialogButton(1000, "Open logs folder")); Config.Flags |= TaskDialogFlags.UseCommandLinks; } if (options.ShowCopyStacktraceButton && core.GetPermissionState(Permission.ClipboardAccess) == PermissionState.Allowed) { buttons.Add(new TaskDialogButton(1001, "Copy stacktrace")); Config.Flags |= TaskDialogFlags.UseCommandLinks; } if (buttons.Count > 0) { Buttons = buttons.ToArray(); } // -7 is shield red bar Config.MainIconHandle = new IntPtr(unchecked ((ushort)-7)); Config.StructSize = (uint)Marshal.SizeOf(Config); Config.Callback = (hwnd, msg, wParam, lParam, _) => { Console.WriteLine("got callback " + msg); switch (msg) { case TaskDialogNotification.Created: { Console.WriteLine("sending"); var res = SendMessage(hwnd, TaskDialogMessages.UpdateIcon, new IntPtr((int)TaskDialogIconType.Main), new IntPtr(unchecked ((ushort)-2))); Console.WriteLine("sent " + res); break; } case TaskDialogNotification.HyperlinkClicked: { Process.Start("explorer", "https://docs.altv.mp/cs/articles/index.html"); break; } case TaskDialogNotification.ButtonClicked: { if ((int)wParam == 1000) { unsafe { var size = 0; var path = core.PtrToStringUtf8AndFree(core.Library.Client.Core_GetClientPath(core.NativePointer, &size), size); Process.Start("explorer", Path.Combine(path, "logs")); } } else if ((int)wParam == 1001) { try { core.CopyToClipboard(e == null ? "Exception is null" : e.ToString()); } catch (Exception e) { // ignore } } break; } } return(0); }; }