public IAsyncOperation <NiconicoSignInStatus> SignIn(string mailOrTelephone, string password) { return(AsyncInfo.Run <NiconicoSignInStatus>(async(cancelToken) => { if (!Util.InternetConnection.IsInternet()) { NiconicoContext?.Dispose(); NiconicoContext = new NiconicoContext(); return NiconicoSignInStatus.Failed; } if (NiconicoContext != null && NiconicoContext.AuthenticationToken?.MailOrTelephone == mailOrTelephone && NiconicoContext.AuthenticationToken?.Password == password) { return NiconicoSignInStatus.Success; } await SignOut(); try { await _SigninLock.WaitAsync(); var context = new NiconicoContext(new NiconicoAuthenticationToken(mailOrTelephone, password)); context.AdditionalUserAgent = HohoemaUserAgent; LoginErrorText = ""; Debug.WriteLine("try login"); NiconicoSignInStatus result = NiconicoSignInStatus.Failed; try { result = await context.SignInAsync(); } catch { LoginErrorText = "サインインに失敗、再起動をお試しください"; } UpdateServiceStatus(result); NiconicoContext = context; if (result == NiconicoSignInStatus.Success) { Debug.WriteLine("login success"); using (var loginActivityLogger = LoggingChannel.StartActivity("login process")) { loginActivityLogger.LogEvent("begin login process."); var fields = new LoggingFields(); await Task.Delay(500); try { loginActivityLogger.LogEvent("getting UserInfo."); var userInfo = await NiconicoContext.User.GetInfoAsync(); LoginUserId = userInfo.Id; IsPremiumUser = userInfo.IsPremium; { try { var user = await NiconicoContext.User.GetUserDetail(LoginUserId.ToString()); LoginUserName = user.Nickname; UserIconUrl = user.ThumbnailUri; OnPropertyChanged(nameof(LoginUserName)); OnPropertyChanged(nameof(UserIconUrl)); } catch (Exception ex) { throw new Exception("ユーザー名取得のフォールバック処理に失敗 + " + LoginUserId, ex); } } fields.AddString("user id", LoginUserId.ToString()); fields.AddString("user name", LoginUserName); fields.AddBoolean("is premium", IsPremiumUser); loginActivityLogger.LogEvent("[Success]:get UserInfo.", fields, LoggingLevel.Information); } catch (Exception ex) { LoginErrorText = $"ユーザー情報の取得に失敗しました。再起動をお試しください。({ex.Message})"; fields.AddString("mail", mailOrTelephone); loginActivityLogger.LogEvent(LoginErrorText, fields, LoggingLevel.Warning); NiconicoContext.Dispose(); NiconicoContext = new NiconicoContext(); return NiconicoSignInStatus.Failed; } fields.Clear(); Debug.WriteLine("user id is : " + LoginUserId); // 0.4.0以前のバージョンからのログインユーザー情報の移行処理 try { await MigrateLegacyUserSettings(LoginUserId.ToString()); } catch { LoginErrorText = "ユーザー設定の過去バージョンとの統合処理に失敗しました。"; return NiconicoSignInStatus.Failed; } try { Debug.WriteLine("initilize: fav"); loginActivityLogger.LogEvent("initialize user favorite"); FollowManager = await FollowManager.Create(this, LoginUserId); } catch { LoginErrorText = "お気に入り情報の取得に失敗しました。再起動をお試しください。"; Debug.WriteLine(LoginErrorText); loginActivityLogger.LogEvent(LoginErrorText, fields, LoggingLevel.Error); NiconicoContext.Dispose(); NiconicoContext = new NiconicoContext(); return NiconicoSignInStatus.Failed; } FollowManagerUpdater = BackgroundUpdater.RegistrationBackgroundUpdateScheduleHandler( FollowManager, "FollowManager", label: "フォロー" ); Debug.WriteLine("Login done."); loginActivityLogger.LogEvent("[Success]: Login done"); } // BG更新をスケジュール UpdateAllComponent(); // 動画のキャッシュフォルダの選択状態をチェック await(App.Current as App).CheckVideoCacheFolderState(); // サインイン完了 OnSignin?.Invoke(); // TODO: 途中だった動画のダウンロードを再開 // await MediaManager.StartBackgroundDownload(); // ニコニコサービスの裏で取得させたいので強制的に待ちを挟む await Task.Delay(1000); } else { Debug.WriteLine("login failed"); NiconicoContext?.Dispose(); NiconicoContext = null; } return result; } finally { _SigninLock.Release(); } })); }
/// <summary> /// This method demonstrates the LoggingChannel and LoggingActivity APIs. /// </summary> /// <param name="channel"> /// The channel to use for the demonstration. This channel may have been /// constructed using a Windows 8.1 constructor or a Windows 10 constructor. /// The same APIs are supported in both cases, but the ETL events will be /// formatted a bit differently depending on how the channel was constructed. /// </param> private void DemonstrateLogging(LoggingChannel channel) { // Whenever any ETW session changes the way it is listening to this // channel, the LoggingEnable event is fired. For example, this might // be called when a session begins listening, changes the level at // which it is listening, or stops listening. channel.LoggingEnabled += this.OnLoggingEnabled; // Log simple string events channel.LogMessage("Simple message"); // default level is Verbose channel.LogMessage("Simple error", LoggingLevel.Error); // Log simple string + integer events. channel.LogValuePair("Simple message", 123); // default level is Verbose channel.LogValuePair("Simple error", 456, LoggingLevel.Error); // The channel.Name property returns the name that was used when the // channel was constructed. When running in Windows 10 mode, the name // is already set as the provider name, so no LoggingChannelName is // automatically added to the event. channel.LogMessage(channel.Name); // The channel.Id property is new to Windows 10. channel.LogMessage(channel.Id.ToString()); // If you want to avoid the overhead of collecting data when nobody is // listening to your channel, check the Enabled property before logging. if (channel.Enabled) { channel.LogMessage(this.CollectExpensiveData()); } // The IsEnabled() method is exactly the same as the Enabled property, // except that it is a new Windows 10 API. if (channel.IsEnabled()) { channel.LogMessage(this.CollectExpensiveData()); } // If you want to only collect data if somebody is listening at a specific // level, you need to check both Enabled and Level. Note that the value of // the Level is unspecified when Enabled is false. if (channel.Enabled && channel.Level <= LoggingLevel.Warning) { channel.LogMessage(this.CollectExpensiveData(), LoggingLevel.Warning); } // The IsEnabled(LoggingLevel) method is a bit nicer than checking both // Enabled and Level, but it is only available on Windows 10 or later. if (channel.IsEnabled(LoggingLevel.Warning)) { channel.LogMessage(this.CollectExpensiveData(), LoggingLevel.Warning); } // You can also use IsEnabled to check for keywords. if (channel.IsEnabled(LoggingLevel.Information, 0x10)) { channel.LogMessage(this.CollectExpensiveData(), LoggingLevel.Information); } // Use LoggingFields with the LogEvent method to write complex events. var fields = new LoggingFields(); fields.AddDouble("pi", 3.14159); channel.LogEvent( "ComplexEvent", fields, LoggingLevel.Verbose, new LoggingOptions(0x10)); // Keywords = 0x10 // You can add any number of name-value pairs to a fields object, though // you may encounter ETW limitations if you add too many. For example, // ETW is limited to a maximum event size of 64KB, and the current // TraceLogging decoder can handle no more than 128 fields. // Performance optimization: You can reuse a LoggingFields object to // avoid unnecessary allocations. Don't forget to call Clear() // between uses, and don't try to share a LoggingFields object between // threads. fields.Clear(); fields.AddDateTime("Date", DateTimeOffset.Now); channel.LogEvent("Now", fields); fields.Clear(); // You can add a formatting hint to affect the way a value is decoded. // Not all combinations are useful, and the hint may be ignored. // For example, you can encode an MBCS string by writing a byte array // with a String hint. fields.AddUInt8Array( "AnsiString", new byte[] { 65, 66, 67, 49, 50, 51 }, // "ABC123" LoggingFieldFormat.String); // You can add "tag" bits to a field. These are user-defined bits that // can be used to communicate with an event processing tool. For example, // you might define a tag bit to indicate that a field contains private // data that should not be displayed on-screen. fields.AddString("Password", "12345", LoggingFieldFormat.Default, 0x10); // You can add a "structure" to an event. A structure is a name for a // group of fields. Structures can nest. Call BeginStruct to add a level // of nesting, and call EndStruct after the last field of the structure. fields.BeginStruct("Nested"); fields.AddInt16("Nested-1", 1); fields.AddInt16("Nested-2", 2); fields.BeginStruct("Nested-Nested"); fields.AddInt16("Nested-Nested-3", 3); fields.EndStruct(); fields.AddInt16("Nested-4", 4); fields.EndStruct(); // Advanced scenarios: you can use a LoggingOptions object to control // detailed event settings such as keywords, opcodes, and activity Ids. // These have their normal ETW semantics. You can also set event tags, // which are bit values that can be used to communicate with the event // processor. channel.LogEvent( "VeryComplexEvent", fields, LoggingLevel.Information, new LoggingOptions { Keywords = 0x123, Tags = 0x10 }); // Windows 10 introduces the ILoggingTarget interface. LoggingChannel // implements this interface. This interface allows components to accept // a logger as an parameter. this.DoSomething(channel); /* * If a LoggingActivity is created using a LoggingActivity constructor, * it will use Windows 8.1 semantics: * * - If an activity is destroyed (garbage-collected) without being closed * and the associated LoggingChannel is still open, the activity will * write a default Stop event. * - The default Stop event (written by the destructor or by the Close() * method) is encoded as a "simple" event. * * The 8.1 semantics are deprecated because the automatic generation of * a Stop event at garbage-collection can be misleading. The Stop event * is intended to mark the a precise point at which an activity is * completed, while the garbage-collection of an abandoned activity is * inherently imprecise and unpredictable. * * If a LoggingActivity is created using a StartActivity method, it will * use Windows 10 semantics: * * - If an activity is destroyed (garbage-collected) without being closed, * there will be no Stop event for the activity. * - The default Stop event (written by the Close() method) is encoded as * a TraceLogging event with name "ActivityClosed". */ // This activity is created with Windows 8.1 semantics. using (var a1 = new LoggingActivity("Activity1", channel)) { // The activity Start event is written by the LoggingActivity constructor. // You would do your activity's work here. // The activity Stop event is written when the activity is closed (disposed). // The Windows 10 LoggingActivity adds new methods for writing events // that are marked as associated with the activity. a1.LogEvent("Activity event"); // LoggingActivity also implements the ILoggingTarget interface, so you can // use either a channel or an activity as a logging target. this.DoSomething(a1); // The Windows 10 LoggingActivity adds new methods for creating nested activities. // Note that nested activities are always created with Windows 10 semantics, // even when nested under an activity that is using Windows 8.1 semantics. using (var a2 = a1.StartActivity("Activity2")) { // Nested task occurs here. // The Windows 10 LoggingActivity allows you to customize the Stop event. a2.StopActivity("Activity 2 stop"); } // Because a1 is using Windows 8.1 semantics, if we did not call Dispose(), // it would attempt to write a Stop event when it is garbage collected. // Writing Stop events during garbage collection is not useful, so be sure // to properly stop, close, or dispose activities. } // The Windows 10 StartActivity method creates a new activity, optionally with // specified fields and characteristics. // This activity is created with Windows 10 semantics. using (var a3 = channel.StartActivity("Activity3")) { // Because a3 is using Windows 10 semantics, if we did not call Dispose(), // there would be no Stop event (not even when the activity is garbage // collected). To get a Stop event, be sure to stop, close, or dispose the // activity. } }
/// <summary> /// This method demonstrates the LoggingChannel and LoggingActivity APIs. /// </summary> /// <param name="channel"> /// The channel to use for the demonstration. This channel may have been /// constructed using a Windows 8.1 constructor or a Windows 10 constructor. /// The same APIs are supported in both cases, but the ETL events will be /// formatted a bit differently depending on how the channel was constructed. /// </param> private void DemonstrateLogging(LoggingChannel channel) { // Whenever any ETW session changes the way it is listening to this // channel, the LoggingEnable event is fired. For example, this might // be called when a session begins listening, changes the level at // which it is listening, or stops listening. channel.LoggingEnabled += this.OnLoggingEnabled; // Log simple string events channel.LogMessage("Simple message"); // default level is Verbose channel.LogMessage("Simple error", LoggingLevel.Error); // Log simple string + integer events. channel.LogValuePair("Simple message", 123); // default level is Verbose channel.LogValuePair("Simple error", 456, LoggingLevel.Error); // The channel.Name property returns the name that was used when the // channel was constructed. When running in Windows 10 mode, the name // is already set as the provider name, so no LoggingChannelName is // automatically added to the event. channel.LogMessage(channel.Name); // The channel.Id property is new to Windows 10. channel.LogMessage(channel.Id.ToString()); // If you want to avoid the overhead of collecting data when nobody is // listening to your channel, check the Enabled property before logging. if (channel.Enabled) { channel.LogMessage(this.CollectExpensiveData()); } // The IsEnabled() method is exactly the same as the Enabled property, // except that it is a new Windows 10 API. if (channel.IsEnabled()) { channel.LogMessage(this.CollectExpensiveData()); } // If you want to only collect data if somebody is listening at a specific // level, you need to check both Enabled and Level. Note that the value of // the Level is unspecified when Enabled is false. if (channel.Enabled && channel.Level <= LoggingLevel.Warning) { channel.LogMessage(this.CollectExpensiveData(), LoggingLevel.Warning); } // The IsEnabled(LoggingLevel) method is a bit nicer than checking both // Enabled and Level, but it is only available on Windows 10 or later. if (channel.IsEnabled(LoggingLevel.Warning)) { channel.LogMessage(this.CollectExpensiveData(), LoggingLevel.Warning); } // You can also use IsEnabled to check for keywords. if (channel.IsEnabled(LoggingLevel.Information, 0x10)) { channel.LogMessage(this.CollectExpensiveData(), LoggingLevel.Information); } // Use LoggingFields with the LogEvent method to write complex events. var fields = new LoggingFields(); fields.AddDouble("pi", 3.14159); channel.LogEvent( "ComplexEvent", fields, LoggingLevel.Verbose, new LoggingOptions(0x10)); // Keywords = 0x10 // You can add any number of name-value pairs to a fields object, though // you may encounter ETW limitations if you add too many. For example, // ETW is limited to a maximum event size of 64KB, and the current // TraceLogging decoder can handle no more than 128 fields. // Performance optimization: You can reuse a LoggingFields object to // avoid unnecessary allocations. Don't forget to call Clear() // between uses, and don't try to share a LoggingFields object between // threads. fields.Clear(); fields.AddDateTime("Date", DateTimeOffset.Now); channel.LogEvent("Now", fields); fields.Clear(); // You can add a formatting hint to affect the way a value is decoded. // Not all combinations are useful, and the hint may be ignored. // For example, you can encode an MBCS string by writing a byte array // with a String hint. fields.AddUInt8Array( "AnsiString", new byte[] { 65, 66, 67, 49, 50, 51 }, // "ABC123" LoggingFieldFormat.String); // You can add "tag" bits to a field. These are user-defined bits that // can be used to communicate with an event processing tool. For example, // you might define a tag bit to indicate that a field contains private // data that should not be displayed on-screen. fields.AddString("Password", "12345", LoggingFieldFormat.Default, 0x10); // You can add a "structure" to an event. A structure is a name for a // group of fields. Structures can nest. Call BeginStruct to add a level // of nesting, and call EndStruct after the last field of the structure. fields.BeginStruct("Nested"); fields.AddInt16("Nested-1", 1); fields.AddInt16("Nested-2", 2); fields.BeginStruct("Nested-Nested"); fields.AddInt16("Nested-Nested-3", 3); fields.EndStruct(); fields.AddInt16("Nested-4", 4); fields.EndStruct(); // Advanced scenarios: you can use a LoggingOptions object to control // detailed event settings such as keywords, opcodes, and activity Ids. // These have their normal ETW semantics. You can also set event tags, // which are bit values that can be used to communicate with the event // processor. channel.LogEvent( "VeryComplexEvent", fields, LoggingLevel.Information, new LoggingOptions { Keywords = 0x123, Tags = 0x10 }); // Windows 10 introduces the ILoggingTarget interface. LoggingChannel // implements this interface. This interface allows components to accept // a logger as an parameter. this.DoSomething(channel); /* If a LoggingActivity is created using a LoggingActivity constructor, it will use Windows 8.1 semantics: - If an activity is destroyed (garbage-collected) without being closed and the associated LoggingChannel is still open, the activity will write a default Stop event. - The default Stop event (written by the destructor or by the Close() method) is encoded as a "simple" event. The 8.1 semantics are deprecated because the automatic generation of a Stop event at garbage-collection can be misleading. The Stop event is intended to mark the a precise point at which an activity is completed, while the garbage-collection of an abandoned activity is inherently imprecise and unpredictable. If a LoggingActivity is created using a StartActivity method, it will use Windows 10 semantics: - If an activity is destroyed (garbage-collected) without being closed, there will be no Stop event for the activity. - The default Stop event (written by the Close() method) is encoded as a TraceLogging event with name "ActivityClosed". */ // This activity is created with Windows 8.1 semantics. using (var a1 = new LoggingActivity("Activity1", channel)) { // The activity Start event is written by the LoggingActivity constructor. // You would do your activity's work here. // The activity Stop event is written when the activity is closed (disposed). // The Windows 10 LoggingActivity adds new methods for writing events // that are marked as associated with the activity. a1.LogEvent("Activity event"); // LoggingActivity also implements the ILoggingTarget interface, so you can // use either a channel or an activity as a logging target. this.DoSomething(a1); // The Windows 10 LoggingActivity adds new methods for creating nested activities. // Note that nested activities are always created with Windows 10 semantics, // even when nested under an activity that is using Windows 8.1 semantics. using (var a2 = a1.StartActivity("Activity2")) { // Nested task occurs here. // The Windows 10 LoggingActivity allows you to customize the Stop event. a2.StopActivity("Activity 2 stop"); } // Because a1 is using Windows 8.1 semantics, if we did not call Dispose(), // it would attempt to write a Stop event when it is garbage collected. // Writing Stop events during garbage collection is not useful, so be sure // to properly stop, close, or dispose activities. } // The Windows 10 StartActivity method creates a new activity, optionally with // specified fields and characteristics. // This activity is created with Windows 10 semantics. using (var a3 = channel.StartActivity("Activity3")) { // Because a3 is using Windows 10 semantics, if we did not call Dispose(), // there would be no Stop event (not even when the activity is garbage // collected). To get a Stop event, be sure to stop, close, or dispose the // activity. } }