/// <summary> /// This is the main configuration method. Call this in the Constructor of your app. This registers an error handler for unhandled errors. /// </summary> /// <param name="this"></param> /// <param name="appIdentifier">Your unique app id from HockeyApp.</param> /// <returns>Configurable Hockey client. Configure additional settings by calling methods on the returned IHockeyClientConfigurable</returns> public static IHockeyClientConfigurable Configure(this IHockeyClient @this, string appIdentifier) { @this.AsInternal().PlatformHelper = new HockeyPlatformHelper81(); @this.AsInternal().AppIdentifier = appIdentifier; TaskScheduler.UnobservedTaskException += async (sender, e) => { e.SetObserved(); await HockeyClient.Current.AsInternal().HandleExceptionAsync(e.Exception); if (customUnobservedTaskExceptionFunc == null || customUnobservedTaskExceptionFunc(e)) { Application.Current.Exit(); } }; Application.Current.UnhandledException += async (sender, e) => { e.Handled = true; await HockeyClient.Current.AsInternal().HandleExceptionAsync(e.Exception); if (customUnhandledExceptionFunc == null || customUnhandledExceptionFunc(e)) { Application.Current.Exit(); } }; return @this as IHockeyClientConfigurable; }
public static IHockeyClientConfigurable Configure(this IHockeyClient @this, string identifier) { @this.AsInternal().AppIdentifier = identifier; @this.AsInternal().PlatformHelper = new HockeyPlatformHelperWPF(); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException; TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; return (IHockeyClientConfigurable)@this; }
/// <summary> /// Configures the client. /// </summary> /// <param name="this">This object.</param> /// <param name="identifier">Identifier.</param> /// <returns>HockeyClient configurable.</returns> public static IHockeyClientConfigurable Configure(this IHockeyClient @this, string identifier) { @this.AsInternal().AppIdentifier = identifier; @this.AsInternal().PlatformHelper = new HockeyPlatformHelperWPF(); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException; ServiceLocator.AddService<IPlatformService>(new PlatformService()); TelemetryConfiguration.Active.InstrumentationKey = identifier; return (IHockeyClientConfigurable)@this; }
/// <summary> /// This is the main configuration method. Call this in the Constructor of your app. This registers an error handler for unhandled errors. /// </summary> /// <param name="this"></param> /// <param name="appIdentifier">Your unique app id from HockeyApp.</param> /// <param name="endpointAddress">The HTTP address where the telemetry is sent.</param> /// <param name="configuration">Telemetry configuration.</param> /// <returns>Configurable Hockey client. Configure additional settings by calling methods on the returned IHockeyClientConfigurable</returns> public static IHockeyClientConfigurable Configure(this IHockeyClient @this, string appIdentifier, TelemetryConfiguration configuration = null) { @this.AsInternal().PlatformHelper = new HockeyPlatformHelper81(); @this.AsInternal().AppIdentifier = appIdentifier; ServiceLocator.AddService<BaseStorageService>(new StorageService()); ServiceLocator.AddService<IApplicationService>(new ApplicationService()); ServiceLocator.AddService<IDeviceService>(new DeviceService()); ServiceLocator.AddService<Services.IPlatformService>(new PlatformService()); ServiceLocator.AddService<IUnhandledExceptionTelemetryModule>(new UnhandledExceptionTelemetryModule()); WindowsAppInitializer.InitializeAsync(appIdentifier, configuration); return @this as IHockeyClientConfigurable; }
/// <summary> /// Configures HockeyClient. /// </summary> /// <param name="this">HockeyClient object.</param> /// <param name="identifier">Identfier.</param> /// <param name="keepRunningAfterException">Keep running after exception.</param> /// <returns>Instance object.</returns> public static IHockeyClientConfigurable Configure(this IHockeyClient @this, string identifier, bool keepRunningAfterException) { @this.AsInternal().PlatformHelper = new HockeyPlatformHelperWinForms(); @this.AsInternal().AppIdentifier = identifier; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; if (keepRunningAfterException) { Application.ThreadException += Current_ThreadException; Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); } TelemetryConfiguration.Active.InstrumentationKey = identifier; return (IHockeyClientConfigurable)@this; }
public static IHockeyClientConfigurable Configure(this IHockeyClient @this, string identifier, bool keepRunningAfterException) { @this.AsInternal().PlatformHelper = new HockeyPlatformHelperWinForms(); @this.AsInternal().AppIdentifier = identifier; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; if (keepRunningAfterException) { Application.ThreadException += Current_ThreadException; Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); } TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; return (IHockeyClientConfigurable)@this; }
/// <summary> /// main configuration method. call in app constructor /// </summary> /// <param name="this"></param> /// <param name="appId"></param> /// <param name="rootFrame"></param> /// <returns></returns> public static IHockeyClientConfigurable Configure(this IHockeyClient @this, string appId, TelemetryConfiguration telemetryConfiguration = null, Frame rootFrame = null) { @this.AsInternal().PlatformHelper = new HockeyPlatformHelperWP8SL(); @this.AsInternal().AppIdentifier = appId; CrashHandler.Current.Application = Application.Current; ServiceLocator.AddService<BaseStorageService>(new StorageService()); ServiceLocator.AddService<Services.IApplicationService>(new ApplicationService()); ServiceLocator.AddService<Services.IPlatformService>(new PlatformService()); ServiceLocator.AddService<IDeviceService>(new DeviceService()); var exceptionModule = new UnhandledExceptionTelemetryModule(rootFrame); // we need to initialize in Configure method and not in WindowsAppInitializer.InitializeAsync // to prevent UnauthorizedAccessException with Invalid cross-thread access message exceptionModule.Initialize(); ServiceLocator.AddService<IUnhandledExceptionTelemetryModule>(exceptionModule); WindowsAppInitializer.InitializeAsync(appId, telemetryConfiguration); return @this as IHockeyClientConfigurable; }
/// <summary> /// Inititate user identification and define a action to perform when authorization is successfull /// </summary> /// <param name="this">The this.</param> /// <param name="appSecret">The application secret from HockeyApp.</param> /// <param name="successAction">Action to perform when login is successfull</param> /// <param name="eMail">[Optional] E-Mail adress to prefill form</param> /// <param name="tokenValidationPolicy">[Optional] Default is EveryLogin</param> /// <param name="authValidationMode">[Optional] Default is Graceful</param> public static void IdentifyUser(this IHockeyClient @this, string appSecret, Action successAction, string eMail = null, TokenValidationPolicy tokenValidationPolicy = TokenValidationPolicy.EveryLogin, AuthValidationMode authValidationMode = AuthValidationMode.Graceful) { @this.AsInternal().CheckForInitialization(); var authMan = AuthManager.Current; authMan.SuccessAction = successAction; authMan.AuthenticateUser(AuthenticationMode.Identify, tokenValidationPolicy, authValidationMode, eMail, appSecret); }
/// <summary> /// main configuration method. call in app constructor /// </summary> /// <param name="this"></param> /// <param name="appId"></param> /// <param name="rootFrame"></param> /// <returns></returns> public static IHockeyClientConfigurable Configure(this IHockeyClient @this, string appId, Frame rootFrame = null) { @this.AsInternal().PlatformHelper = new HockeyPlatformHelperWP8SL(); @this.AsInternal().AppIdentifier = appId; CrashHandler.Current.Application = Application.Current; CrashHandler.Current.Application.UnhandledException += (sender, args) => { CrashHandler.Current.HandleException(args.ExceptionObject); if (customUnhandledExceptionAction != null) { customUnhandledExceptionAction(args); } }; if (rootFrame != null) { //Idea based on http://www.markermetro.com/2013/01/technical/handling-unhandled-exceptions-with-asyncawait-on-windows-8-and-windows-phone-8/ //catch async void Exceptions AsyncSynchronizationContext.RegisterForFrame(rootFrame, CrashHandler.Current); } return @this as IHockeyClientConfigurable; }
/// <summary> /// Send crashes to the HockeyApp server /// </summary> /// <param name="this"></param> /// <returns></returns> public static async Task<bool> SendCrashesAsync(this IHockeyClient @this) { @this.AsInternal().CheckForInitialization(); bool result = await @this.AsInternal().SendCrashesAndDeleteAfterwardsAsync().ConfigureAwait(false); return result; }
public static async Task<bool> HandleCrashesAsync(this IHockeyClient @this, Boolean sendAutomatically = false) { @this.AsInternal().CheckForInitialization(); return await CrashHandler.Current.HandleCrashesAsync(sendAutomatically).ConfigureAwait(false); }
/// <summary> /// Check for available updates /// </summary> /// <param name="this"></param> /// <param name="settings"><see cref="UpdateCheckSettings"/></param> public static void CheckForUpdates(this IHockeyClient @this, UpdateCheckSettings settings = null) { @this.AsInternal().CheckForInitialization(); UpdateManager.Instance.RunUpdateCheck(settings); }
/// <summary> /// Open the feedback UI /// </summary> /// <param name="this"></param> public static void ShowFeedback(this IHockeyClient @this) { @this.AsInternal().CheckForInitialization(); FeedbackManager.Instance.NavigateToFeedbackUI(); }
/// <summary> /// Identify user with hockeaypp auth. Opening a login page to require valid email address for app if needed /// </summary> /// <param name="this"></param> /// <param name="appSecret">Your app's app secret (see HockeyApp app page)</param> /// <param name="successRedirect">Page-URI to redirect to after successful login</param> /// <param name="navigationService">[optional] obsolete - not needed</param> /// <param name="eMail">[Optional] initial email</param> /// <param name="tokenValidationPolicy"><see cref="TokenValidationPolicy"/></param> /// <param name="authValidationMode"><see cref="AuthValidationMode"/></param> public static void IdentifyUser(this IHockeyClient @this, string appSecret, Uri successRedirect, NavigationService navigationService = null, string eMail = null, TokenValidationPolicy tokenValidationPolicy = TokenValidationPolicy.EveryLogin, AuthValidationMode authValidationMode = AuthValidationMode.Graceful) { @this.AsInternal().CheckForInitialization(); AuthManager.Instance.AuthenticateUser(successRedirect, AuthenticationMode.Identify, tokenValidationPolicy, authValidationMode, eMail, appSecret); }
/// <summary> /// Set the user Id and emal/contact information of the current user if known. This is sent to HockeyApp with crashes. /// </summary> /// <param name="this"></param> /// <param name="user"></param> /// <param name="email"></param> /// <returns></returns> public static IHockeyClient UpdateContactInfo(this IHockeyClient @this, string user, string email) { @this.AsInternal().UserID = user; @this.AsInternal().ContactInformation = email; return @this; }
/// <summary> /// The provided func is called in case of an exception and the returned string is added as additional description of the exception. /// </summary> /// <param name="this"></param> /// <param name="descriptionLoader"></param> /// <returns></returns> public static IHockeyClientConfigurable SetExceptionDescriptionLoader(this IHockeyClientConfigurable @this, Func<Exception, string> descriptionLoader) { @this.AsInternal().DescriptionLoader = descriptionLoader; return @this; }
/// <summary> /// Check for available updates asynchronously. /// </summary> /// <param name="this">The this.</param> /// <param name="autoShowUi">Use the default update dialogs</param> /// <param name="shutdownActions">Callback to gracefully stop your application. If using default-ui, call has to be provided.</param> /// <param name="updateAvailableAction">Callback for available versions, if you want to provide own update dialogs</param> /// <returns></returns> public static async Task<bool> CheckForUpdatesAsync(this IHockeyClient @this, bool autoShowUi, Func<bool> shutdownActions = null, Action<IAppVersion> updateAvailableAction = null) { @this.AsInternal().CheckForInitialization(); //TODO refactor for next version return await HockeyClientWPF.Instance.UpdateManager.CheckForUpdatesAsync(autoShowUi, shutdownActions, updateAvailableAction); }
/// <summary> /// Invoke this method to open the feedback UI where a user can send you a message including image attachments over the HockeyApp feedback system. /// </summary> /// <param name="this"></param> /// <param name="initialUserName">[Optional] Username to prefill the name field</param> /// <param name="initialEMail">[Optional] Email to prefill the email field</param> public static void ShowFeedback(this IHockeyClient @this, string initialUserName = null, string initialEMail = null) { @this.AsInternal().CheckForInitialization(); var flyout = new FeedbackFlyout(); FeedbackManager.Current.InitialEmail = initialEMail; FeedbackManager.Current.InitialUsername = initialUserName; flyout.ShowIndependent(); }
/// <summary> /// Creates a new Feedback-Thread. Thread is stored on the server with the first message. /// </summary> /// <returns></returns> public static IFeedbackThread CreateFeedbackThread(this IHockeyClient @this) { return @this.AsInternal().CreateNewFeedbackThread(); }
/// <summary> /// Opens a Feedback-Thread on the server. /// </summary> /// <param name="this">The this.</param> /// <param name="feedbackToken">A guid which identifies the Feedback-Thread</param> /// <returns> /// The Feedback-Thread or, if not found or delete, null. /// </returns> public static async Task<IFeedbackThread> OpenFeedbackThreadAsync(this IHockeyClient @this,string feedbackToken) { return await @this.AsInternal().OpenFeedbackThreadAsync(feedbackToken); }
/// <summary> /// Send crashes to the HockeyApp server. If crashes are available a messagebox will popoup to ask the user if he wants to send crashes. /// </summary> /// <param name="this"></param> /// <param name="sendAutomatically">if true crashes will be sent without asking</param> /// <returns></returns> public static async Task<bool> SendCrashesAsync(this IHockeyClient @this, Boolean sendAutomatically = false) { @this.AsInternal().CheckForInitialization(); if (sendAutomatically) { return await @this.AsInternal().SendCrashesAndDeleteAfterwardsAsync().ConfigureAwait(false); } else { if (await @this.AsInternal().AnyCrashesAvailableAsync()) { MessageBoxResult result = MessageBox.Show(LocalizedStrings.LocalizedResources.CrashLogQuestion, LocalizedStrings.LocalizedResources.CrashLogMessageBox, MessageBoxButton.YesNo); if (result.Equals(MessageBoxResult.Yes)) { return await @this.AsInternal().SendCrashesAndDeleteAfterwardsAsync().ConfigureAwait(false); } else { await @this.AsInternal().DeleteAllCrashesAsync().ConfigureAwait(false); } } return false; } }
/// <summary> /// Send any collected crashes to the HockeyApp server. You should normally call this during startup of your app. /// </summary> /// <param name="this"></param> /// <param name="sendWithoutAsking">configures if available crashes are sent immediately or if the user should be asked if the crashes should be sent or discarded</param> /// <returns>true if crashes where sent successfully</returns> public static async Task<bool> SendCrashesAsync(this IHockeyClient @this, bool sendWithoutAsking = false) { @this.AsInternal().CheckForInitialization(); return await CrashHandler.Current.HandleCrashesAsync(sendWithoutAsking); }
/// <summary> /// Configures the client with a platform helper /// </summary> /// <param name="this">The this.</param> /// <param name="platformHelper">The platform helper.</param> /// <returns></returns> public static IHockeyClientConfigurable Configure(this IHockeyClient @this, IHockeyPlatformHelper platformHelper) { @this.AsInternal().PlatformHelper = platformHelper; return @this as IHockeyClientConfigurable; }
/// <summary> /// Inititate user authorization and define a page navigate to when authorization is successfull /// </summary> /// <param name="this"></param> /// <param name="pageTypeForSuccessRedirect">Pagetype to navigate when login is successfull</param> /// <param name="eMail">[Optional] E-Mail adress to prefill form</param> /// <param name="tokenValidationPolicy">[Optional] Default is EveryLogin</param> /// <param name="authValidationMode">[Optional] Default is Graceful</param> public static void AuthorizeUser(this IHockeyClient @this, Type pageTypeForSuccessRedirect, string eMail = null, TokenValidationPolicy tokenValidationPolicy = TokenValidationPolicy.EveryLogin, AuthValidationMode authValidationMode = AuthValidationMode.Graceful) { @this.AsInternal().CheckForInitialization(); var authMan = AuthManager.Current; authMan.SuccessRedirectPageType = pageTypeForSuccessRedirect; AuthManager.Current.AuthenticateUser(AuthenticationMode.Authorize, tokenValidationPolicy, authValidationMode, eMail, null); }
/// <summary> /// Use this if you're using an on-premise version of HockeyApp. Default is: https://rink.hockeyapp.net /// </summary> /// <param name="this"></param> /// <param name="hockeyApiDomain"></param> /// <returns></returns> public static IHockeyClientConfigurable SetApiDomain(this IHockeyClientConfigurable @this, string hockeyApiDomain) { @this.AsInternal().ApiDomain = hockeyApiDomain; return @this; }