- ベストアンサー
Delphiでデバッグ時の識別はできますか?
現在、2重起動防止のため下記のようなコードにしています。 Delphiではデバッグ実行時のフォームも2重起動の対象となるため、開発環境があるときは、2重起動のチェックをしないようにしてあります。 これでうまく行くのですが、何だか野暮ったい気がします。 こう少しスマートな解決策はないでしょうか? program Sample; uses Forms, Windows, Dialogs, uFrmSample in 'uFrmSample.pas' {frmSample}; {$R *.res} var MainWnd: THandle; begin {Delphi開発環境の存在をチェックする} MainWnd := FindWindow(nil, 'delphi 6'); if MainWnd = 0 then begin {間発環境が実行中でなければ2重起動をチェックする} MainWnd := FindWindow('TFrmSample', nil); if MainWnd <> 0 then begin ShowMessage('既に起動しています'); SetForegroundWindow(MainWnd); Exit; end; end; Application.Initialize; Application.CreateForm(TfrmSample, frmSample); Application.Run; end. 以上、よろしくおねがいします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
実現したいことは(FindWindowではIDE使用時に誤動作してしまうので)FindWindow以外での二重起動の防止ではありませんか。 もしそうでしたらMutexを使ってみてはどうでしょう。「delphi 二重起動防止」などで検索するとたくさん現れます。
その他の回答 (2)
- redfox63
- ベストアンサー率71% (1325/1856)
コンパイルスイッチを参照するようにしてみてはいかがでしょう {$IFOPT D+} // デバッグ情報の生成オプションがついている場合 {$ENDIF} といった具合です
お礼
ご親切な回答ありがとうございます。 動作を確認しました。 しかしこの方法では、リリースするときデバッグオプションを外し忘れると、先の状況と同じになります。 (別にサイズやリバースエンジニアリングに気を使っていないので、通常はデバッグオプションをチェックしたままリリースしています。)
- redfox63
- ベストアンサー率71% (1325/1856)
プロジェクトのオプション > ディレクトリ/条件タブの『条件定義(C)』にDEBUGなどを定義しておきます デバッグ時に実行させたいコードを {$IFDEF DEBUG} // ここにデバッグ時のコードを記述 {$ENDIF} といった具合にしましょう Delphiのヘルプで『条件コンパイル』などを検索してみてください
お礼
すばやい回答ありがとうございます。 私の質問のポイントが曖昧だったようです。ソースコードや環境設定を変えずにデバッグ実行なのかEXEからの実行なのかを識別する方法はないでしょうか? ご指摘の方法だと、直接{$DEFINE DEBUG}と書いてから条件分けするのと同じで、リリースコンパイルするときにDEBUGを削除し忘れる可能性があります。(とういか忘れた経験があります。)
お礼
的確な回答ありがとうございます。 ミューテックスを使った方法は知っていましたが、何だか難しそうなので敬遠していました。 でも、今回の質問を機に"くろねこ研究所"を参考にして、下記のコードで動作確認をしてみました。 program Sample; uses Forms, Windows, Dialogs, uFrmSample in 'uFrmSample.pas' {frmSample}; {$R *.res} var hMutex: THandle; MainWnd: THandle; begin //Mutexを作成する hMutex := CreateMutex(nil, true, 'Sample'); //Mutexが既に存在しているか判断する if (hMutex <> 0) and (GetLastError() = ERROR_ALREADY_EXISTS) then begin //存在していた場合、そのインスタンスを再前面にする MainWnd := FindWindow('TFrmSample', nil); ShowMessage('既に起動しています'); SetForegroundWindow(MainWnd); Exit; //起動中止 end; Application.Initialize; Application.CreateForm(TfrmSample, frmSample); Application.Run; //ミューテックスの開放 if (hMutex <> 0) then ReleaseMutex(hMutex); if (hMutex <> 0) then CloseHandle(hMutex); end. 結果、非常にうまくいっています。 デバッグ実行でもEXEからの実行でも期待どおりの動作をしました。 これからは、ミューテックスを使った方法に切り替えることにします。 (以前からの方法でも同じですが、ユニークな名前を作成するとき注意が必要ですね。)