OSDN Git Service

#36043 CDTXMania 内の app 以外の static メンバをインスタンスメンバにし、appを介してアクセスするように変更。CChipのメンバの多くをpr...
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / 全体 / Program.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Globalization;\r
4 using System.Text;\r
5 using System.Runtime.InteropServices;\r
6 using System.Threading;\r
7 using System.Diagnostics;\r
8 using System.Windows.Forms;\r
9 using System.IO;\r
10 using FDK;\r
11 \r
12 namespace DTXMania\r
13 {\r
14         internal class Program\r
15         {\r
16                 #region [ 二重起動チェック、DLL存在チェック ]\r
17                 //-----------------------------\r
18                 private static Mutex mutex二重起動防止用;\r
19 \r
20                 private static bool tDLLの存在チェック( string strDll名, string str存在しないときに表示するエラー文字列jp, string str存在しないときに表示するエラー文字列en, bool bLoadDllCheck )\r
21                 {\r
22                         string str存在しないときに表示するエラー文字列 = ( CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja" ) ?\r
23                                 str存在しないときに表示するエラー文字列jp : str存在しないときに表示するエラー文字列en;\r
24                         if ( bLoadDllCheck )\r
25                         {\r
26                                 IntPtr hModule = LoadLibrary( strDll名 );              // 実際にLoadDll()してチェックする\r
27                                 if ( hModule == IntPtr.Zero )\r
28                                 {\r
29                                         MessageBox.Show( str存在しないときに表示するエラー文字列, "DTXMania runtime error", MessageBoxButtons.OK, MessageBoxIcon.Hand );\r
30                                         return false;\r
31                                 }\r
32                                 FreeLibrary( hModule );\r
33                         }\r
34                         else\r
35                         {                                                                                                       // 単純にファイルの存在有無をチェックするだけ (プロジェクトで「参照」していたり、アンマネージドなDLLが暗黙リンクされるものはこちら)\r
36                                 string path = Path.Combine( System.IO.Directory.GetCurrentDirectory(), strDll名 );\r
37                                 if ( !File.Exists( path ) )\r
38                                 {\r
39                                         MessageBox.Show( str存在しないときに表示するエラー文字列, "DTXMania runtime error", MessageBoxButtons.OK, MessageBoxIcon.Hand );\r
40                                         return false;\r
41                                 }\r
42                         }\r
43                         return true;\r
44                 }\r
45                 private static bool tDLLの存在チェック( string strDll名, string str存在しないときに表示するエラー文字列jp, string str存在しないときに表示するエラー文字列en )\r
46                 {\r
47                         //return true;\r
48                         return tDLLの存在チェック( strDll名, str存在しないときに表示するエラー文字列jp, str存在しないときに表示するエラー文字列en, false );\r
49                 }\r
50 \r
51                 #region [DllImport]\r
52                 [DllImport( "kernel32", CharSet = CharSet.Unicode, SetLastError = true )]\r
53                 internal static extern void FreeLibrary( IntPtr hModule );\r
54 \r
55                 [DllImport( "kernel32", CharSet = CharSet.Unicode, SetLastError = true )]\r
56                 internal static extern IntPtr LoadLibrary( string lpFileName );\r
57                 #endregion\r
58                 //-----------------------------\r
59                 #endregion\r
60 \r
61                 [STAThread] \r
62                 private static void Main()\r
63                 {\r
64                         mutex二重起動防止用 = new Mutex( false, "DTXManiaMutex" );\r
65 \r
66                         if ( mutex二重起動防止用.WaitOne( 0, false ) )\r
67                         {\r
68                                 string newLine = Environment.NewLine;\r
69                                 bool bDLLnotfound = false;\r
70 \r
71                                 Trace.WriteLine( "Current Directory: " + Environment.CurrentDirectory );\r
72                                 Trace.WriteLine( "EXEのあるフォルダ: " + Path.GetDirectoryName( Application.ExecutablePath ) );\r
73 \r
74                                 #region [DLLの存在チェック]\r
75                                 if ( !tDLLの存在チェック( "dll\\SlimDX" + CDTXMania.SLIMDXDLL + ".dll",\r
76                                         "SlimDX" + CDTXMania.SLIMDXDLL + ".dll またはその依存するdllが存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
77                                         "SlimDX" + CDTXMania.SLIMDXDLL + ".dll, or its depended DLL, is not found." + newLine + "Please download DTXMania again."\r
78                                         ) ) bDLLnotfound = true;\r
79                                 if ( !tDLLの存在チェック( "dll\\FDK.dll",\r
80                                         "FDK.dll またはその依存するdllが存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
81                                         "FDK.dll, or its depended DLL, is not found." + newLine + "Please download DTXMania again."\r
82                                         ) ) bDLLnotfound = true;\r
83                                 if ( !tDLLの存在チェック( "xadec.dll",           // #35444 2015.8.27 yyagi; Changed dll path\r
84                                         "xadec.dll が存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
85                                         "xadec.dll is not found." + newLine + "Please download DTXMania again."\r
86                                         ) ) bDLLnotfound = true;\r
87                                 if ( !tDLLの存在チェック( "dll\\SoundDecoder.dll",\r
88                                         "SoundDecoder.dll またはその依存するdllが存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
89                                         "SoundDecoder.dll, or its depended DLL, is not found." + newLine + "Please download DTXMania again."\r
90                                         ) ) bDLLnotfound = true;\r
91                                 if ( !tDLLの存在チェック( CDTXMania.D3DXDLL,\r
92                                         CDTXMania.D3DXDLL + " が存在しません。" + newLine + "DirectX Redist フォルダの DXSETUP.exe を実行し、" + newLine + "必要な DirectX ランタイムをインストールしてください。",\r
93                                         CDTXMania.D3DXDLL + " is not found." + newLine + "Please execute DXSETUP.exe in \"DirectX Redist\" folder, to install DirectX runtimes required for DTXMania.",\r
94                                         true\r
95                                         ) ) bDLLnotfound = true;\r
96                                 if ( !tDLLの存在チェック( "dll\\bass.dll",\r
97                                         "bass.dll が存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
98                                         "baas.dll is not found." + newLine + "Please download DTXMania again."\r
99                                         ) ) bDLLnotfound = true;\r
100                                 if ( !tDLLの存在チェック( "dll\\Bass.Net.dll",\r
101                                         "Bass.Net.dll が存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
102                                         "Bass.Net.dll is not found." + newLine + "Please download DTXMania again."\r
103                                         ) ) bDLLnotfound = true;\r
104                                 if ( !tDLLの存在チェック( "dll\\bassmix.dll",\r
105                                         "bassmix.dll を読み込めません。bassmix.dll か bass.dll が存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
106                                         "bassmix.dll is not loaded. bassmix.dll or bass.dll must not exist." + newLine + "Please download DTXMania again."\r
107                                         ) ) bDLLnotfound = true;\r
108                                 if ( !tDLLの存在チェック( "dll\\bassasio.dll",\r
109                                         "bassasio.dll を読み込めません。bassasio.dll か bass.dll が存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
110                                         "bassasio.dll is not loaded. bassasio.dll or bass.dll must not exist." + newLine + "Please download DTXMania again."\r
111                                         ) ) bDLLnotfound = true;\r
112                                 if ( !tDLLの存在チェック( "dll\\basswasapi.dll",\r
113                                         "basswasapi.dll を読み込めません。basswasapi.dll か bass.dll が存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
114                                         "basswasapi.dll is not loaded. basswasapi.dll or bass.dll must not exist." + newLine + "Please download DTXMania again."\r
115                                         ) ) bDLLnotfound = true;\r
116                                 if ( !tDLLの存在チェック( "dll\\bass_fx.dll",\r
117                                         "bass_fx.dll を読み込めません。bass_fx.dll か bass.dll が存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
118                                         "bass_fx.dll is not loaded. bass_fx.dll or bass.dll must not exist." + newLine + "Please download DTXMania again."\r
119                                         ) ) bDLLnotfound = true;\r
120                                 if ( !tDLLの存在チェック( "dll\\DirectShowLib-2005.dll",\r
121                                         "DirectShowLib-2005.dll が存在しません。" + newLine + "DTXManiaをダウンロードしなおしてください。",\r
122                                         "DirectShowLib-2005.dll is not found." + newLine + "Please download DTXMania again."\r
123                                         ) ) bDLLnotfound = true;\r
124                                 #endregion\r
125                                 if ( !bDLLnotfound )\r
126                                 {\r
127 #if DEBUG && TEST_ENGLISH\r
128                                         Thread.CurrentThread.CurrentCulture = new CultureInfo( "en-US" );\r
129 #endif\r
130 \r
131                                         DWM.EnableComposition( false ); // Disable AeroGrass temporally\r
132 \r
133                                         // BEGIN #23670 2010.11.13 from: キャッチされない例外は放出せずに、ログに詳細を出力する。\r
134                                         // BEGIM #24606 2011.03.08 from: DEBUG 時は例外発生箇所を直接デバッグできるようにするため、例外をキャッチしないようにする。\r
135 #if !DEBUG\r
136                                         try\r
137 #endif\r
138                                         {\r
139                                                 using ( var mania = new CDTXMania() )\r
140                                                         mania.Run();\r
141 \r
142                                                 Trace.WriteLine( "" );\r
143                                                 Trace.WriteLine( "遊んでくれてありがとう!" );\r
144                                         }\r
145 #if !DEBUG\r
146                                         catch( Exception e )\r
147                                         {\r
148                                                 Trace.WriteLine( "" );\r
149                                                 Trace.Write( e.ToString() );\r
150                                                 Trace.WriteLine( "" );\r
151                                                 Trace.WriteLine( "エラーだゴメン!(涙" );\r
152                                                 MessageBox.Show( e.ToString(), "DTXMania Error", MessageBoxButtons.OK, MessageBoxIcon.Error );  // #23670 2011.2.28 yyagi to show error dialog\r
153                                         }\r
154 #endif\r
155                                         // END #24606 2011.03.08 from\r
156                                         // END #23670 2010.11.13 from\r
157 \r
158                                         if ( Trace.Listeners.Count > 1 )\r
159                                                 Trace.Listeners.RemoveAt( 1 );\r
160                                 }\r
161 \r
162                                 // BEGIN #24615 2011.03.09 from: Mutex.WaitOne() が true を返した場合は、Mutex のリリースが必要である。\r
163 \r
164                                 mutex二重起動防止用.ReleaseMutex();\r
165                                 mutex二重起動防止用 = null;\r
166 \r
167                                 // END #24615 2011.03.09 from\r
168                         }\r
169                         else            // DTXManiaが既に起動中\r
170                         {\r
171                                 \r
172                                 // → 引数が0個の時はそのまま終了\r
173                                 // 1個( コンパクトモード or DTXV -S) か2個 (DTXV -Nxxx ファイル名)のときは、そのプロセスにコマンドラインを丸々投げて終了する\r
174 \r
175                                 for ( int i = 0; i < 5; i++ )           // 検索結果のハンドルがZeroになることがあるので、200ms間隔で5回リトライする\r
176                                 {\r
177                                         #region [ 既に起動中のDTXManiaプロセスを検索する。]\r
178                                         // このやり方だと、ShowInTaskbar=falseでタスクバーに表示されないパターンの時に検索に失敗するようだが\r
179                                         // DTXManiaでそのパターンはない?のでこのままいく。\r
180                                         // FindWindowを使えばこのパターンにも対応できるが、C#でビルドするアプリはウインドウクラス名を自前指定できないので、これは使わない。\r
181 \r
182                                         Process current = Process.GetCurrentProcess();\r
183                                         Process[] running = Process.GetProcessesByName( current.ProcessName );\r
184                                         Process target = null;\r
185                                         //IntPtr hWnd = FindWindow( null, "DTXMania .NET style release " + CDTXMania.app.VERSION );\r
186 \r
187                                         foreach ( Process p in running )\r
188                                         {\r
189                                                 if ( p.Id != current.Id )       // プロセス名は同じでかつ、プロセスIDが自分自身とは異なるものを探す\r
190                                                 {\r
191                                                         if ( p.MainModule.FileName == current.MainModule.FileName && p.MainWindowHandle != IntPtr.Zero )\r
192                                                         {\r
193                                                                 target = p;\r
194                                                                 break;\r
195                                                         }\r
196                                                 }\r
197                                         }\r
198                                         #endregion\r
199 \r
200                                         #region [ 起動中のDTXManiaがいれば、そのプロセスにコマンドラインを投げる ]\r
201                                         if ( target != null )\r
202                                         {\r
203                                                 string[] commandLineArgs = Environment.GetCommandLineArgs();\r
204                                                 if ( commandLineArgs != null && commandLineArgs.Length > 1 )\r
205                                                 {\r
206                                                         string arg = null;\r
207                                                         for ( int j = 1; j < commandLineArgs.Length; j++ )\r
208                                                         {\r
209                                                                 if ( j == 1 )\r
210                                                                 {\r
211                                                                         arg += commandLineArgs[ j ];\r
212                                                                 }\r
213                                                                 else\r
214                                                                 {\r
215                                                                         arg += " " + "\"" + commandLineArgs[ j ] + "\"";\r
216                                                                 }\r
217                                                         }\r
218 \r
219 //Trace.TraceInformation( "Message=" + arg + ", len(w/o null)=" + arg.Length );\r
220 \r
221                                                         if ( arg != null )\r
222                                                         {\r
223                                                                 FDK.CSendMessage.sendmessage( target.MainWindowHandle, current.MainWindowHandle, arg );\r
224                                                         }\r
225                                                 }\r
226                                                 break;\r
227                                         }\r
228                                         #endregion\r
229                                         else\r
230                                         {\r
231                                                 Trace.TraceInformation( "メッセージ送信先のプロセスが見つからず。5回リトライします。" );\r
232                                                 Thread.Sleep( 200 );\r
233                                         }\r
234                                 }\r
235                         }\r
236                 }\r
237         }\r
238 }\r