FindWindow() による二重起動防止 – プログラミング – Home

FindWindow() による二重起...
 
通知
すべてクリア

[解決済] FindWindow() による二重起動防止


ゲキアツ
 ゲキアツ
(@ゲキアツ)
ゲスト
結合: 11年前
投稿: 32
Topic starter  

お世話になります。
以前、Mutex による二重起動防止についてご相談させて戴きました。
Windows 7/8.1 に搭載されている音声読み上げアプリ『ナレーター』の起動中に、自分が
作ったアプリを終了させると、タスクマネージャーのバックグラウンド・プロセスに自分
のアプリが残ったままになり、そのため Mutex が検出されて2回目の起動ができなかっ
たのです。
こちらです。
http://rarara.cafe.coocan.jp/cgi-bin/lng/vc/vclng.cgi?print+201403/14030001.txt

解決策として、二重起動防止に FindWindow() 関数を使うことにしました。
アプリの名称を仮に Gekiatsu とします。
コードは下記の通りです。

BOOL CGekiatsuApp::InitInstance()
{
CWnd *pWnd;
pWnd = CWnd::FindWindow(NULL, _T(Gekiatsu));
if (pWnd != NULL)
{
pWnd->ShowWindow(SW_RESTORE);
pWnd->SetForegroundWindow();
return FALSE;
}
}

これで解決できたと思っていたら、このアプリの実行ファイルを Gekiatsu というフォル
ダの中に置くと、起動しないことが判明しました。(例:D:\MyApp\Gekiatsu)
フォルダも Window ということになるのでしょうか?
D:\Gekiatsu\MyApp というように直前が Gekiatsu でなければ起動します。

何かいい解決策はないでしょうか?
よろしくお願いいたします。


引用未解決
トピックタグ
AR2
 AR2
(@ar2)
Estimable Member
結合: 5年前
投稿: 110
 

 ちょっと語弊がありますが、FindWindow()の第2引き数は、トップレベルのウィンドウ
のキャプション文字列(タイトルバーの文字列)なので、どこかに「Gekiatsu」というタ
イトルバーを持ったアプリケーションが起動しているのだと思います。
 具体的には、エクスプローラーで該当フォルダーを開いてんじゃね?と予想しています。
 (エクスプローラーはコントロールパネルでタイトルバーのパス表記をどうするか指定
できます)

 簡単な方法は2重起動を防止するアプリケーションのタイトルバーにパスで使えない文
字を埋めておく、コッソリスペースを足しておくと原理が分かりやすいでしょう。

 次に簡単な方法は、第1引き数を使うことです。
 ドキュメント-ビュー構成であると仮定して、PreCreateWindow()に以下の記述でウィン
ドウのクラス名をユニークである事が保証できる文字列に書き換えてしまうとバッティン
グしなくなります。
 自前でウィンドウ作っているなら、生成時のクラス名を適当なものにすれば良いです。
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 if (cs.lpszName)
  WNDCLASS wc;
  ::GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wc);
  wc.lpszClassName = Lなんかユニークになる文字列、GUIDとかお奨め;
  AfxRegisterClass(&wc);
  cs.lpszClass = wc.lpszClassName;
 }
・・・

 他にもハンドルからプロセス名を取得して一致を見るとか、逆にプロセス一覧からハン
ドルを求めるとか、親プロセスとの関係から取得するとか、いろんな回避方法があります
ので工夫してみてください。
 (ですが、本来はMutexを使うのが王道だと思っています)


返信引用
みい
 みい
(@みい)
ゲスト
結合: 22年前
投稿: 65
 

SetPropで自身に目印をつけておいて、FindWindowで見つけだした
Windowに対してGetPropして目印つけてるWindowか判断している
って処理を見たことがあります。


返信引用
ゲキアツ
 ゲキアツ
(@ゲキアツ)
ゲスト
結合: 11年前
投稿: 32
Topic starter  

AR様、みい様 有り難うございます。
AR様に教えて戴いた、PreCreateWindow()でウィンドウのユニークなクラス名を定義する
方法でクリア出来ました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました