using System.Reflection;
using Microsoft.Win32;
using OpenTween.Setting;
+using System.Security.Principal;
namespace OpenTween
{
[STAThread]
static int Main(string[] args)
{
+ WarnIfRunAsAdministrator();
+
if (!CheckRuntimeVersion())
{
var message = string.Format(Properties.Resources.CheckRuntimeVersion_Error, ".NET Framework 4.5.1");
- MessageBox.Show(message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ MessageBox.Show(message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
return 1;
}
}
/// <summary>
+ /// OpenTween が管理者権限で実行されている場合に警告を表示します
+ /// </summary>
+ private static void WarnIfRunAsAdministrator()
+ {
+ // UAC が無効なシステムでは警告を表示しない
+ using (var lmKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
+ using (var systemKey = lmKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\"))
+ {
+ var enableLUA = (int?)systemKey?.GetValue("EnableLUA");
+ if (enableLUA != 1)
+ return;
+ }
+
+ using (var currentIdentity = WindowsIdentity.GetCurrent())
+ {
+ var principal = new WindowsPrincipal(currentIdentity);
+ if (principal.IsInRole(WindowsBuiltInRole.Administrator))
+ {
+ var message = string.Format(Properties.Resources.WarnIfRunAsAdministrator_Message, ApplicationSettings.ApplicationName);
+ MessageBox.Show(message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ }
+ }
+ }
+
+ /// <summary>
/// 動作中の .NET Framework のバージョンが適切かチェックします
/// </summary>
private static bool CheckRuntimeVersion()
return;
}
- IntPtr windowHandle = NativeMethods.GetWindowHandle((uint)prevProcess.Id, Application.ProductName);
+ IntPtr windowHandle = NativeMethods.GetWindowHandle((uint)prevProcess.Id, ApplicationSettings.ApplicationName);
if (windowHandle != IntPtr.Zero)
{
NativeMethods.SetActiveWindow(windowHandle);
private static void OnUnhandledException(Exception ex)
{
+ if (CheckIgnorableError(ex))
+ return;
+
if (MyCommon.ExceptionOut(ex))
{
Application.Exit();
}
}
+ /// <summary>
+ /// 無視しても問題のない既知の例外であれば true を返す
+ /// </summary>
+ private static bool CheckIgnorableError(Exception ex)
+ {
+#if DEBUG
+ return false;
+#else
+ if (ex is AggregateException aggregated)
+ {
+ if (aggregated.InnerExceptions.Count != 1)
+ return false;
+
+ ex = aggregated.InnerExceptions.Single();
+ }
+
+ switch (ex)
+ {
+ case System.Net.WebException webEx:
+ // SSL/TLS のネゴシエーションに失敗した場合に発生する。なぜかキャッチできない例外
+ // https://osdn.net/ticket/browse.php?group_id=6526&tid=37432
+ if (webEx.Status == System.Net.WebExceptionStatus.SecureChannelFailure)
+ return true;
+ break;
+ case System.Threading.Tasks.TaskCanceledException cancelEx:
+ // ton.twitter.com の画像でタイムアウトした場合、try-catch で例外がキャッチできない
+ // https://osdn.net/ticket/browse.php?group_id=6526&tid=37433
+ var stackTrace = new System.Diagnostics.StackTrace(cancelEx);
+ var lastFrameMethod = stackTrace.GetFrame(stackTrace.FrameCount - 1).GetMethod();
+ if (lastFrameMethod.ReflectedType == typeof(Connection.TwitterApiConnection) &&
+ lastFrameMethod.Name == nameof(Connection.TwitterApiConnection.GetStreamAsync))
+ return true;
+ break;
+ }
+
+ return false;
+#endif
+ }
+
public static void InitCulture()
{
var currentCulture = CultureInfo.CurrentUICulture;
if (!Directory.Exists(configDir))
{
var text = string.Format(Properties.Resources.ConfigDirectoryNotExist, configDir);
- MessageBox.Show(text, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ MessageBox.Show(text, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
var roamingDir = Path.Combine(new[]
{
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
- Application.ProductName,
+ ApplicationSettings.ApplicationName,
});
Directory.CreateDirectory(roamingDir);
{
// StartupPath に設定ファイルが存在し、Roaming 内のファイルよりも新しい場合のみ警告を表示する
var message = string.Format(Properties.Resources.SettingPath_Relocation, Application.StartupPath, MyCommon.settingPath);
- MessageBox.Show(message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
+ MessageBox.Show(message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
// Roaming に設定ファイルを作成 (StartupPath に読み込みに成功した設定ファイルがあれば内容がコピーされる)