外部アプリの2重起動防止 – プログラミング – Home

外部アプリの2重起動防止
 
通知
すべてクリア

[解決済] 外部アプリの2重起動防止


まりのちゃん
 まりのちゃん
(@まりのちゃん)
ゲスト
結合: 18年前
投稿: 16
Topic starter  

VC++ 6.0で開発しております。

過去スレから外部アプリの2重起動防止についてしらべ、
以下のような実装してみたのですがうまく行きません。

// 既に起動しているか?
if (::FindWindow(NULL,test.exeに設定されているタイトル名) != NULL)
{
return false;
}

// OpenVPNクライアントの起動
ShellExecute(NULL, open, C:\\Program Files\\TEST\\test.exe, NULL, NULL,
SW_SHOWNORMAL);

*test.exe(仮称)は私がVCアプリから起動しようとしている外部アプリケーションで
す。

なにがうまく行かないかというと、上記ロジックだとtest.exeを起動して
ウインドウがオープンしている状態であれば
test.exeに設定されているタイトル名がFindWindowで検知でき、
二重起動を防止できるのですが、
タスクトレイに常駐している状態でウインドウが開いていない状態では
うまく行きません。
どなたか良い方法をご存知方、実装方法をおしえていただけないでしょうか?

ちがう実装方法で、例えばタスクマネージャのプロセスに表示されいるイメージ名
で多重起動を防止できる方法などありましたら教えてください。


引用未解決
トピックタグ
まりのちゃん
 まりのちゃん
(@まりのちゃん)
ゲスト
結合: 18年前
投稿: 16
Topic starter  

すみません。
情報がたりませんでしたので追加します。

作成しようとしているアプリは常駐プロセスではありません。
起動されたタイミングでtest.exeが起動しているか確認し、
起動していればtest.exeを起動せず終了する。
・・・というものです。


返信引用
まりのちゃん
 まりのちゃん
(@まりのちゃん)
ゲスト
結合: 18年前
投稿: 16
Topic starter  

お騒がせしました。
解決!?しました。

方法としましては、
PCで稼動しているプロセス名を全て取得する方法で
該当する~.exeがあるか検索し、
あった場合は起動中とみなし
同exeは起動しないようにしました。
実装ロジックは以下です。

う~んこれでいんでしょうか?
もっと簡単な実装方法ご存知の方いらっしゃましたら
レスをいただければと思います。

DWORD ProcessIDs[1000];
DWORD ProcessNum;
HMODULE Modules[1000];
DWORD ModuleNum;
char FileName[1000];
DWORD RetSize;
DWORD i, j;
HANDLE hProcess;
BOOL bResult;

CString exeName = test.exe;
CString readName;
int findPos = -1;

/* プロセスの一覧と数を取得 */
EnumProcesses(ProcessIDs, sizeof(ProcessIDs), &RetSize);
ProcessNum = RetSize / sizeof(DWORD);

for(i=0; i<ProcessNum; i++)
{
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
ProcessIDs[i]);

if(hProcess == NULL)
{
printf(\tオープン失敗.\n);
} else {
/* プロセス中のモジュールの一覧を取得 */
bResult = EnumProcessModules(hProcess, Modules, sizeof(Modules),
&RetSize);
if(bResult) {
ModuleNum = RetSize / sizeof(HMODULE);

/* 各モジュールのファイル名を表示 */
for(j=0; j<ModuleNum; j++) {
GetModuleFileNameEx(hProcess, Modules[j], FileName, 1000);
readName = FileName;
findPos = readName.Find(exeName, 0);
if (findPos != -1)
{
break;
}
}

if (findPos != -1)
{
break;
}
}
CloseHandle(hProcess);
}

if (findPos == -1)
{
WinExec(C:\\Program Files\\TEST\\test.exe,SW_SHOWNORMAL);
}


返信引用
とるまリンゴ
 とるまリンゴ
(@とるまリンゴ)
ゲスト
結合: 19年前
投稿: 35
 

ミューテックスを使って2重起動防止する方法は、如何でしょう?
これならば、
Googleで「ミューテックス VC」で検索すると、色々でてきますよ。

(例)
http://techtips.belution.com/ja/vc/0025/

http://hp.vector.co.jp/authors/VA019882/tips/data/data01.htm
006 アプリケーションの2重起動を防止する


返信引用
大三元
 大三元
(@大三元)
ゲスト
結合: 18年前
投稿: 54
 

CxxxDlgが元のダイアログクラスだとすると、
xxx.cppのInitInstance()の
// 標準的な初期化処理
// もしこれらの機能を使用せず、実行ファイルのサイズを小さくしたけ
// れば以下の特定の初期化ルーチンの中から不必要なものを削除して
// ください。
のコメントの後に、
以下の記述を追加すればできますよ!!

// アプリケーションの二重起動防止
CString MutexName;
CWnd* pWnd;

MutexName.Format(Link20060703 %s,m_pszExeName);
CMutex mutex(FALSE,MutexName);

// 実行中
if(mutex.Lock(0) == FALSE)
{
pWnd = CWnd::FindWindow(NULL,m_pszAppName);
if(pWnd != NULL)
{
// 実行中のアプリケーションを前面に移動
pWnd->SetForegroundWindow();
}
return FALSE;
}


返信引用
まりのちゃん
 まりのちゃん
(@まりのちゃん)
ゲスト
結合: 18年前
投稿: 16
Topic starter  

すみません。スレの最初の発言で書かなかったでんすが
ミューテックスも試したのですができなかったんですよ~。
やり方がまちがっていたんでしょうかね~?
ミューテックスってそもそも以下のような判定できんるんでしょうか?
例えば
VCアプリからWinEXEで秀丸エディタを起動

その後VCアプリを再実行
 if:秀丸エディタがいたら起動処理を行わない。
else:秀丸エディタ
  ↑ここの判定部分


返信引用
まりのちゃん
 まりのちゃん
(@まりのちゃん)
ゲスト
結合: 18年前
投稿: 16
Topic starter  

まちがえました
 if:秀丸エディタがいたら起動処理を行わない。
else:秀丸エディタ起動
  ↑ここの判定部分

ようはVCで作成したアプリではないものを
判定できるかです。

大三元さんありがとうございます。
大三元さんの方法時間があるときに試してみます。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

ミューテックスでは自分が全く関与できないソフトを排他する事は出来ません。
なので、今の方法で何とかするしかないと思います。

ミューテックスを使う場合と言うのは基本的に自分が作成しているアプリや
システム内での排他制御になると思います。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

ミューテックスを使った方法は、
自分のアプリケーションが多重起動しないように
する時に使うテクニックですので、
外部アプリケーションの場合は使えないでしょう。

外部アプリのEXEファイルパスが分かっているなら、
そのファイルを排他読み取りオープンできるかどうかで
確認するのはいかがでしょうか。

#偶然に、さらに別のアプリがそのEXEを排他読み取りオープン
#している場合も引っかかってしまいますが。


返信引用
まりのちゃん
 まりのちゃん
(@まりのちゃん)
ゲスト
結合: 18年前
投稿: 16
Topic starter  

現行のままでいくことにします。
みなさん情報ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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