OSDN Git Service

#28263 DTX2WAV003:
[dtxmania/dtxmania.git] / DTX2WAV / Program.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Threading.Tasks;
5 using System.Windows.Forms;
6 using System.Diagnostics;
7 using System.Runtime.InteropServices;
8 using System.IO;
9
10 namespace DTX2WAV
11 {
12         static class Program
13         {
14                 /// <summary>
15                 /// アプリケーションのメイン エントリ ポイントです。
16                 /// </summary>
17                 [STAThread]
18                 static void Main()
19                 {
20                         // 以下、DOBON.NETを参照した。mutexを使って二重起動を抑制。
21                         //Mutex名を決める(必ずアプリケーション固有の文字列に変更すること!)
22                         string mutexName = "DTX2WAV";
23                         //Mutexオブジェクトを作成する
24                         System.Threading.Mutex mutex = new System.Threading.Mutex(false, mutexName);
25
26                         bool hasHandle = false;
27                         try
28                         {
29                                 try
30                                 {
31                                         // mutexの所有権を要求する
32                                         hasHandle = mutex.WaitOne(0, false);
33                                 }
34                                 //.NET Framework 2.0以降の場合
35                                 catch (System.Threading.AbandonedMutexException)
36                                 {
37                                         //別のアプリケーションがmutexを解放しないで終了した時
38                                         hasHandle = true;
39                                 }
40                                 #region [ mutexを得られなければ、既に起動済みと判断して、そっちを最前面に出して、こっちは終了 ]
41                                 if (hasHandle == false)
42                                 {
43                                         //得られなかった場合は、すでに起動していると判断して終了
44                                         //MessageBox.Show("多重起動はできません。");
45
46                                         // 得られなかった場合は、既に起動していると判断して、
47                                         // 既に起動しているほうを最前面に出す
48                                         Process prevProcess = GetPreviousProcess();
49                                         if (prevProcess != null)
50                                         {
51                                                 WakeupWindow(prevProcess.MainWindowHandle);
52                                         }
53                                         return;
54                                 }
55                                 #endregion
56
57                                 #region [ DTXMania本体が既に起動されていないか確認する。既に起動済みなら警告して終了 ]
58                                 Process dtxmaniaProcess = GetProcessesByFileName("DTXManiaGR.exe");
59                                 if (dtxmaniaProcess != null)
60                                 {
61                                         MessageBox.Show(
62                                                 "既にDTXMania本体が起動しています。DTX2WAVを起動する前に、DTXMania本体を終了してください。",
63                                                 "DTX2WAV",
64                                                 MessageBoxButtons.OK,
65                                                 MessageBoxIcon.Exclamation
66                                         );
67                                         return;
68                                 }
69
70                                 #endregion
71
72                                 #region [ アプリを通常通り起動する ]
73                                 Application.EnableVisualStyles();
74                                 Application.SetCompatibleTextRenderingDefault(false);
75                                 Application.Run(new Main());
76                                 #endregion
77                         }
78                         finally
79                         {
80                                 if (hasHandle)
81                                 {
82                                         // mutexを解放する
83                                         mutex.ReleaseMutex();
84                                 }
85                                 mutex.Close();
86                         }
87
88
89                 }
90
91                 // .NET TIPSより
92                 // 実行中の同じアプリケーションのプロセスを取得する
93                 // http://www.atmarkit.co.jp/fdotnet/dotnettips/151winshow/winshow.html
94                 public static Process GetPreviousProcess()
95                 {
96                         Process curProcess = Process.GetCurrentProcess();
97                         Process[] allProcesses = Process.GetProcessesByName(curProcess.ProcessName);
98
99                         foreach (Process checkProcess in allProcesses)
100                         {
101                                 // 自分自身のプロセスIDは無視する
102                                 if (checkProcess.Id != curProcess.Id)
103                                 {
104                                         // プロセスのフルパス名を比較して同じアプリケーションか検証
105                                         if (String.Compare(
106                                                  checkProcess.MainModule.FileName,
107                                                  curProcess.MainModule.FileName, true) == 0)
108                                         {
109                                                 // 同じフルパス名のプロセスを取得
110                                                 return checkProcess;
111                                         }
112                                 }
113                         }
114
115                         // 同じアプリケーションのプロセスが見つからない!
116                         return null;
117                 }
118
119                 /// <summary>
120                 /// 指定した実行ファイル名のプロセスを取得する。
121                 /// https://dobon.net/vb/dotnet/process/getprocessesbyfilename.html
122                 /// </summary>
123                 /// <param name="searchFileName">検索する実行ファイル名。</param>
124                 /// <returns>最初に一致したProcess。</returns>
125                 public static System.Diagnostics.Process GetProcessesByFileName(string searchFileName)
126                 {
127                         searchFileName = searchFileName.ToLower();
128
129                         //すべてのプロセスを列挙する
130                         foreach (System.Diagnostics.Process p
131                                 in System.Diagnostics.Process.GetProcesses())
132                         {
133                                 string fileName;
134                                 try
135                                 {
136                                         //メインモジュールのパスを取得する
137                                         fileName = p.MainModule.FileName;
138                                 }
139                                 catch (System.ComponentModel.Win32Exception)
140                                 {
141                                         //MainModuleの取得に失敗
142                                         fileName = "";
143                                 }
144                                 if (0 < fileName.Length)
145                                 {
146                                         //ファイル名の部分を取得する
147                                         fileName = System.IO.Path.GetFileName(fileName);
148                                         //探しているファイル名と一致した時、コレクションに追加
149                                         if (searchFileName.Equals(fileName.ToLower()))
150                                         {
151                                                 return p;
152                                         }
153                                 }
154                         }
155
156                         return null;
157                 }
158
159
160                 // .NET TIPSより
161                 // 外部プロセスのウィンドウを最前面にする
162                 // http://www.atmarkit.co.jp/fdotnet/dotnettips/151winshow/winshow.html
163                 public static void WakeupWindow(IntPtr hWnd)
164                 {
165                         // メイン・ウィンドウが最小化されていれば元に戻す
166                         if (IsIconic(hWnd))
167                         {
168                                 ShowWindowAsync(hWnd, SW_RESTORE);
169                         }
170
171                         // メイン・ウィンドウを最前面に表示する
172                         SetForegroundWindow(hWnd);
173                 }
174                 // 外部プロセスのメイン・ウィンドウを起動するためのWin32 API
175                 [DllImport("user32.dll")]
176                 private static extern bool SetForegroundWindow(IntPtr hWnd);
177                 [DllImport("user32.dll")]
178                 private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
179                 [DllImport("user32.dll")]
180                 private static extern bool IsIconic(IntPtr hWnd);
181                 // ShowWindowAsync関数のパラメータに渡す定義値
182                 private const int SW_RESTORE = 9;  // 画面を元の大きさに戻す
183
184         }
185 }