using System.Threading.Tasks;
using System.Globalization;
using System.Reflection;
+using Microsoft.Win32;
namespace OpenTween
{
[STAThread]
static int Main(string[] args)
{
+ if (!CheckRuntimeVersion())
+ {
+ var message = string.Format(Properties.Resources.CheckRuntimeVersion_Error, ".NET Framework 4.5.1");
+ MessageBox.Show(message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return 1;
+ }
+
StartupOptions = ParseArguments(args);
- CheckSettingFilePath();
+ if (!SetConfigDirectoryPath())
+ return 1;
+
InitCulture();
- string pt = Application.ExecutablePath.Replace("\\", "/") + "/" + Application.ProductName;
+ // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する
+ string pt = MyCommon.settingPath.Replace("\\", "/") + "/" + Application.ProductName;
using (Mutex mt = new Mutex(false, pt))
{
if (!mt.WaitOne(0, false))
var text = string.Format(MyCommon.ReplaceAppName(Properties.Resources.StartupText1), MyCommon.GetAssemblyName());
MessageBox.Show(text, MyCommon.ReplaceAppName(Properties.Resources.StartupText2), MessageBoxButtons.OK, MessageBoxIcon.Information);
- ShowPreviousWindow();
+ TryActivatePreviousWindow();
return 1;
}
}
/// <summary>
+ /// 動作中の .NET Framework のバージョンが適切かチェックします
+ /// </summary>
+ private static bool CheckRuntimeVersion()
+ {
+ // Mono 上で動作している場合はバージョンチェックを無視します
+ if (Type.GetType("Mono.Runtime", false) != null)
+ return true;
+
+ // .NET Framework 4.5.1 以降で動作しているかチェックする
+ // 参照: http://msdn.microsoft.com/en-us/library/hh925568%28v=vs.110%29.aspx
+
+ using (var lmKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
+ using (var ndpKey = lmKey.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"))
+ {
+ var releaseKey = (int)ndpKey.GetValue("Release");
+ return releaseKey >= 378675;
+ }
+ }
+
+ /// <summary>
/// “/key:value”形式の起動オプションを解釈し IDictionary に変換する
/// </summary>
/// <remarks>
.ToDictionary(x => x.Key, x => x.Last().Groups[2].Value);
}
- private static void ShowPreviousWindow()
+ private static void TryActivatePreviousWindow()
{
// 実行中の同じアプリケーションのウィンドウ・ハンドルの取得
- var prevProcess = Win32Api.GetPreviousProcess();
- if (prevProcess == null)
+ var prevProcess = GetPreviousProcess();
+ if (prevProcess == null || prevProcess.MainWindowHandle == IntPtr.Zero)
+ {
return;
+ }
+
+ var form = Control.FromHandle(prevProcess.MainWindowHandle) as Form;
+ if (form != null)
+ {
+ if (form.WindowState == FormWindowState.Minimized)
+ {
+ NativeMethods.RestoreWindow(form);
+ }
+ form.Activate();
+ }
+ }
- if (prevProcess.MainWindowHandle != IntPtr.Zero)
+ private static Process GetPreviousProcess()
+ {
+ var currentProcess = Process.GetCurrentProcess();
+ try
{
- // 起動中のアプリケーションを最前面に表示
- Win32Api.WakeupWindow(prevProcess.MainWindowHandle);
+ return Process.GetProcessesByName(currentProcess.ProcessName)
+ .Where(p => p.Id != currentProcess.Id)
+ .FirstOrDefault(p => p.MainModule.FileName.Equals(currentProcess.MainModule.FileName, StringComparison.OrdinalIgnoreCase));
}
- else
+ catch
{
- //プロセス特定は出来たが、ウィンドウハンドルが取得できなかった(アイコン化されている)
- //タスクトレイアイコンのクリックをエミュレート
- //注:アイコン特定はTooltipの文字列で行うため、多重起動時は先に見つけた物がアクティブになる
- Win32Api.ClickTasktrayIcon(Application.ProductName);
+ return null;
}
}
}
}
- private static void CheckSettingFilePath()
+ private static bool SetConfigDirectoryPath()
{
- if (File.Exists(Path.Combine(Application.StartupPath, "roaming")))
+ string configDir;
+ if (StartupOptions.TryGetValue("configDir", out configDir) && !string.IsNullOrEmpty(configDir))
{
- MyCommon.settingPath = MySpecialPath.UserAppDataPath();
+ // 起動オプション /configDir で設定ファイルの参照先を変更できます
+ if (!Directory.Exists(configDir))
+ {
+ var text = string.Format(Properties.Resources.ConfigDirectoryNotExist, configDir);
+ MessageBox.Show(text, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return false;
+ }
+
+ MyCommon.settingPath = Path.GetFullPath(configDir);
}
else
{
- MyCommon.settingPath = Application.StartupPath;
+ if (File.Exists(Path.Combine(Application.StartupPath, "roaming")))
+ {
+ MyCommon.settingPath = MySpecialPath.UserAppDataPath();
+ }
+ else
+ {
+ MyCommon.settingPath = Application.StartupPath;
+ }
}
+
+ return true;
}
}
}