/// <summary> /// Reports an administrator-correctable fault (a problem that could later cause errors) to the administrators. /// </summary> public static void ReportAdministratorCorrectableFault(string message) { var emailMessage = getFaultEmailMessage(message); emailMessage.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses()); EmailStatics.SendEmailWithDefaultFromAddress(emailMessage); }
/// <summary> /// Reports an administrator-correctable error to the administrators. /// </summary> public static void ReportAdministratorCorrectableError(Exception e) { var emailMessage = getErrorEmailMessage(e.Message); emailMessage.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses()); EmailStatics.SendEmailWithDefaultFromAddress(emailMessage); }
protected override void loadData() { ph.AddControlsReturnThis(new LegacyParagraph("You may report any problems, make suggestions, or ask for help here.")); FormState.ExecuteWithDataModificationsAndDefaultAction( PostBack.CreateFull(firstModificationMethod: modifyData, actionGetter: () => new PostBackAction(new ExternalResourceInfo(info.ReturnUrl))) .ToCollection(), () => { var list = FormItemList.CreateStack(); list.AddFormItems( new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName).ToMailAddress() .ToString() .ToComponents() .ToFormItem(label: "From".ToComponents()), "{0} ({1} for this system)".FormatWith( StringTools.GetEnglishListPhrase(EmailStatics.GetAdministratorEmailAddresses().Select(i => i.DisplayName), true), "support contacts".ToQuantity(EmailStatics.GetAdministratorEmailAddresses().Count(), showQuantityAs: ShowQuantityAs.None)) .ToComponents() .ToFormItem(label: "To".ToComponents()), body.ToTextControl(false, setup: TextControlSetup.Create(numberOfRows: 10), value: "").ToFormItem(label: "Message".ToComponents())); ph.AddControlsReturnThis(list.ToCollection().GetControls()); EwfUiStatics.SetContentFootActions(new ButtonSetup("Send Message").ToCollection()); }); }
/// <summary> /// Sends a notification to the administrators. Do not use for anything that requires corrective action. /// </summary> public static void SendAdministratorNotification(string message) { var emailMessage = getNotificationEmailMessage(message); emailMessage.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses()); EmailStatics.SendEmailWithDefaultFromAddress(emailMessage); }
protected override void loadData() { ph.AddControlsReturnThis(new LegacyParagraph("You may report any problems, make suggestions, or ask for help here.")); var pb = PostBack.CreateFull(firstModificationMethod: modifyData, actionGetter: () => new PostBackAction(new ExternalResourceInfo(info.ReturnUrl))); FormState.ExecuteWithDataModificationsAndDefaultAction( pb.ToCollection(), () => { var table = FormItemBlock.CreateFormItemTable(); table.AddFormItems( FormItem.Create( "From", new PlaceHolder().AddControlsReturnThis( new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName).ToMailAddress().ToString().ToComponents().GetControls())), FormItem.Create( "To", new PlaceHolder().AddControlsReturnThis( "{0} ({1} for this system)".FormatWith( StringTools.GetEnglishListPhrase(EmailStatics.GetAdministratorEmailAddresses().Select(i => i.DisplayName), true), "support contacts".ToQuantity(EmailStatics.GetAdministratorEmailAddresses().Count(), showQuantityAs: ShowQuantityAs.None)) .ToComponents() .GetControls())), FormItem.Create( "Message", new EwfTextBox("", rows: 10), validationGetter: control => new EwfValidation( (pbv, validator) => body.Value = validator.GetString(new ValidationErrorHandler("message"), control.GetPostBackValue(pbv), false)))); ph.AddControlsReturnThis(table); }); EwfUiStatics.SetContentFootActions(new ActionButtonSetup("Send Message", new PostBackButton(pb))); }
private void tick(object state) { TelemetryStatics.ExecuteBlockWithStandardExceptionHandling( () => { // We need to schedule the next tick even if there is an exception thrown in this one. Use try-finally instead of CallEveryMethod so we don't lose // exception stack traces. try { var currentInstant = SystemClock.Instance.GetCurrentInstant(); var interval = new TickInterval(new Interval(lastTickInstant, currentInstant)); lastTickInstant = currentInstant; if (ConfigurationStatics.IsLiveInstallation && interval.FitsPattern(OperationRecurrencePattern.CreateDaily(0, 0))) { EmailStatics.SendHealthCheckEmail(WindowsServiceMethods.GetServiceInstalledName(service)); } service.Tick(interval); } finally { try { timer.Change(tickInterval, Timeout.Infinite); } catch (ObjectDisposedException) { // This should not be necessary with the Timer.Dispose overload we are using, but see http://stackoverflow.com/q/12354883/35349. } } }); }
private void tick(object state) { TelemetryStatics.ExecuteBlockWithStandardExceptionHandling( () => { // We need to schedule the next tick even if there is an exception thrown in this one. Use try-finally instead of CallEveryMethod so we don't lose // exception stack traces. try { var now = DateTime.Now; if (ConfigurationStatics.IsLiveInstallation && !ConfigurationStatics.MachineIsStandbyServer && new[] { lastHealthCheckDateAndTime, now }.Any(dt => dt.Date.IsBetweenDateTimes(lastHealthCheckDateAndTime, now))) { EmailStatics.SendHealthCheckEmail(WindowsServiceMethods.GetServiceInstalledName(service)); } lastHealthCheckDateAndTime = now; service.Tick(); } finally { try { timer.Change(tickInterval, Timeout.Infinite); } catch (ObjectDisposedException) { // This should not be necessary with the Timer.Dispose overload we are using, but see http://stackoverflow.com/q/12354883/35349. } } }); }
/// <summary> /// After setting the From property to the from address specified in the config file, sends the specified mail message using the SMTP server specified in /// the config file. /// </summary> public static void SendEmailWithDefaultFromAddress(EmailMessage m) { assertClassInitialized(); m.From = new EmailAddress( ConfigurationStatics.SystemGeneralProvider.EmailDefaultFromAddress, ConfigurationStatics.SystemGeneralProvider.EmailDefaultFromName); EmailStatics.SendEmail(m); }
private void modifyData() { var message = new EmailMessage { Subject = "Contact from " + AppTools.SystemName, BodyHtml = ("Contact from " + AppTools.User.Email + Environment.NewLine + Environment.NewLine + emailText).GetTextAsEncodedHtml() }; message.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses()); message.ReplyToAddresses.Add(new EmailAddress(AppTools.User.Email)); EmailStatics.SendEmailWithDefaultFromAddress(message); AddStatusMessage(StatusMessageType.Info, "Your feedback has been sent."); }
internal static void SendPassword(string emailAddress, string password) { string subject; string bodyHtml; SystemProvider.GetPasswordResetParams(emailAddress, password, out subject, out bodyHtml); var m = new EmailMessage { Subject = subject, BodyHtml = bodyHtml }; m.ToAddresses.Add(new EmailAddress(emailAddress)); EmailStatics.SendEmailWithDefaultFromAddress(m); }
private void modifyData() { var message = new EmailMessage { From = new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName), Subject = "Contact from " + ConfigurationStatics.SystemName, BodyHtml = body.Value.GetTextAsEncodedHtml() }; message.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses()); EmailStatics.SendEmail(message); AddStatusMessage(StatusMessageType.Info, "Your message has been sent."); }
internal static void SendHealthCheckEmail(string appFullName) { var message = new EmailMessage(); var body = new StringBuilder(); var tenGibibytes = 10 * Math.Pow(1024, 3); var freeSpaceIsLow = false; foreach (var driveInfo in DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.Fixed)) { var bytesFree = driveInfo.TotalFreeSpace; freeSpaceIsLow = freeSpaceIsLow || bytesFree < tenGibibytes; body.AppendLine("{0} free on {1} drive.".FormatWith(FormattingMethods.GetFormattedBytes(bytesFree), driveInfo.Name)); } message.Subject = StringTools.ConcatenateWithDelimiter(" ", "Health check", freeSpaceIsLow ? "and WARNING" : "", "from " + appFullName); message.BodyHtml = body.ToString().GetTextAsEncodedHtml(); EmailStatics.SendDeveloperNotificationEmail(message); }
protected override PageContent getContent() { var body = new DataValue <string>(); return(FormState.ExecuteWithDataModificationsAndDefaultAction( PostBack.CreateFull( modificationMethod: () => { var message = new EmailMessage { Subject = "Support request from {0} in {1}".FormatWith( AppTools.User.FriendlyName.Any() ? AppTools.User.FriendlyName : AppTools.User.Email, ConfigurationStatics.SystemDisplayName), BodyHtml = body.Value.GetTextAsEncodedHtml() }; message.ReplyToAddresses.Add(new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName)); message.ToAddresses.AddRange(EmailStatics.GetAdministratorEmailAddresses()); EmailStatics.SendEmailWithDefaultFromAddress(message); AddStatusMessage(StatusMessageType.Info, "Your message has been sent."); }, actionGetter: () => new PostBackAction(new ExternalResource(ReturnUrl))) .ToCollection(), () => new UiPageContent(contentFootActions: new ButtonSetup("Send Message").ToCollection()) .Add(new Paragraph("You may report any problems, make suggestions, or ask for help here.".ToComponents())) .Add( FormItemList.CreateStack( items: new EmailAddress(AppTools.User.Email, AppTools.User.FriendlyName).ToMailAddress() .ToString() .ToComponents() .ToFormItem(label: "From".ToComponents()) .Append( "{0} ({1} for this system)".FormatWith( StringTools.GetEnglishListPhrase(EmailStatics.GetAdministratorEmailAddresses().Select(i => i.DisplayName), true), "support contacts".ToQuantity(EmailStatics.GetAdministratorEmailAddresses().Count(), showQuantityAs: ShowQuantityAs.None)) .ToComponents() .ToFormItem(label: "To".ToComponents())) .Append( body.ToTextControl(false, setup: TextControlSetup.Create(numberOfRows: 10), value: "").ToFormItem(label: "Message".ToComponents())) .Materialize())))); }
/// <summary> /// Initializes the system. This includes loading application settings from the configuration file. The application name should be scoped within the system. /// For non web applications, this method must be called directly from the main executable assembly and not from a supporting library. /// /// To debug this method, create a folder called C:\AnyoneFullControl and give Everyone full control. A file will appear in that folder explaining how far /// it got in init. /// </summary> /// <param name="globalInitializer">The system's global initializer. Do not pass null.</param> /// <param name="appName"></param> /// <param name="isClientSideApp"></param> /// <param name="assemblyFolderPath">Pass a nonempty string to override the assembly folder path, which is used to locate the installation folder. Use with /// caution.</param> /// <param name="mainDataAccessStateGetter">A method that returns the current main data-access state whenever it is requested, including during this /// InitStatics call. Do not allow multiple threads to use the same state at the same time. If you pass null, the data-access subsystem will not be /// available in the application.</param> /// <param name="useLongDatabaseTimeouts">Pass true if the application is a background process that can tolerate slow database access.</param> public static void InitStatics( SystemInitializer globalInitializer, string appName, bool isClientSideApp, string assemblyFolderPath = "", Func <DataAccessState> mainDataAccessStateGetter = null, bool useLongDatabaseTimeouts = false) { var initializationLog = "Starting init"; try { if (initialized) { throw new ApplicationException("This class can only be initialized once."); } if (globalInitializer == null) { throw new ApplicationException("The system must have a global initializer."); } // Initialize these before the exception handling block below because it's reasonable for the exception handling to depend on them. ConfigurationStatics.Init(assemblyFolderPath, globalInitializer.GetType(), appName, isClientSideApp, ref initializationLog); EmailStatics.Init(); TelemetryStatics.Init(); // Setting the initialized flag to true must be done before executing the secondary init block below so that exception handling works. initialized = true; initializationLog += Environment.NewLine + "Succeeded in primary init."; } catch (Exception e) { initializationLog += Environment.NewLine + e; EwlStatics.EmergencyLog("Initialization log", initializationLog); throw; } try { CultureInfo.DefaultThreadCurrentCulture = Cultures.EnglishUnitedStates; var asposePdfLicensePath = EwlStatics.CombinePaths(ConfigurationStatics.InstallationConfiguration.AsposeLicenseFolderPath, "Aspose.PDF.lic"); if (File.Exists(asposePdfLicensePath)) { new Aspose.Pdf.License().SetLicense(asposePdfLicensePath); } var asposeWordsLicensePath = EwlStatics.CombinePaths(ConfigurationStatics.InstallationConfiguration.AsposeLicenseFolderPath, "Aspose.Words.lic"); if (File.Exists(asposeWordsLicensePath)) { new Aspose.Words.License().SetLicense(asposeWordsLicensePath); } AppMemoryCache.Init(); BlobStorageStatics.Init(); DataAccessStatics.Init(); DataAccessState.Init(mainDataAccessStateGetter, useLongDatabaseTimeouts); EncryptionOps.Init(); HtmlBlockStatics.Init(); UserManagementStatics.Init(); GlobalInitializationOps.globalInitializer = globalInitializer; globalInitializer.InitStatics(); } catch (Exception e) { secondaryInitFailed = true; // Suppress all exceptions since they would prevent apps from knowing that primary initialization succeeded. EWF apps need to know this in order to // automatically restart themselves. Other apps could find this knowledge useful as well. try { TelemetryStatics.ReportError("An exception occurred during application initialization:", e); } catch {} } }
public static void SendEmailWithDefaultFromAddress(EmailMessage m) { assertClassInitialized(); EmailStatics.SendEmailWithDefaultFromAddress(m); }
/// <summary> /// Standard library use only. /// </summary> public void SendHealthCheck() { EmailStatics.SendHealthCheckEmail(ConfigurationStatics.InstallationConfiguration.FullShortName + " - " + ConfigurationStatics.AppName); }
/// <summary> /// Reports an error to the developers. The report includes the specified exception and additional information about the running program. The prefix /// provides additional information before the standard exception and page information. /// </summary> public static void ReportError(string prefix, Exception exception) { using (var sw = new StringWriter()) { if (prefix.Length > 0) { sw.WriteLine(prefix); sw.WriteLine(); } if (exception != null) { sw.WriteLine(exception.ToString()); sw.WriteLine(); } sw.WriteLine("Application: {0}".FormatWith(ConfigurationStatics.AppName)); sw.WriteLine("Version: {0}".FormatWith(ConfigurationStatics.AppAssembly.GetName().Version)); if (!ConfigurationStatics.IsDevelopmentInstallation) { sw.WriteLine(); sw.WriteLine("Installation: {0}".FormatWith(ConfigurationStatics.InstallationConfiguration.InstallationName)); sw.WriteLine("Machine: {0}".FormatWith(Tewl.Tools.NetTools.GetLocalHostName())); } if (NetTools.IsWebApp()) { // This check ensures that there is an actual request, which is not the case during application initialization. if (EwfApp.Instance != null && EwfApp.Instance.RequestState != null) { sw.WriteLine(); sw.WriteLine("URL: " + AppRequestState.Instance.Url); sw.WriteLine(); foreach (string fieldName in HttpContext.Current.Request.Form) { sw.WriteLine("Form field " + fieldName + ": " + HttpContext.Current.Request.Form[fieldName]); } sw.WriteLine(); foreach (string cookieName in HttpContext.Current.Request.Cookies) { sw.WriteLine("Cookie " + cookieName + ": " + HttpContext.Current.Request.Cookies[cookieName].Value); } sw.WriteLine(); sw.WriteLine("User agent: " + HttpContext.Current.Request.GetUserAgent()); sw.WriteLine("Referrer: " + NetTools.ReferringUrl); User user = null; User impersonator = null; // exception-prone code try { user = AppTools.User; impersonator = AppRequestState.Instance.ImpersonatorExists ? AppRequestState.Instance.ImpersonatorUser : null; } catch {} if (user != null) { sw.WriteLine("User: {0}{1}".FormatWith(user.Email, impersonator != null ? " (impersonated by {0})".FormatWith(impersonator.Email) : "")); } } } EwlStatics.CallEveryMethod( () => { lock ( errorEmailLimiter ) { errorEmailLimiter.RequestAction( () => EmailStatics.SendDeveloperNotificationEmail(getErrorEmailMessage(sw.ToString())), () => SendDeveloperNotification( "An error occurred and the email rate-limit was reached! See the log file for this and any other errors that may occur in the near future."), () => {}); } }, () => logError(sw.ToString())); } }
/// <summary> /// Reports an error to the developers. The report includes the specified exception and additional information about the running program. The prefix /// provides additional information before the standard exception and page information. /// </summary> public static void ReportError(string prefix, Exception exception) { using (var sw = new StringWriter()) { if (prefix.Length > 0) { sw.WriteLine(prefix); sw.WriteLine(); } if (exception != null) { sw.WriteLine(exception.ToString()); sw.WriteLine(); } if (NetTools.IsWebApp()) { // This check ensures that there is an actual request, which is not the case during application initialization. if (EwfApp.Instance != null && EwfApp.Instance.RequestState != null) { sw.WriteLine("URL: " + AppRequestState.Instance.Url); sw.WriteLine(); foreach (string fieldName in HttpContext.Current.Request.Form) { sw.WriteLine("Form field " + fieldName + ": " + HttpContext.Current.Request.Form[fieldName]); } sw.WriteLine(); foreach (string cookieName in HttpContext.Current.Request.Cookies) { sw.WriteLine("Cookie " + cookieName + ": " + HttpContext.Current.Request.Cookies[cookieName].Value); } sw.WriteLine(); sw.WriteLine("User agent: " + HttpContext.Current.Request.GetUserAgent()); sw.WriteLine("Referrer: " + NetTools.ReferringUrl); User user = null; User impersonator = null; // exception-prone code try { user = AppTools.User; impersonator = AppRequestState.Instance.ImpersonatorExists ? AppRequestState.Instance.ImpersonatorUser : null; } catch {} if (user != null) { sw.WriteLine("User: {0}{1}".FormatWith(user.Email, impersonator != null ? " (impersonated by {0})".FormatWith(impersonator.Email) : "")); } } } else { sw.WriteLine("Program: " + ConfigurationStatics.AppName); sw.WriteLine("Version: " + ConfigurationStatics.AppAssembly.GetName().Version); sw.WriteLine("Machine: " + StandardLibraryMethods.GetLocalHostName()); } StandardLibraryMethods.CallEveryMethod( delegate { EmailStatics.SendDeveloperNotificationEmail(getErrorEmailMessage(sw.ToString())); }, delegate { logError(sw.ToString()); }); } }
/// <summary> /// Initializes the system. This includes loading application settings from the configuration file. The application name should be scoped within the system. /// For non web applications, this method must be called directly from the main executable assembly and not from a supporting library. /// /// To debug this method, create a folder called C:\AnyoneFullControl and give Everyone full control. A file will appear in that folder explaining how far /// it got in init. /// </summary> /// <param name="globalInitializer">The system's global initializer. Do not pass null.</param> /// <param name="appName"></param> /// <param name="isClientSideProgram"></param> /// <param name="useRelativeInstallationPath">Pass true to use a relative path for the installation folder. This means that the folder will be located using /// the working directory rather than the assembly path. Use with caution.</param> /// <param name="mainDataAccessStateGetter">A method that returns the current main data-access state whenever it is requested, including during this /// InitStatics call. Do not allow multiple threads to use the same state at the same time. If you pass null, the data-access subsystem will not be /// available in the application.</param> public static void InitStatics( SystemInitializer globalInitializer, string appName, bool isClientSideProgram, bool useRelativeInstallationPath = false, Func <DataAccessState> mainDataAccessStateGetter = null) { var initializationLog = "Starting init"; try { if (initialized) { throw new ApplicationException("This class can only be initialized once."); } if (globalInitializer == null) { throw new ApplicationException("The system must have a global initializer."); } // Initialize ConfigurationStatics, including the general provider, before the exception handling block below because it's reasonable for the exception // handling to depend on this. ConfigurationStatics.Init(useRelativeInstallationPath, globalInitializer.GetType(), appName, isClientSideProgram, ref initializationLog); // Setting the initialized flag to true must be done before executing the secondary init block below so that exception handling works. initialized = true; initializationLog += Environment.NewLine + "Succeeded in primary init."; } catch (Exception e) { initializationLog += Environment.NewLine + e; EwlStatics.EmergencyLog("Initialization log", initializationLog); throw; } try { var asposeLicense = ConfigurationStatics.SystemGeneralProvider.AsposeLicenseName; if (asposeLicense.Any()) { new Aspose.Pdf.License().SetLicense(asposeLicense); new Aspose.Words.License().SetLicense(asposeLicense); } AppMemoryCache.Init(); BlobFileOps.Init(); DataAccessStatics.Init(); DataAccessState.Init(mainDataAccessStateGetter); EmailStatics.Init(); EncryptionOps.Init(); HtmlBlockStatics.Init(); InstallationSupportUtility.ConfigurationLogic.Init1(); UserManagementStatics.Init(); GlobalInitializationOps.globalInitializer = globalInitializer; globalInitializer.InitStatics(); } catch (Exception e) { secondaryInitFailed = true; // Suppress all exceptions since they would prevent apps from knowing that primary initialization succeeded. EWF apps need to know this in order to // automatically restart themselves. Other apps could find this knowledge useful as well. try { TelemetryStatics.ReportError("An exception occurred during application initialization:", e); } catch {} } }
/// <summary> /// Sends a notification to the developers. Do not use for anything that requires corrective action. /// </summary> public static void SendDeveloperNotification(string message) { EmailStatics.SendDeveloperNotificationEmail(getNotificationEmailMessage(message)); }
/// <summary> /// Reports a fault (a problem that could later cause errors) to the developers. /// </summary> public static void ReportFault(string message) { EmailStatics.SendDeveloperNotificationEmail(getFaultEmailMessage(message)); }
public static void SendEmail(EmailMessage message) { assertClassInitialized(); EmailStatics.SendEmail(message); }