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で質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
字面がカッコいい英単語
あなたが思う「字面がカッコいい英単語」を教えてください。
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
スレッドの名前の取得について
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
スレッドの監視方法について
-
WaitForSingleObjectの使い方に...
-
DirectX キーが入力されるまで...
-
スレッドの終了はどうやるんで...
-
C#でスレッド実行中のイベント...
-
特定のスレッドの破棄
-
マルチスレッド内のループについて
-
MFC通信プログラムマルチスレッ...
-
スレッドの終了の仕方
-
スレッドの安全な終了のさせ方
-
スレッド内のCString使用
-
VC++スレッドの正しい終了のさ...
-
スレッドについて
-
メインスレッドのPostMessageと...
-
C言語である関数への同時アクセ...
-
Mutexの次の使い方で
-
PHP スレッド構成の掲示板について
-
Macターミナルで実行中のプログ...
-
3のつく数字と3の倍数のみを表...
-
プロダクションコードとは?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
WaitForSingleObjectの使い方に...
-
VC++スレッドの正しい終了のさ...
-
Windows上で、シグナル(SIGTERM...
-
スレッドの安全な終了のさせ方
-
スレッドの監視方法について
-
スレッドにて同一メモリの書き...
-
別スレッドのデータを受信できない
-
スレッドの終了はどうやるんで...
-
同一スレッドで、ロックをかけ...
-
スレッドの終了の仕方
-
別スレッドからメインダイアロ...
-
_beginthreadexで生成したスレ...
-
待機関数(WaitForMultipleObjec...
-
VB2005 シリアル通信のClose処理
-
マルチスレッドについて
-
Linuxでスレッド優先度って変え...
-
msec単位のWait Timerが作れない!
-
自作クラスのイベントを外部ハ...
-
スレッド一覧の取得
-
C# スレッドから親ウィンドウへ...
おすすめ情報