Solution46
LibLogOut.cpp
[詳解]
1 //=============================================================================
2 /// @file
3 /// ログ出力ライブラリ実装ファイル
4 ///
5 /// ログ出力ライブラリ実装ファイルです。
6 ///
7 /// $Id: LibLogOut.cpp 245 2019-03-20 15:03:41Z admin $
8 /// $Date: 2019-03-21 00:03:41 +0900 (2019/03/21 (木)) $
9 /// $Author: admin $
10 ///
11 /// @attention なし
12 
13 #pragma managed( push, off )
14 
15 //=============================================================================
16 // インクルードファイル
17 #include <LibLogOut.h>
18 #include <CSyncAuto.h>
19 #include <CProcess.h>
20 #include <CDebug.h>
21 #include <CConsole.h>
22 #include <LibUtility.h>
23 #include <stdio.h>
24 
25 //=============================================================================
26 // インクルード実装ファイル
27 #include <LibCommon.hpp>
28 
29 //=============================================================================
30 // ログ出力ライブラリ名前空間
31 namespace LibLogOut {
32  //=========================================================================
33  // ログ出力ライブラリクラス
34  //=========================================================================
35  // 構築子と解体子
36  //-------------------------------------------------------------------------
37  // コンストラクタ
39  // 基底クラスコンストラクタ
40  : CMapping()
41  , CStreamOut()
42  // メンバ変数初期化
43  , m_psMappingInfo( nullptr )
44  , m_cEventRequest()
45  , m_cEventNotify()
46  , m_cFileLog()
47  , m_cThreadSub()
48  , m_szExeFile()
49  {
50  // コンストラクタ実行通知
52 
53  // 処理ブロック
54  bool result = false;
55  do {
56  // 実行モジュールファイルパスを取得する
57  GetExeFileName( m_szExeFile, MAX_PATH );
58 
59  // マッピングメモリを作成する
60  if ( !Create( sizeof( SMappingInfo ), OBJECT_NAME ) ) {
61  // 致命的エラー!
63  break;
64  }
65  // 同期処理ブロック
66  else do {
67  CSyncAuto cSyncAuto( *this );
68 
69  // 共有メモリ情報構造体ポインタを取得する
70  m_psMappingInfo = reinterpret_cast< SMappingInfo* >( GetView() );
71  if ( nullptr == m_psMappingInfo ) {
72  // 致命的エラー!
74  break;
75  }
76 
77  // プロセス情報を巡回する
78  DWORD dwProcessId = ::GetCurrentProcessId();
79  for ( int nIndex = 0;; ++nIndex ) {
80  // インデックスを調べる
81  if ( PROCESS_MAX <= nIndex ) {
82  // 致命的エラー!
84  break;
85  }
86  // プロセスIDを調べる
87  else if ( 0 == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
88  // プロセスIDを設定する
89  m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId = dwProcessId;
90  break;
91  }
92  }
93 
94  // 要求イベントを作成する
95  wchar_t szBuffer[ MAX_PATH ];
96  ::swprintf_s( szBuffer, EVENT_REQUEST_FORMAT, dwProcessId );
97  if ( !m_cEventRequest.Create( szBuffer ) ) {
98  // 致命的エラー!
100  break;
101  }
102  // 通知イベントを作成する
103  else if ( !m_cEventNotify.Create( EVENT_NOTIFY_NAME ) ) {
104  // 致命的エラー!
106  break;
107  }
108  // 新規作成か調べる
109  else if ( IsCreate() ) {
110  // デバイス種別を巡回する
111  for ( int nIndex = 0; DEVICE_MAX > nIndex; ++nIndex ) {
112  // 出力許可フラグを設定する
113  m_psMappingInfo->m_bEnable[ nIndex ] = true;
114 
115  // 出力プロセスIDを設定する
116  m_psMappingInfo->m_dwProcessId[ nIndex ] = dwProcessId;
117  }
118 
119  // 新規ログ出力ファイルパスを取得する
120  wchar_t szPath[ MAX_PATH ];
121  if ( !GetNewLogFilePath( szPath, MAX_PATH ) ) {
122  // 致命的エラー!
124  break;
125  }
126 
127  // パスをコピーする
128  ::wcscpy_s( m_psMappingInfo->m_szPath, szPath );
129 
130  // ログ出力ファイルを作成する
131  if ( !m_cFileLog.Create( m_psMappingInfo->m_szPath ) ) {
132  // 致命的エラー!
134  break;
135  }
136  }
137  // ログ出力ファイルを追記モードでオープンする
138  else if ( !m_cFileLog.OpenAppend( m_psMappingInfo->m_szPath ) ) {
139  // 致命的エラー!
141  break;
142  }
143 
144  // 参照プロセスカウントをインクリメントする
146 
147  // サブスレッドを起動する
148  if ( !m_cThreadSub.Create( SubThreadProc, this ) ) {
149  // 致命的エラー!
151  break;
152  }
153 
154  // 成功!
155  result = true;
156  } while ( false );
157  } while ( false );
158 
159  // 実行結果を調べる
160  if ( !result ) {
161  // サブスレッドをクローズする
162  m_cThreadSub.Close();
163 
164  // ファイルをクローズする
165  m_cFileLog.Close();
166 
167  // 通知イベントをクローズする
168  m_cEventNotify.Close();
169 
170  // 要求イベントをクローズする
171  m_cEventRequest.Close();
172 
173  // マッピングをクローズする
174  Close();
175  }
176  }
177 
178  //-------------------------------------------------------------------------
179  // デストラクタ
181  // デストラクタ実行通知
183 
184  // 同期処理ブロック
185  do {
186  CSyncAuto cSyncAuto( *this );
187 
188  // プロセス情報を更新する
189  UpdateProcessInfo( true );
190 
191  // 参照プロセスカウントを調べる
192  if ( 0 == m_psMappingInfo->m_nReffer ) {
193  // バッファカウントを調べる
194  if ( 0 < m_psMappingInfo->m_nCount ) {
195  // フラッシュする
196  Flush();
197  ConsoleNewLine();
198  }
199 
200  // コンソールウィンドウハンドルを調べる
201  if ( nullptr != ConsoleWindowHandle() ) {
202  // 終了演出をするかどうかしらべる
203  if ( true ) {
204  // コンソール入力バッファをクリアする
206 
207  // 巡回する
208  wchar_t const* pszMessage = L"ダイセンジガケ ダラナヨサ";
209  for ( ;; ++pszMessage ) {
210  // キー入力を調べる
211  if ( ConsoleKbHitDirect() ) {
212  // 終了!
213  break;
214  }
215  // 文字コードを調べる
216  else if ( L'\0' == *pszMessage ) {
217  // 巡回する
218  for ( int nIndex = 0; 100 > nIndex; ++nIndex ) {
219  // キー入力を調べる
220  if ( ConsoleKbHitDirect() ) {
221  // 終了!
222  break;
223  }
224 
225  // 少し待つ
226  ::Sleep( 10 );
227  }
228  ConsoleNewLine();
229  break;
230  }
231  // 文字コードを調べる
232  else if ( L' ' == *pszMessage ) {
233  // 巡回する
234  for ( int nIndex = 0; 50 > nIndex; ++nIndex ) {
235  // キー入力を調べる
236  if ( ConsoleKbHitDirect() ) {
237  // 終了!
238  break;
239  }
240 
241  // 少し待つ
242  ::Sleep( 10 );
243  }
244  }
245  else {
246  // 巡回する
247  for ( int nIndex = 0; 25 > nIndex; ++nIndex ) {
248  // キー入力を調べる
249  if ( ConsoleKbHitDirect() ) {
250  // 終了!
251  break;
252  }
253 
254  // 少し待つ
255  ::Sleep( 10 );
256  }
257 
258  // 1文字出力する
259  ConsoleChar( *pszMessage );
260  }
261  }
262  }
263  }
264  }
265  } while ( false );
266  }
267 
268  //=========================================================================
269  // 公開関数
270  //-------------------------------------------------------------------------
271  // 文字列出力関数
272  bool CLibLogOut::OutputString( wchar_t const* pszString ) noexcept {
273  // 処理ブロック
274  bool result = false;
275  do {
276  // 文字列ポインタを調べる
277  if ( nullptr == pszString ) {
278  // 失敗!
279  break;
280  }
281  // 同期処理ブロック
282  else do {
283  CSyncAuto cSyncAuto( *this );
284 
285  // 巡回する
286  for ( ;; ++pszString ) {
287  // 文字コードを調べる
288  if ( L'\0' == *pszString ) {
289  // 成功!
290  result = true;
291  break;
292  }
293  // バッファカウントを調べる
294  else if ( BUFFER_SIZE <= m_psMappingInfo->m_nCount ) {
295  // フラッシュする
296  if ( !Flush() ) {
297  // 致命的エラー!
299  break;
300  }
301  // バッファカウントを調べる
302  else if ( BUFFER_SIZE <= m_psMappingInfo->m_nCount ) {
303  // 致命的エラー!
305  break;
306  }
307  }
308 
309  // 文字列バッファに1文字追加する
311  }
312  } while ( false );
313  } while ( false );
314 
315  // 実行結果を返す
316  return result;
317  }
318 
319  //-------------------------------------------------------------------------
320  // 行番号更新関数
322  // 同期処理ブロック
323  bool result = false;
324  do {
325  CSyncAuto cSyncAuto( *this );
326 
327  // 行番号をインクリメントする
329  } while ( false );
330 
331  // 実行結果を返す
332  return result;
333  }
334 
335  //-------------------------------------------------------------------------
336  // 行番号取得関数
337  int CLibLogOut::GetLineNumber() noexcept {
338  // 同期処理ブロック
339  int result = 0;
340  do {
341  CSyncAuto cSyncAuto( *this );
342 
343  // 行番号を取得する
344  result = m_psMappingInfo->m_nLine;
345  } while ( false );
346 
347  // 実行結果を返す
348  return result;
349  }
350 
351  //-------------------------------------------------------------------------
352  // インデントカウント取得関数
353  int CLibLogOut::GetIndentCount() noexcept {
354  // 同期処理ブロック
355  int result = 0;
356  do {
357  CSyncAuto cSyncAuto( *this );
358 
359  // インデントカウントを取得する
360  result = m_psMappingInfo->m_nIndent;
361  } while ( false );
362 
363  // 実行結果を返す
364  return result;
365  }
366 
367  //-------------------------------------------------------------------------
368  // インデント関数
369  bool CLibLogOut::Indent() noexcept {
370  // 同期処理ブロック
371  bool result = false;
372  do {
373  CSyncAuto cSyncAuto( *this );
374 
375  // プロセス情報を更新する
377 
378  // インデントカウントをインクリメントする
380 
381  // 巡回する
382  DWORD dwProcessId = ::GetCurrentProcessId();
383  for ( int nIndex = 0;; ++nIndex ) {
384  // インデックスを調べる
385  if ( PROCESS_MAX <= nIndex ) {
386  // 致命的エラー!
388  break;
389  }
390  // プロセスIDを調べる
391  else if ( dwProcessId == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
392  // インデントカウントをインクリメントする
393  ++m_psMappingInfo->m_sProcess[ nIndex ].m_nIndent;
394 
395  // 成功!
396  result = true;
397  break;
398  }
399  }
400  } while ( false );
401 
402  // 実行結果を返す
403  return result;
404  }
405 
406  //-------------------------------------------------------------------------
407  // アンインデント関数
408  bool CLibLogOut::Unindent() noexcept {
409  // 同期処理ブロック
410  bool result = false;
411  do {
412  CSyncAuto cSyncAuto( *this );
413 
414  // プロセス情報を更新する
416 
417  // インデントカウントをデクリメントする
419 
420  // 巡回する
421  DWORD dwProcessId = ::GetCurrentProcessId();
422  for ( int nIndex = 0;; ++nIndex ) {
423  // インデックスを調べる
424  if ( PROCESS_MAX <= nIndex ) {
425  // 致命的エラー!
427  break;
428  }
429  // プロセスIDを調べる
430  else if ( dwProcessId == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
431  // インデントカウントをデクリメントする
432  --m_psMappingInfo->m_sProcess[ nIndex ].m_nIndent;
433 
434  // 成功!
435  result = true;
436  break;
437  }
438  }
439  } while ( false );
440 
441  // 実行結果を返す
442  return result;
443  }
444 
445  //-------------------------------------------------------------------------
446  // 参照プロセスカウント取得関数
447  int CLibLogOut::GetRefferCount() noexcept {
448  // 同期処理ブロック
449  int result = 0;
450  do {
451  CSyncAuto cSyncAuto( *this );
452 
453  // 参照プロセスカウントを取得する
454  result = m_psMappingInfo->m_nReffer;
455  } while ( false );
456 
457  // 実行結果を返す
458  return result;
459  }
460 
461  //-------------------------------------------------------------------------
462  // バッファカウント取得関数
463  int CLibLogOut::GetCount() noexcept {
464  // 同期処理ブロック
465  int result = 0;
466  do {
467  CSyncAuto cSyncAuto( *this );
468 
469  // バッファカウントを取得する
470  result = m_psMappingInfo->m_nCount;
471  } while ( false );
472 
473  // 実行結果を返す
474  return result;
475  }
476 
477  //-------------------------------------------------------------------------
478  // フラッシュ関数
479  bool CLibLogOut::Flush() noexcept {
480  // 同期処理ブロック
481  bool result = false;
482  do {
483  CSyncAuto cSyncAuto( *this );
484 
485  // プロセス情報を更新する
487 
488  // 出力バッファを巡回する
489  DWORD dwProcessId = ::GetCurrentProcessId();
490  for ( int nIndex = 0, nCount = m_psMappingInfo->m_nCount;; ) {
491  // 残り文字数を調べる
492  if ( nCount <= nIndex ) {
493  // バッファカウントをクリアする
495 
496  // 成功!
497  result = true;
498  break;
499  }
500 
501  // 出力文字コードを巡回する
502  m_psMappingInfo->m_nRequestPos = nIndex;
504  for ( ; nCount > nIndex; ++nIndex ) {
505  // 出力要求サイズをインクリメントする
507 
508  // 文字コードを調べる
509  if ( L'\n' == m_psMappingInfo->m_szBuffer[ nIndex ] ) {
510  // インデックスをインクリメントする
511  ++nIndex;
512 
513  // 終了!
514  break;
515  }
516  }
517 
518  // 出力デバイスを巡回する
519  for ( int nDevice = 0; DEVICE_MAX > nDevice; ++nDevice ) {
520  // 出力許可フラグを調べる
521  if ( m_psMappingInfo->m_bEnable[ nDevice ] ) {
522  // 出力デバイス種別を設定する
523  m_psMappingInfo->m_eDevice = static_cast< EOutputDevice >( nDevice );
524 
525  // 出力プロセスIDを調べる
526  bool bResult = false;
527  if ( 0 != m_psMappingInfo->m_dwProcessId[ nDevice ] ) {
528  // 出力プロセスIDを調べる
529  if ( dwProcessId != m_psMappingInfo->m_dwProcessId[ nDevice ] ) {
530  // 要求イベントをオープンする
531  wchar_t szBuffer[ MAX_PATH ];
532  ::swprintf_s( szBuffer, EVENT_REQUEST_FORMAT, m_psMappingInfo->m_dwProcessId[ nDevice ] );
533  CEvent cRequest;
534  if ( cRequest.Open( szBuffer ) ) {
535  // 要求イベントをセットする
536  if ( cRequest.Set() ) {
537  // 通知イベントを待機する
538  if ( m_cEventNotify.Wait( NOTIFY_WAIT ) ) {
539  // 成功!
540  bResult = true;
541  }
542  }
543  }
544  }
545  }
546 
547  // 実行結果を調べる
548  if ( !bResult ) {
549  // カレントプロセスでデバイス出力する
550  OutputDevice();
551  }
552  }
553  }
554  }
555  } while ( false );
556 
557  // 実行結果を返す
558  return result;
559  }
560 
561  //-------------------------------------------------------------------------
562  // 出力デバイスプロセス設定関数
563  bool CLibLogOut::SetDeviceProcess( EOutputDevice eDevice, DWORD dwProcessId ) noexcept {
564  // 同期処理ブロック
565  bool result = false;
566  do {
567  CSyncAuto cSyncAuto( *this );
568 
569  // プロセス情報を更新する
571 
572  // プロセス情報を巡回する
573  for ( int nIndex = 0;; ++nIndex ) {
574  // インデックスを調べる
575  if ( PROCESS_MAX <= nIndex ) {
576  // 失敗!
577  break;
578  }
579  // プロセスIDを調べる
580  else if ( dwProcessId == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
581  // 出力プロセスIDを設定する
582  m_psMappingInfo->m_dwProcessId[ static_cast< int >( eDevice ) ] = dwProcessId;
583 
584  // 成功!
585  result = true;
586  break;
587  }
588  }
589  } while ( false );
590 
591  // 実行結果を返す
592  return result;
593  }
594 
595  //=========================================================================
596  // 限定公開関数
597  //-------------------------------------------------------------------------
598  // プロセス情報更新関数
599  bool CLibLogOut::UpdateProcessInfo( bool bCurrent ) noexcept {
600  // 同期処理ブロック
601  bool result = false;
602  do {
603  CSyncAuto cSyncAuto( *this );
604 
605  // プロセス情報を巡回する
606  DWORD dwProcessId = ::GetCurrentProcessId();
607  for ( int nIndex = 0;; ++nIndex ) {
608  // インデックスを調べる
609  if ( PROCESS_MAX <= nIndex ) {
610  // 成功!
611  result = true;
612  break;
613  }
614  // プロセスIDを調べる
615  else if ( 0 == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
616  // 継続!
617  continue;
618  }
619  // プロセスIDを調べる
620  else if ( dwProcessId == m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) {
621  // カレントプロセス削除フラグを調べる
622  if ( !bCurrent ) {
623  // 継続!
624  continue;
625  }
626  }
627  else {
628  // プロセスをオープンする
629  CProcess cProcess;
630  if ( cProcess.Open( m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId ) ) {
631  // プロセス実行状態を調べる
632  if ( !cProcess.Wait( 0 ) ) {
633  // プロセスをクローズする
634  cProcess.Close();
635 
636  // 継続!
637  continue;
638  }
639 
640  // プロセスをクローズする
641  cProcess.Close();
642  }
643  }
644 
645  // インデックスカウントを減算する
647 
648  // 参照プロセスカウントを調べる
649  if ( 0 == m_psMappingInfo->m_nReffer ) {
650  // 致命的エラー!
652  break;
653  }
654 
655  // 参照プロセスカウントをデクリメントする
656  wchar_t const* pszMessage = L"";
657  if ( 0 == --m_psMappingInfo->m_nReffer ) {
658  // 生成消滅演算子情報更新ログを出力する
659  pszMessage = L", All Processes Termination";
660  }
661 
662  // プロセス終了ログを出力する
663  ExOutputLineFormat( true, false, L"Indent#%ld, By Terminated Process[%04X], Count = %ld%s."
667  , pszMessage );
668 
669  // デバイス種別を巡回する
670  for ( int nDevice = 0; DEVICE_MAX > nDevice; ++nDevice ) {
671  // プロセスIDを調べる
672  if ( m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId == m_psMappingInfo->m_dwProcessId[ nDevice ] ) {
673  // デバイス種別を巡回する
674  for ( int nDevice2 = 0;; ++nDevice2 ) {
675  // インデックスを調べる
676  if ( DEVICE_MAX <= nDevice2 ) {
677  // プロセスIDを設定する
678  m_psMappingInfo->m_dwProcessId[ nDevice ] = dwProcessId;
679  break;
680  }
681  // プロセスIDを調べる
682  else if ( ( 0 != m_psMappingInfo->m_dwProcessId[ nDevice2 ] ) && ( m_psMappingInfo->m_sProcess[ nIndex ].m_dwProcessId != m_psMappingInfo->m_dwProcessId[ nDevice2 ] ) ) {
683  // プロセスIDを設定する
684  m_psMappingInfo->m_dwProcessId[ nDevice ] = m_psMappingInfo->m_dwProcessId[ nDevice2 ];
685  break;
686  }
687  }
688  }
689  }
690 
691  // プロセス情報をクリアする
693  m_psMappingInfo->m_sProcess[ nIndex ].m_nIndent = 0;
694  }
695  } while ( false );
696 
697  // 実行結果を返す
698  return result;
699  }
700 
701  //-------------------------------------------------------------------------
702  // デバイス出力関数
703  bool CLibLogOut::OutputDevice() noexcept {
704  // 処理ブロック
705  bool result = false;
706  do {
707  // 文字列ポインタを取得する
708  wchar_t* pszString = &m_psMappingInfo->m_szBuffer[ m_psMappingInfo->m_nRequestPos ];
709 
710  // 終端文字を保存する
711  wchar_t ch = pszString[ m_psMappingInfo->m_nRequestSize ];
712 
713  // 終端文字を設定する
714  pszString[ m_psMappingInfo->m_nRequestSize ] = L'\0';
715 
716  // 出力要求デバイス種別を調べる
717  switch ( m_psMappingInfo->m_eDevice ) {
718  case EOutputDevice::Debug: // デバッグ出力
719  // デバッグ出力する
720  DebugString( pszString );
721 
722  // 成功!
723  result = true;
724  break;
725 
726  case EOutputDevice::Console: // コンソール出力
727  // コンソール出力する
728  ConsoleString( pszString );
729 
730  // 成功!
731  result = true;
732  break;
733 
734  case EOutputDevice::File: // ファイル出力
735  // ファイル出力する
736  m_cFileLog.OutputString( pszString );
737 
738  // 成功!
739  result = true;
740  break;
741  }
742 
743  // 終端文字を復元する
744  pszString[ m_psMappingInfo->m_nRequestSize ] = ch;
745  } while ( false );
746 
747  // 実行結果を返す
748  return result;
749  }
750 
751  //=========================================================================
752  // 静的公開関数
753  //-------------------------------------------------------------------------
754  // プロジェクト種別取得関数
755  wchar_t const* CLibLogOut::GetProjectType() noexcept {
756  // プロジェクト種別文字列を返す
757  return _PROJECT_TYPE;
758  }
759 
760  //-------------------------------------------------------------------------
761  // インスタンスハンドル取得関数
762  HINSTANCE CLibLogOut::GetInstanceHandle() noexcept {
763 #if defined( _WINDLL ) && !defined( _MANAGED )
764 
765  // インスタンスハンドルを返す
766  return s_hInstance;
767 
768 # else
769 
770  // 実行モジュールのインスタンスハンドルを返す
771  return ::GetModuleHandleW( nullptr );
772 
773 # endif
774  }
775 
776  //=========================================================================
777  // 静的限定公開関数
778  //-------------------------------------------------------------------------
779  // サブスレッド関数
780  DWORD CLibLogOut::SubThreadProc( LPVOID lpParam ) noexcept {
781  // 処理ブロック
782  DWORD result = 0;
783  do {
784  // インスタンスポインタを取得する
785  CLibLogOut*& rpcInstance = reinterpret_cast< CLibLogOut*& >( lpParam );
786  if ( nullptr == rpcInstance ) {
787  // 致命的エラー!
789  break;
790  }
791  // 巡回する
792  else for ( ;; ) {
793  // 要求イベントを待つ
794  if ( rpcInstance->m_cEventRequest.Wait() ) {
795  // デバイスに出力する
796  rpcInstance->OutputDevice();
797 
798  // 通知イベントをセットする
799  rpcInstance->m_cEventNotify.Set();
800  }
801  }
802  } while ( false );
803 
804  // 実行結果を返す
805  return result;
806  }
807 
808  //-------------------------------------------------------------------------
809  // 新規ログ出力ファイルパス取得関数
810  bool CLibLogOut::GetNewLogFilePath( wchar_t* pszPath, int nSize ) noexcept {
811  // 処理ブロック
812  bool result = false;
813  do {
814  // 実行ファイルパスを取得する
815  GetExeFilePath( pszPath, nSize );
816 
817  // ファイルパスを分解する
818  wchar_t szDrive[ _MAX_DRIVE ];
819  wchar_t szDir [ _MAX_DIR ];
820  wchar_t szFName[ _MAX_FNAME ];
821  wchar_t szExt [ _MAX_EXT ];
822  if ( 0 != ::_wsplitpath_s( pszPath, szDrive, szDir, szFName, szExt ) ) {
823  // 失敗!
824  break;
825  }
826  // ファイル検索文字列を作成する
827  else if ( 0 >= ::swprintf_s( pszPath, nSize, L"%s%s%s#??.log", szDrive, szDir, szFName ) ) {
828  // 失敗!
829  break;
830  }
831 
832  // ファイルを検索する
833  WORD wNumber = 0;
834  WIN32_FIND_DATAW sFindData;
835  HANDLE hFind = ::FindFirstFileW( pszPath, &sFindData );
836  if ( INVALID_HANDLE_VALUE != hFind ) {
837  // 巡回する
838  long long unsigned llMax = 0;
839  for ( ;; ) {
840  // ファイルパスを作成する
841  if ( 0 < ::swprintf_s( pszPath, nSize, L"%s%s%s", szDrive, szDir, sFindData.cFileName ) ) {
842  // ファイルをオープンする
843  HANDLE handle = ::CreateFileW( pszPath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, nullptr );
844  if ( INVALID_HANDLE_VALUE != handle ) {
845  // 更新日時を取得する
846  FILETIME time;
847  if ( 0 != ::GetFileTime( handle, nullptr, nullptr, &time ) ) {
848  // 更新日時を比較する
849  long long unsigned tmp = ( static_cast< long long unsigned >( time.dwHighDateTime ) << 32 ) | static_cast< long long unsigned >( time.dwLowDateTime );
850  if ( llMax <= tmp ) {
851  // 最大値を更新する
852  llMax = tmp;
853 
854  // ログ出力ファイル番号を取得する
855  wNumber = static_cast< WORD >( ( ::wcstol( &sFindData.cFileName[ ::wcslen( szFName ) + 1 ], nullptr, 10 ) + 1 ) % 100 );
856  }
857  }
858 
859  // ファイルハンドルをクローズする
860  ::CloseHandle( handle );
861  }
862  }
863 
864  // 次のファイルを検索する
865  if ( 0 == ::FindNextFileW( hFind, &sFindData ) ) {
866  // 終了!
867  break;
868  }
869  }
870 
871  // ファイル検索ハンドルをクローズする
872  ::FindClose( hFind );
873  }
874 
875  // 新規ログ出力ファイルパスを作成する
876  ::swprintf_s( pszPath, nSize, L"%s%s%s#%02u.log", szDrive, szDir, szFName, wNumber );
877 
878  // 成功!
879  result = true;
880  } while ( false );
881 
882  // 実行結果を返す
883  return result;
884  }
885 
886  //=========================================================================
887  // 静的限定公開文字列定数
888  wchar_t const* const CLibLogOut::OBJECT_NAME = L"LibLogOut::CLibLogOut";
889  wchar_t const* const CLibLogOut::EVENT_REQUEST_FORMAT = L"LibLogOut::CLibLogOut.EventRequest#%04X";
890  wchar_t const* const CLibLogOut::EVENT_NOTIFY_NAME = L"LibLogOut::CLibLogOut.EventNotify";
891 
892  //=========================================================================
893  // 静的限定公開変数
895 }
896 
897 #pragma managed( pop )
virtual bool Open(wchar_t const *pszObjectName) noexcept
オープン関数
Definition: CEvent.cpp:92
#define NotifyConstructor()
コンストラクタ実行通知マクロ
Definition: LibUtility.h:24
static wchar_t const * GetProjectType() noexcept
プロジェクト種別取得関数
Definition: LibLogOut.cpp:755
デバッグクラスヘッダファイル
共有メモリ情報構造体
Definition: LibLogOut.h:377
virtual bool SetDeviceProcess(EOutputDevice eDevice, DWORD dwProcessId) noexcept
出力デバイスプロセス設定関数
Definition: LibLogOut.cpp:563
virtual bool Flush() noexcept
フラッシュ関数
Definition: LibLogOut.cpp:479
#define NotifyFatalError()
致命的エラー発生通知マクロ
Definition: LibUtility.h:22
virtual void Close() noexcept override
クローズ関数
Definition: CProcess.cpp:46
static wchar_t const *const EVENT_NOTIFY_NAME
通知イベント名
Definition: LibLogOut.h:407
共通ライブラリ実装ヘッダファイル
ログ出力ライブラリクラス
Definition: LibLogOut.h:64
int m_nRequestPos
出力要求開始位置
Definition: LibLogOut.h:388
static DWORD WINAPI SubThreadProc(LPVOID lpParam) noexcept
サブスレッド関数
Definition: LibLogOut.cpp:780
CEvent m_cEventRequest
要求イベント
Definition: LibLogOut.h:396
static CLibLogOut s_cInstance
静的インスタンス
Definition: LibLogOut.h:412
ログ出力ライブラリ名前空間
Definition: LibLogOut.h:56
#define NotifyDestructor()
デストラクタ実行通知マクロ
Definition: LibUtility.h:25
static HINSTANCE GetInstanceHandle() noexcept
インスタンスハンドル取得関数
Definition: LibLogOut.cpp:762
virtual LPVOID GetView() const noexcept
ビューポインタ取得関数
Definition: CMapping.h:79
virtual bool OutputString(wchar_t const *pszString) noexcept override
文字列出力関数
Definition: CFileStream.cpp:38
virtual bool UpdateProcessInfo(bool bCurrent=false) noexcept
プロセス情報更新関数
Definition: LibLogOut.cpp:599
CLibLogOut() noexcept
コンストラクタ
Definition: LibLogOut.cpp:38
SMappingInfo * m_psMappingInfo
共有メモリ情報構造体ポインタ
Definition: LibLogOut.h:395
wchar_t m_szPath[MAX_PATH]
ログ出力ファイルパス
Definition: LibLogOut.h:383
プロセスクラスヘッダファイル
virtual bool Indent() noexcept override
インデント関数
Definition: LibLogOut.cpp:369
static bool GetNewLogFilePath(wchar_t *pszPath, int nSize) noexcept
新規ログ出力ファイルパス取得関数
Definition: LibLogOut.cpp:810
virtual bool IsCreate() const noexcept
新規作成状態取得関数
Definition: CSync.h:81
EOutputDevice
出力デバイス種別列挙体
Definition: LibLogOut.h:75
#define _PROJECT_TYPE
プロジェクト種別定義
Definition: LibCommonDef.h:88
#define ConsoleNewLine()
改行出力マクロ
Definition: CConsole.h:29
イベントクラス
Definition: CEvent.h:30
virtual bool Wait(DWORD dwTime=INFINITE) noexcept
ウェイト関数
Definition: CSync.cpp:59
#define ConsoleChar(...)
1文字出力マクロ
Definition: CConsole.h:26
virtual bool Unindent() noexcept override
アンインデント関数
Definition: LibLogOut.cpp:408
EOutputDevice m_eDevice
出力要求デバイス種別
Definition: LibLogOut.h:387
virtual bool Open(DWORD dwProcessId, DWORD dwAccess=SYNCHRONIZE) noexcept
オープン関数
Definition: CProcess.cpp:114
DWORD m_dwProcessId[DEVICE_MAX]
出力プロセスID配列
Definition: LibLogOut.h:385
static wchar_t const *const OBJECT_NAME
オブジェクト名
Definition: LibLogOut.h:405
int m_nIndent
インデントカウント
Definition: LibLogOut.h:367
int m_nIndent
インデントカウント
Definition: LibLogOut.h:381
static wchar_t const *const EVENT_REQUEST_FORMAT
要求イベント名書式設定文字列
Definition: LibLogOut.h:406
virtual int GetCount() noexcept
バッファカウント取得関数
Definition: LibLogOut.cpp:463
自動同期クラス
Definition: CSyncAuto.h:30
virtual ~CLibLogOut() noexcept
デストラクタ
Definition: LibLogOut.cpp:180
virtual bool Set() noexcept
シグナルセット関数
Definition: CEvent.cpp:130
ストリーム出力クラス
Definition: CStreamOut.h:30
SProcessInfo m_sProcess[PROCESS_MAX]
参照プロセス情報構造体配列
Definition: LibLogOut.h:386
コンソール入出力クラスヘッダコンソール
#define ConsoleString(...)
文字列出力マクロ
Definition: CConsole.h:27
int m_nReffer
参照プロセスカウント
Definition: LibLogOut.h:378
int m_nRequestSize
出力要求サイズ
Definition: LibLogOut.h:389
virtual int GetRefferCount() noexcept
参照プロセスカウント取得関数
Definition: LibLogOut.cpp:447
static DWORD const NOTIFY_WAIT
通知イベント待機時間
Definition: LibLogOut.h:353
virtual int GetIndentCount() noexcept override
インデントカウント取得関数
Definition: LibLogOut.cpp:353
virtual bool UpdateLineNumber() noexcept override
行番号更新関数
Definition: LibLogOut.cpp:321
virtual bool OutputDevice() noexcept
デバイス出力関数
Definition: LibLogOut.cpp:703
マッピングクラス
Definition: CMapping.h:30
wchar_t m_szBuffer[BUFFER_SIZE+1]
文字列バッファ
Definition: LibLogOut.h:379
#define ConsoleWindowHandle()
ウィンドウハンドル取得マクロ
Definition: CConsole.h:44
int m_nCount
バッファカウント
Definition: LibLogOut.h:380
virtual bool Create(DWORD dwSize, wchar_t const *pszObjectName=nullptr) noexcept
作成関数
Definition: CMapping.cpp:65
LIB_COMMON_API wchar_t const * GetExeFileName(wchar_t *pszBuffer, size_t uSize) noexcept
実行ファイル名取得関数
Definition: LibUtility.cpp:272
自動同期クラスヘッダファイル
#define ConsoleKbHitDirect()
直接入力検査マクロ
Definition: CConsole.h:63
bool m_bEnable[DEVICE_MAX]
出力許可フラグ配列
Definition: LibLogOut.h:384
LIB_COMMON_API wchar_t const * GetExeFilePath(wchar_t *pszBuffer, size_t uSize) noexcept
実行ファイルパス取得関数
Definition: LibUtility.cpp:225
プロセスクラス
Definition: CProcess.h:30
#define ConsoleClearInput()
入力バッファクリアマクロ
Definition: CConsole.h:64
static int const DEVICE_MAX
出力デバイス最大値
Definition: LibLogOut.h:85
virtual int GetLineNumber() noexcept override
行番号取得関数
Definition: LibLogOut.cpp:337
virtual bool ExOutputLineFormat(bool bHeader, bool bIndent, wchar_t const *pszFormat,...) noexcept
拡張書式設定文字列行出力関数
Definition: CStreamOut.cpp:315
CFileStream m_cFileLog
ログ出力ファイル
Definition: LibLogOut.h:398
CEvent m_cEventNotify
通知イベント
Definition: LibLogOut.h:397
virtual void Close() noexcept override
クローズ関数
Definition: CMapping.cpp:48
virtual bool OutputString(wchar_t const *pszString) noexcept override
文字列出力関数
Definition: LibLogOut.cpp:272
DWORD m_dwProcessId
プロセスID
Definition: LibLogOut.h:366
ユーティリティライブラリヘッダファイル
static int const PROCESS_MAX
最大参照プロセス数
Definition: LibLogOut.h:352
#define DebugString(...)
文字列出力マクロ
Definition: CDebug.h:24
ログ出力ライブラリヘッダファイル