多重起動を防止するやつをパワーアップさせたい。
多重起動を防止するやつをパワーアップさせたい。
多重起動を防止する方法なら知っているのですが、多重起動できないソフトを起動させた状態で同一ソフトを起動させようとした時に元々起動していた方のソフトのウインドウをアクティブにするということはできないのでしょうか?
WinXPにてCtrl+Alt+Deleteを押すと出てくるタスクマネージャのような。
WinXPにてCtrl+Alt+Deleteを押すと出てくるタスクマネージャのような。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
Re: 多重起動を防止するやつをパワーアップさせたい。
2重起動防止はFindWindowかミューテックスを使用していると思いますが、
他にファイルマッピングという方法もあります。
CreateFileMapping
というAPIを調べてみてください。
簡単にいうとメモリをプロセス間で共有するということです。
他にファイルマッピングという方法もあります。
CreateFileMapping
というAPIを調べてみてください。
簡単にいうとメモリをプロセス間で共有するということです。
ありがとうございました。とりあえずBasicHelpに載ってないようなのでBackSearchABで探して、サンプルが無いのでググルさんに聞いたのですが・・・
http://www.microsoft.com/japan/develope ... apping.htm
C言語は読めるので移植する上で問題は無いのですが、SECURITY_ATTRIBUTES構造体がどのようなものか分かりません。誰か知ってる人いますか?
ちなみに、GetLastError()で183が返るかどうかで2重起動をチェックしてました。
http://www.microsoft.com/japan/develope ... apping.htm
コード: 全て選択
HANDLE CreateFileMapping(
HANDLE hFile, // ファイルのハンドル
LPSECURITY_ATTRIBUTES lpAttributes, // セキュリティ
DWORD flProtect, // 保護
DWORD dwMaximumSizeHigh, // サイズを表す上位 DWORD
DWORD dwMaximumSizeLow, // サイズを表す下位 DWORD
LPCTSTR lpName // オブジェクト名
);
コード: 全て選択
'ActiveBasic調に直してみる。
Declare Function CriateFileMapping Lib "kernel32" (
hFile As HANDLE,
lpAttributes As LPSECURITY_ATTRIBUTES,
flProtect As DWord,
dwMaximumSizeHigh As DWord,
dwMaximumSizeLow As DWord,
lpName As BytePtr) As HANDLE
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
Re: 多重起動を防止するやつをパワーアップさせたい。
こっちへのレスです(^^;多重起動できないソフトを起動させた状態で同一ソフトを起動させようとした時に元々起動していた方のソフトのウインドウをアクティブにする
コード: 全て選択
Type PROCESSENTRY32
dwSize As DWord
cntUsage As DWord
th32ProcessID As DWord
th32DefaultHeapID As *DWord
th32ModuleID As DWord
cntThreads As DWord
th32ParentProcessID As DWord
pcPriClassBase As Long
dwFlags As DWord
szExeFile[ELM(MAX_PATH)] As Byte
End Type
Const TH32CS_SNAPPROCESS=2
Declare Function CreateToolhelp32Snapshot Lib "kernel32" (dwFlag As DWord,th32ProcessID As DWord) As HANDLE
Declare Function Process32First Lib "kernel32" (hSnapshot As HANDLE,ByRef lppe As PROCESSENTRY32) As Long
Declare Function Process32Next Lib "kernel32" (hSnapshot As HANDLE,ByRef lppe As PROCESSENTRY32) As Long
Declare Function EnumWindows Lib "user32" (lpEnumFunc As VoidPtr,lParam As LPARAM) As Long
Function EnumWindowsProc(hWnd As HWND,lParam As LPARAM) As Long
Dim dwProcessId As DWord
'同じ名前のEXEの可視ウィンドウをすべてアクティブ表示
GetWindowThreadProcessId(hWnd,VarPtr(dwProcessId))
If dwProcessId=lParam And IsWindowVisible(hWnd)<>0 Then ShowWindow(hWnd,SW_SHOW)
EnumWindowsProc=1
End Function
Dim hSnapHandle As HANDLE
Dim udtProcessEntry32 As PROCESSENTRY32
'プロセスを列挙
hSnapHandle=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)
With udtProcessEntry32
.dwSize=SizeOf(PROCESSENTRY32)
If Process32First(hSnapHandle,udtProcessEntry32) Then
Do
'自分と同じファイル名か?
If lstrcmpi(.szExeFile,"test.exe")=0 Then
'自分自身は対象から外す
If .th32ProcessID<>GetCurrentProcessId() Then
'ウィンドウ列挙
EnumWindows(AddressOf(EnumWindowsProc),.th32ProcessID)
End If
End If
Loop While Process32Next(hSnapHandle,udtProcessEntry32)
End If
End With
CloseHandle(hSnapHandle)
簡単にしか実験していないので、ひょっとしたら動作がおかしいかもしれませんが、そのときは細かいところをいろいろ変更してみてください(^^;;
[hira]
http://hira.hopto.org/
http://hira.hopto.org/
> C言語は読めるので移植する上で問題は無いのですが、SECURITY_ATTRIBUTES構造体がどのようなものか分かりません。誰か知ってる人いますか?
>コード: 全て選択
> 'ActiveBasic調に直してみる。 > Declare Function CriateFileMapping Lib "kernel32" ( > hFile As HANDLE, > lpAttributes As LPSECURITY_ATTRIBUTES, > flProtect As DWord, > dwMaximumSizeHigh As DWord, > dwMaximumSizeLow As DWord, > lpName As BytePtr) As HANDLE >
コード: 全て選択
Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (
hFile As HANDLE,
lpAttributes As *SECURITY_ATTRIBUTES,
flProtect As DWord,
dwMaximumSizeHigh As DWord,
dwMaximumSizeLow As DWord,
lpName As BytePtr) As HANDLE
SECURITY_ATTRIBUTES構造体はCreateFile等でも使用されるもので、
ハンドルを継承する(?)場合なんかで使われるらしいですが・・・。
よくわからないのでいつもNULL渡してます。
NULLの場合デフォルトの設定が使われるらしいので問題ないはずです。
ちなみにhiraさんのコードの方が大変そうですがより正確にできますね。
なぜだろ。
hiraさんのコードの先頭に#consoleと付け加えて一番下にSleep(1000000)と書き足して・・・
とりあえずテストしてみたのですが、普通に多重起動します・・・
一応、#promptでもやってみましたが多重起動します。
スペック
OS:WindowsXP HomeEdition SP2
CPU:3GHz、デュアルコア
(デバイスマネージャの表記:Intel(R) Pentium(R) 4 CPU 3.00GHz)
メモリ:512MB
とりあえずテストしてみたのですが、普通に多重起動します・・・
コード: 全て選択
#console
Type PROCESSENTRY32
dwSize As DWord
cntUsage As DWord
th32ProcessID As DWord
th32DefaultHeapID As *DWord
th32ModuleID As DWord
cntThreads As DWord
th32ParentProcessID As DWord
pcPriClassBase As Long
dwFlags As DWord
szExeFile[ELM(MAX_PATH)] As Byte
End Type
Const TH32CS_SNAPPROCESS=2
Declare Function CreateToolhelp32Snapshot Lib "kernel32" (dwFlag As DWord,th32ProcessID As DWord) As HANDLE
Declare Function Process32First Lib "kernel32" (hSnapshot As HANDLE,ByRef lppe As PROCESSENTRY32) As Long
Declare Function Process32Next Lib "kernel32" (hSnapshot As HANDLE,ByRef lppe As PROCESSENTRY32) As Long
Declare Function EnumWindows Lib "user32" (lpEnumFunc As VoidPtr,lParam As LPARAM) As Long
Function EnumWindowsProc(hWnd As HWND,lParam As LPARAM) As Long
Dim dwProcessId As DWord
'同じ名前のEXEの可視ウィンドウをすべてアクティブ表示
GetWindowThreadProcessId(hWnd,VarPtr(dwProcessId))
If dwProcessId=lParam And IsWindowVisible(hWnd)<>0 Then ShowWindow(hWnd,SW_SHOW)
EnumWindowsProc=1
End Function
Dim hSnapHandle As HANDLE
Dim udtProcessEntry32 As PROCESSENTRY32
'プロセスを列挙
hSnapHandle=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)
With udtProcessEntry32
.dwSize=SizeOf(PROCESSENTRY32)
If Process32First(hSnapHandle,udtProcessEntry32) Then
Do
'自分と同じファイル名か?
If lstrcmpi(.szExeFile,"test.exe")=0 Then
'自分自身は対象から外す
If .th32ProcessID<>GetCurrentProcessId() Then
'ウィンドウ列挙
EnumWindows(AddressOf(EnumWindowsProc),.th32ProcessID)
End If
End If
Loop While Process32Next(hSnapHandle,udtProcessEntry32)
End If
End With
CloseHandle(hSnapHandle)
Sleep(1000000)
スペック
OS:WindowsXP HomeEdition SP2
CPU:3GHz、デュアルコア
(デバイスマネージャの表記:Intel(R) Pentium(R) 4 CPU 3.00GHz)
メモリ:512MB
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
すみません、多重起動防止機能は省略して書いていました(^^;;
ミューテックスで判断しておけばいいかな、と思ったので…。
とりあえず、この検索処理を利用して多重起動防止をしようとすると
です。
ミューテックスで判断しておけばいいかな、と思ったので…。
とりあえず、この検索処理を利用して多重起動防止をしようとすると
コード: 全て選択
Type PROCESSENTRY32
dwSize As DWord
cntUsage As DWord
th32ProcessID As DWord
th32DefaultHeapID As *DWord
th32ModuleID As DWord
cntThreads As DWord
th32ParentProcessID As DWord
pcPriClassBase As Long
dwFlags As DWord
szExeFile[ELM(MAX_PATH)] As Byte
End Type
Const TH32CS_SNAPPROCESS=2
Declare Function CreateToolhelp32Snapshot Lib "kernel32" (dwFlag As DWord,th32ProcessID As DWord) As HANDLE
Declare Function Process32First Lib "kernel32" (hSnapshot As HANDLE,ByRef lppe As PROCESSENTRY32) As Long
Declare Function Process32Next Lib "kernel32" (hSnapshot As HANDLE,ByRef lppe As PROCESSENTRY32) As Long
Declare Function EnumWindows Lib "user32" (lpEnumFunc As VoidPtr,lParam As LPARAM) As Long
Function EnumWindowsProc(hWnd As HWND,lParam As LPARAM) As Long
Dim dwProcessId As DWord
GetWindowThreadProcessId(hWnd,VarPtr(dwProcessId))
If dwProcessId=lParam And IsWindowVisible(hWnd)<>0 Then ShowWindow(hWnd,SW_RESTORE)
EnumWindowsProc=1
End Function
Dim hSnapHandle As HANDLE
Dim udtProcessEntry32 As PROCESSENTRY32
'プロセスを列挙
hSnapHandle=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)
With udtProcessEntry32
.dwSize=SizeOf(PROCESSENTRY32)
If Process32First(hSnapHandle,udtProcessEntry32) Then
Do
'自分と同じファイル名か?
If lstrcmpi(.szExeFile,"test.exe")=0 Then
'自分自身は対象から外す
If .th32ProcessID<>GetCurrentProcessId() Then
'ウィンドウ列挙
EnumWindows(AddressOf(EnumWindowsProc),.th32ProcessID)
'自分自身を終了する
CloseHandle(hSnapHandle)
End
End If
End If
Loop While Process32Next(hSnapHandle,udtProcessEntry32)
End If
End With
CloseHandle(hSnapHandle)
[hira]
http://hira.hopto.org/
http://hira.hopto.org/
私の場合
というのを私の場合は、多重起動できないソフトを起動させた状態で同一ソフトを起動させようとした時に元々起動していた方のソフトのウインドウをアクティブにするということはできないのでしょうか?
ミューテックスで判断して多重起動していたらRegisterWindowMessageで何かメッセージを取得し、SendMessageで全てのウインドウに送っています。
メッセージループ内にRegisterWindowMessageのメッセージを調べる部分を作っておいて、最初から起動している方は強引にアクティブにします。
一方、あとから起動したほうは、メッセージを送信後に終了します。
私のソフトで使っている方法です。
hiraさんのコードで多重起動は解決しました。ありがとうございました。
ところで、どうやって元から起動していた実行ファイルの窓をアクティブにするかが分かりません。
システム系無知ですみません^^;
そもそも私はミューテックスがどのようなものか知らずにレス返してましたが、BackSearchABで調べたらGetLastError関数で確実に183(ERROR_ALREADY_EXISTS)が返るようにするものかなと解釈したところです。間違ってたら指摘してやってください。
ところで、どうやって元から起動していた実行ファイルの窓をアクティブにするかが分かりません。
システム系無知ですみません^^;
そもそも私はミューテックスがどのようなものか知らずにレス返してましたが、BackSearchABで調べたらGetLastError関数で確実に183(ERROR_ALREADY_EXISTS)が返るようにするものかなと解釈したところです。間違ってたら指摘してやってください。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
確かに、いきなりEnumWindows関数は難しいですね。konisi さんが書きました:> hiraさんのコードで多重起動は解決しました。ありがとうございました。
> ところで、どうやって元から起動していた実行ファイルの窓をアクティブにするかが分かりません。
>
> システム系無知ですみません^^;
しかし、英語名からある程度意味は推測できると思います。
このEnumWindows関数は現在デスクトップ上で実行中のあらゆるプログラムのウィンドウハンドルを列挙、つまり簡単にいうとウィンドウを1つずつ順番にお目当てのウィンドウハンドルが得られるまで調べていくものです。
コード: 全て選択
Declare Function EnumWindows Lib "user32" (lpEnumFunc As VoidPtr,lParam As LPARAM) As Long
Function EnumWindowsProc(hWnd As HWND,lParam As LPARAM) As Long
Dim dwProcessId As DWord
GetWindowThreadProcessId(hWnd,VarPtr(dwProcessId))
If dwProcessId=lParam And IsWindowVisible(hWnd)<>0 Then ShowWindow(hWnd,SW_RESTORE)
EnumWindowsProc=1
End Function
アクティブにしています。
この場合、ウィンドウを所有しているスレッドが属するプロセスIDが等しいかどうかで判断しているようですね。
よって、hira様のプログラムは非常に安全性が高い方法だと言えます。
ウィンドウ名やウィンドウクラスで調べる方法もありますが、
その場合、同じ名前のウィンドウが存在すると致命的なバグが発生します。
イメージとしてはそれで合っています。konisi さんが書きました:> そもそも私はミューテックスがどのようなものか知らずにレス返してましたが、BackSearchABで調べたらGetLastError関数で確実に183(ERROR_ALREADY_EXISTS)が返るようにするものかなと解釈したところです。間違ってたら指摘してやってください。
~余談~
私の場合、共有メモリで実現します。
最初に起動したアプリケーションでは共有メモリを新規作成し、
共有メモリに自分のウィンドウハンドルを書き込んでおきます。
次に実行されるプログラムでは共有メモリの新規作成に失敗するので、
そのタイミングで共有メモリからウィンドウハンドルを取り出して、
アクティブ化した後、自分自身を終了させるという方法です。
ありがとうございました。
なんとなく分かっていました。皆さん、ありがとうございました。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
ここ以外の場所では「暇人13世」というHNを主として使用。
に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。