// (c) 2012 Egtra (@egtra) <http://dev.activebasic.com/egtra/>
// (c) 2012 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
// All rights reserved.
-//
+//
// This file is part of OpenTween.
-//
+//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version.
-//
+//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License
// for more details.
-//
+//
// You should have received a copy of the GNU General public License along
// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
-using System.IO;
-using System.Diagnostics;
using System.Windows.Forms;
-using System.Threading;
-using System.Globalization;
-using System.Reflection;
+using OpenTween.Connection;
+using OpenTween.Setting;
namespace OpenTween
{
- internal class MyApplication
+ internal class ApplicationEvents
{
/// <summary>
+ /// 起動時に指定されたオプションを取得します
+ /// </summary>
+ public static CommandLineArgs StartupOptions { get; private set; } = null!;
+
+ /// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
- static int Main()
+ public static int Main(string[] args)
{
- CheckSettingFilePath();
- InitCulture();
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
- string pt = Application.ExecutablePath.Replace("\\", "/") + "/" + Application.ProductName;
- using (Mutex mt = new Mutex(false, pt))
- {
- if (!mt.WaitOne(0, false))
- {
- ShowPreviousWindow();
- return 1;
- }
+ using var errorReportHandler = new ErrorReportHandler();
- Application.ThreadException += MyApplication_UnhandledException;
+ StartupOptions = new(args);
+ InitializeTraceFrag();
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new TweenMain());
+ if (!ApplicationPreconditions.CheckAll())
+ return 1;
- mt.ReleaseMutex();
+ var settingsPath = SettingManager.DetermineSettingsPath(StartupOptions);
+ if (MyCommon.IsNullOrEmpty(settingsPath))
+ return 1;
- return 0;
- }
- }
+ var settings = new SettingManager(settingsPath);
+ settings.LoadAll();
- private static void ShowPreviousWindow()
- {
- // 実行中の同じアプリケーションのウィンドウ・ハンドルの取得
- var prevProcess = Win32Api.GetPreviousProcess();
- if (prevProcess != null && prevProcess.MainWindowHandle != IntPtr.Zero)
- {
- // 起動中のアプリケーションを最前面に表示
- Win32Api.WakeupWindow(prevProcess.MainWindowHandle);
- }
- else
+ using var container = new ApplicationContainer(settings);
+
+ settings.Common.Validate();
+
+ ThemeManager.ApplyGlobalUIFont(settings.Local);
+ container.CultureService.Initialize();
+
+ Networking.Initialize();
+ settings.ApplySettings();
+
+ // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する
+ using var mutex = new ApplicationInstanceMutex(ApplicationSettings.AssemblyName, settings.SettingsPath);
+
+ if (mutex.InstanceExists)
{
- if (prevProcess != null)
- {
- //プロセス特定は出来たが、ウィンドウハンドルが取得できなかった(アイコン化されている)
- //タスクトレイアイコンのクリックをエミュレート
- //注:アイコン特定はTooltipの文字列で行うため、多重起動時は先に見つけた物がアクティブになる
- var rslt = Win32Api.ClickTasktrayIcon(Application.ProductName);
- if (!rslt)
- {
- // 警告を表示(見つからない、またはその他の原因で失敗)
- var text = string.Format(MyCommon.ReplaceAppName(Properties.Resources.StartupText1), MyCommon.GetAssemblyName());
- MessageBox.Show(text, MyCommon.ReplaceAppName(Properties.Resources.StartupText2), MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- }
- else
- {
- // 警告を表示(プロセス見つからない場合)
- var text = string.Format(MyCommon.ReplaceAppName(Properties.Resources.StartupText1), MyCommon.GetAssemblyName());
- MessageBox.Show(text, MyCommon.ReplaceAppName(Properties.Resources.StartupText2), MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
+ var text = string.Format(MyCommon.ReplaceAppName(Properties.Resources.StartupText1), ApplicationSettings.AssemblyName);
+ MessageBox.Show(text, MyCommon.ReplaceAppName(Properties.Resources.StartupText2), MessageBoxButtons.OK, MessageBoxIcon.Information);
+
+ mutex.TryActivatePreviousInstance();
+ return 1;
}
- }
- private static void MyApplication_UnhandledException(object sender, ThreadExceptionEventArgs e)
- {
- //GDI+のエラー原因を特定したい
- if (e.Exception.Message != "A generic error occurred in GDI+." &&
- e.Exception.Message != "GDI+ で汎用エラーが発生しました。")
+ if (settings.IsIncomplete)
{
- if (MyCommon.ExceptionOut(e.Exception))
- {
- Application.Exit();
- }
+ var completed = ShowSettingsDialog(settings, container.IconAssetsManager);
+ if (!completed)
+ return 1; // 設定が完了しなかったため終了
}
- }
- private static bool IsEqualCurrentCulture(string CultureName)
- {
- return Thread.CurrentThread.CurrentUICulture.Name.StartsWith(CultureName);
- }
+ SetupTwitter(container.Twitter, settings);
- public static string CultureCode
- {
- get
- {
- if (MyCommon.cultureStr == null)
- {
- var cfgCommon = SettingCommon.Load();
- MyCommon.cultureStr = cfgCommon.Language;
- if (MyCommon.cultureStr == "OS")
- {
- if (!IsEqualCurrentCulture("ja") &&
- !IsEqualCurrentCulture("en") &&
- !IsEqualCurrentCulture("zh-CN"))
- {
- MyCommon.cultureStr = "en";
- }
- }
- }
- return MyCommon.cultureStr;
- }
+ Application.Run(container.MainForm);
+
+ return 0;
}
- public static void InitCulture(string code)
+ private static void InitializeTraceFrag()
{
- try
- {
- Thread.CurrentThread.CurrentUICulture = new CultureInfo(code);
- }
- catch (Exception)
- {
- }
+ var traceFlag = false;
+
+#if DEBUG
+ traceFlag = true;
+#endif
+
+ if (StartupOptions.ContainsKey("d"))
+ traceFlag = true;
+
+ var version = Version.Parse(MyCommon.FileVersion);
+ if (version.Build != 0)
+ traceFlag = true;
+
+ MyCommon.TraceFlag = traceFlag;
}
- public static void InitCulture()
+
+ private static bool ShowSettingsDialog(SettingManager settings, IconAssetsManager iconAssets)
{
- try
- {
- if (CultureCode != "OS") Thread.CurrentThread.CurrentUICulture = new CultureInfo(CultureCode);
- }
- catch (Exception)
- {
- }
+ using var settingDialog = new AppendSettingDialog();
+ settingDialog.Icon = iconAssets.IconMain;
+ settingDialog.ShowInTaskbar = true; // この時点では TweenMain が表示されていないため代わりに表示する
+ settingDialog.LoadConfig(settings.Common, settings.Local);
+
+ var ret = settingDialog.ShowDialog();
+ if (ret != DialogResult.OK)
+ return false;
+
+ settingDialog.SaveConfig(settings.Common, settings.Local);
+
+ if (settings.IsIncomplete)
+ return false;
+
+ settings.SaveAll();
+ return true;
}
- private static void CheckSettingFilePath()
+ private static void SetupTwitter(Twitter tw, SettingManager settings)
{
- if (File.Exists(Path.Combine(Application.StartupPath, "roaming")))
+ var account = settings.Common.SelectedAccount;
+ if (account != null)
+ tw.Initialize(account.GetTwitterCredential(), account.Username, account.UserId);
+ else
+ tw.Initialize(new TwitterCredentialNone(), "", 0L);
+
+ tw.RestrictFavCheck = settings.Common.RestrictFavCheck;
+ tw.ReadOwnPost = settings.Common.ReadOwnPost;
+
+ // アクセストークンが有効であるか確認する
+ // ここが Twitter API への最初のアクセスになるようにすること
+ try
{
- MyCommon.settingPath = MySpecialPath.UserAppDataPath();
+ tw.VerifyCredentials();
}
- else
+ catch (WebApiException ex)
{
- MyCommon.settingPath = Application.StartupPath;
+ MessageBox.Show(
+ string.Format(Properties.Resources.StartupAuthError_Text, ex.Message),
+ ApplicationSettings.ApplicationName,
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Warning
+ );
}
}
}