using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Globalization;
using System.IO;
namespace DTX2WAV
{
static class Program
{
///
/// アプリケーションのメイン エントリ ポイントです。
///
[STAThread]
static void Main()
{
#if DEBUG
#if USE_ENGLISHRESOURCE
Thread.CurrentThread.CurrentUICulture = new CultureInfo( "en-GB", false ); // yyagi; For testing English resources
#endif
#endif
// 以下、DOBON.NETを参照した。mutexを使って二重起動を抑制。
//Mutex名を決める(必ずアプリケーション固有の文字列に変更すること!)
string mutexName = "DTX2WAV";
//Mutexオブジェクトを作成する
System.Threading.Mutex mutex = new System.Threading.Mutex(false, mutexName);
bool hasHandle = false;
try
{
try
{
// mutexの所有権を要求する
hasHandle = mutex.WaitOne(0, false);
}
//.NET Framework 2.0以降の場合
catch (System.Threading.AbandonedMutexException)
{
//別のアプリケーションがmutexを解放しないで終了した時
hasHandle = true;
}
#region [ mutexを得られなければ、既に起動済みと判断して、そっちを最前面に出して、こっちは終了 ]
if (hasHandle == false)
{
//得られなかった場合は、すでに起動していると判断して終了
//MessageBox.Show("多重起動はできません。");
// 得られなかった場合は、既に起動していると判断して、
// 既に起動しているほうを最前面に出す
Process prevProcess = GetPreviousProcess();
if (prevProcess != null)
{
WakeupWindow(prevProcess.MainWindowHandle);
}
return;
}
#endregion
#region [ DTXMania本体が既に起動されていないか確認する。既に起動済みなら警告して終了 ]
Process dtxmaniaProcess = GetProcessesByFileName("DTXManiaGR.exe");
if (dtxmaniaProcess != null)
{
MessageBox.Show(
"既にDTXMania本体が起動しています。DTX2WAVを起動する前に、DTXMania本体を終了してください。",
"DTX2WAV",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation
);
return;
}
#endregion
#region [ アプリを通常通り起動する ]
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Main());
#endregion
}
finally
{
if (hasHandle)
{
// mutexを解放する
mutex.ReleaseMutex();
}
mutex.Close();
}
}
// .NET TIPSより
// 実行中の同じアプリケーションのプロセスを取得する
// http://www.atmarkit.co.jp/fdotnet/dotnettips/151winshow/winshow.html
public static Process GetPreviousProcess()
{
Process curProcess = Process.GetCurrentProcess();
Process[] allProcesses = Process.GetProcessesByName(curProcess.ProcessName);
foreach (Process checkProcess in allProcesses)
{
// 自分自身のプロセスIDは無視する
if (checkProcess.Id != curProcess.Id)
{
// プロセスのフルパス名を比較して同じアプリケーションか検証
if (String.Compare(
checkProcess.MainModule.FileName,
curProcess.MainModule.FileName, true) == 0)
{
// 同じフルパス名のプロセスを取得
return checkProcess;
}
}
}
// 同じアプリケーションのプロセスが見つからない!
return null;
}
///
/// 指定した実行ファイル名のプロセスを取得する。
/// https://dobon.net/vb/dotnet/process/getprocessesbyfilename.html
///
/// 検索する実行ファイル名。
/// 最初に一致したProcess。
public static System.Diagnostics.Process GetProcessesByFileName(string searchFileName)
{
searchFileName = searchFileName.ToLower();
//すべてのプロセスを列挙する
foreach (System.Diagnostics.Process p
in System.Diagnostics.Process.GetProcesses())
{
string fileName;
try
{
//メインモジュールのパスを取得する
fileName = p.MainModule.FileName;
}
catch (System.ComponentModel.Win32Exception)
{
//MainModuleの取得に失敗
fileName = "";
}
if (0 < fileName.Length)
{
//ファイル名の部分を取得する
fileName = System.IO.Path.GetFileName(fileName);
//探しているファイル名と一致した時、コレクションに追加
if (searchFileName.Equals(fileName.ToLower()))
{
return p;
}
}
}
return null;
}
// .NET TIPSより
// 外部プロセスのウィンドウを最前面にする
// http://www.atmarkit.co.jp/fdotnet/dotnettips/151winshow/winshow.html
public static void WakeupWindow(IntPtr hWnd)
{
// メイン・ウィンドウが最小化されていれば元に戻す
if (IsIconic(hWnd))
{
ShowWindowAsync(hWnd, SW_RESTORE);
}
// メイン・ウィンドウを最前面に表示する
SetForegroundWindow(hWnd);
}
// 外部プロセスのメイン・ウィンドウを起動するためのWin32 API
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
// ShowWindowAsync関数のパラメータに渡す定義値
private const int SW_RESTORE = 9; // 画面を元の大きさに戻す
}
}