No.3ベストアンサー
- 回答日時:
実行中スレッド監視という処理概念で定義しますね。
1.SetWindowsHookEx()で、ForegroundIdleProc を渡す
つまり、システム上の全スレッドを監視します。
2.任意スレッドが実行されたらフックプロシージャが
呼び出されるのでここで、GetCurrentThreadId() 関数を
使います。
プロシージャからチェインする前に共有変数
<例>(DWORD th[65535]と定義)にスレッドIDをストア。
<例> for (int i=0;i<=インデックス;i++)
if (th[i]==スレッドID) break;
if (インデックス^i-1) th[インデックス++]=スレッドID
3.2の処理をTSR処理(常駐)させます。
4.メインアプリケーションでは共有変数を参照してIDを列挙します。
複雑で申し訳ないのですが一例としてどうでしょうか・・?
No.4
- 回答日時:
別スレッドが属するウインドウがアクティブにならない限り
自己スレッドのままになりますね・・・。
ブロードキャストでアクティブにすることもできますが、
処理がグズグスになるためフックは避けたほうがよさそうです。
スレッドIDを引数として取るAPI関数などでエラー(無効ID)
検出を使って0からスレッド最大個数整数値のループから拾う
こともできるかもしれませんが・・。
あとはキー名はわかりませんが、レジストリ参照とか・・。
(結局参考にならず、すみません・・・)
ありがとうございました。
完全に満足するものは作成できませんでしたが、それなりのものは作成することが出来ました。何より、いろいろとフック関係の勉強になりました。
No.2
- 回答日時:
#1です。
"pEnd"変数は無視してください、未定義ゴミ変数です。
度々のフォローありがとうございます。
再度、質問させてください。
SetWindowsHookExなどをいろいろと調べて、私が望んでいる仕様に
するには、システムフックにする必要があること。そうするには
DLL化する必要があることなどは分かりました。
で、自分なりにコーディングしてみて、デバッカで確認しました。
SetWindowsHookExで指定したプロシージャが頻繁に呼ばれている
ようですが、GetCurrentThreadIdの値が毎回同じになります。
ちなみに、このIdはDLL関数を呼び出す、メイン側のスレッドIdと
同じことも確認しました。
このような現象に関してなにか知識をお持ちでないでしょうか?
参考までにソースです
///// Cppファイル /////
#include "MyHooker.h"
int WINAPI DllMain(HINSTANCE hInstance , DWORD dwReason , PVOID pvReserved)
{
ghDllInst = hInstance;
memset(gdwThreadIds, NULL, MAXWORD);
return(TRUE);
}
BOOL Hook()
{
ghHook = SetWindowsHookEx(WH_FOREGROUNDIDLE, (HOOKPROC)Procedure, ghDllInst, 0);
if(ghHook) return(TRUE);
return(FALSE);
}
BOOL UnHook()
{
if(ghHook) UnhookWindowsHookEx(ghHook);
ghHook = NULL;
return(TRUE);
}
LRESULT CALLBACK Procedure(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode < 0) return(CallNextHookEx(ghHook, nCode, wParam, lParam));
DWORD dwThreadId = GetCurrentThreadId();
for(int i = 0; i < MAXWORD; i++) {
if(gdwThreadIds[i] == dwThreadId) break;
if(gdwThreadIds[i] == NULL) {
gdwThreadIds[i] = dwThreadId;
break;
}
}
return CallNextHookEx(ghHook, nCode, wParam, lParam);
}
///// ヘッダーファイル /////
#define DLL_EXPORT __declspec (dllexport)
#include "windows.h"
#pragma data_seg(".ShareData")
HHOOKghHook= NULL;
#pragma data_seg()
HINSTANCEghDllInst= NULL;
DLL_EXPORT BOOL Hook();
DLL_EXPORT BOOL UnHook();
DLL_EXPORT LRESULT CALLBACK Procedure(int nCode, WPARAM wParam, LPARAM lParam);
///// Defファイル /////
LIBRARY
SECTIONS
.ShareData READ WRITE SHARED
No.1
- 回答日時:
<定義>
typedef BOOL (WINAPI *_EnumProcesses)(DWORD*,DWORD,DWORD*);
typedef BOOL (WINAPI *_EnumProcessModules)(HANDLE,HMODULE*,DWORD,LPDWORD);
typedef DWORD (WINAPI *_GetModuleBaseName)(HANDLE,HMODULE,LPTSTR,DWORD);
_EnumProcesses EnumProcesses;
_EnumProcessModules EnumProcessModules;
_GetModuleBaseName GetModuleBaseName;
<処理>
HMODULE hDll,hModule[1];
HANDLE hToken, hProcess;
TOKEN_PRIVILEGES tp;
LUID luid;
CHAR pBuf[256];
DWORD pID[255],pNum=0,pNum2=0,i;
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken);
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid);
tp.PrivilegeCount=1;
tp.Privileges[0].Luid=luid;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
hDll=LoadLibrary("psapi.dll");
EnumProcesses=(_EnumProcesses)GetProcAddress(hDll,"EnumProcesses");
EnumProcessModules=(_EnumProcessModules)GetProcAddress(hDll,"EnumProcessModules");
GetModuleBaseName=(_GetModuleBaseName)GetProcAddress(hDll,"GetModuleBaseNameA");
i=(EnumProcesses)(pID,sizeof(pID),&pNum);
pNum/=sizeof(DWORD);
for (i=0,pEnd=true;i<pNum;i++)
{
hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,pID[i]);
if (!hProcess) {CloseHandle(hProcess);continue;}
(EnumProcessModules)(hProcess,hModule,sizeof(hModule),&pNum2);
(GetModuleBaseName)(hProcess,hModule[0],pBuf,sizeof(pBuf));
// pBuf=プロセス名
CloseHandle(hProcess);
}
CloseHandle(hToken);
FreeLibrary(hDll);
がシステムプロセス(WinLogon.exe など)も列挙する一例ですが、
スレッド名はEnumWindowsを使います。
そもそもスレッドは名目実体がないため、列挙トップウインドウの
ハンドルからタイトルとスレッドID(GetWindowThreadProcessId)
を取得して、列挙終了後に昇順に並べたスレッドIDごとに
ID一致するタイトル名をツリー階層表示するのが良いと思いますよ。
参考にしてみてください。
ご回答ありがとうございます。
おっしゃっている意味は大体理解できました。
ただ、GetWindowThreadProcessIdだと、トップレベルウィンドウを
作成したスレッドのIDを取得する感じですよね。
例えば、マルチスレッドのアプリケーションなどの場合は複数の
スレッドが生成されていると思うのですが、その複数のスレッド
すべてのIDを取得するのは難しいのですかね?
質問ばかりで申し訳ありません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- グループウェア slackについて取り急ぎ教えて頂きたいことがあります 2 2022/04/08 09:05
- YouTube 【Youtube】アーカイブ動画でチャットした人の、ユーザー名と内容を一覧で取得する方法はありますか 2 2022/08/10 23:31
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- CPU・メモリ・マザーボード CPUについて 4 2022/07/09 13:41
- PHP isset — 変数が宣言されていること、そして null とは異なることを検査 1 2022/03/27 17:34
- CPU・メモリ・マザーボード 安価ノートPC検討で教えてください 7 2022/05/02 09:25
- Visual Basic(VBA) 別シートのデータを参照して値を入れたい。 まとめデータシートのC列D列の値を商品一覧シートのコードが 7 2022/08/17 13:20
- その他(お金・保険・資産運用) 信用情報の閲覧について 2 2022/06/02 19:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
参照カウンタについてその3
-
pthread_cond_wait での mutex
-
C言語で一定時間待機後、再実行
-
スレッドの終了の仕方
-
スレッドの終了はどうやるんで...
-
スレッドにて同一メモリの書き...
-
C言語である関数への同時アクセ...
-
WaitForSingleObjectの使い方に...
-
スレッドの安全な終了のさせ方
-
C++ GUIのメッセージループ。
-
スレッドの監視方法について
-
マルチスレッドでブレイクポイ...
-
_beginthreadexについて
-
VB2005 シリアル通信のClose処理
-
待機関数(WaitForMultipleObjec...
-
マイクロソフトedge で5チャン...
-
Macターミナルで実行中のプログ...
-
緯度、経度の 10進法と 60進法...
-
VBSの処理中一旦処理を止めて再...
-
小数点を含む数値かどうか判断...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
WaitForSingleObjectの使い方に...
-
スレッドにて同一メモリの書き...
-
VC++スレッドの正しい終了のさ...
-
スレッドの監視方法について
-
Windows上で、シグナル(SIGTERM...
-
スレッドの終了の仕方
-
スレッドの安全な終了のさせ方
-
CWnd::OnTimerのスレッドの取得
-
MFC通信プログラムマルチスレッ...
-
Linuxでスレッド優先度って変え...
-
.netアプリへのSendMessageでフ...
-
VB2005 シリアル通信のClose処理
-
別スレッドからメインダイアロ...
-
マルチスレッドについて
-
スレッドの終了はどうやるんで...
-
マルチスレッドプログラミング...
-
別スレッドのデータを受信できない
-
特定のスレッドの破棄
-
msec単位のWait Timerが作れない!
-
C# スレッド終了の監視について
おすすめ情報