アプリ版:「スタンプのみでお礼する」機能のリリースについて

こんにちわ。

VC6.0でWindowsNT4.0上で動作しているプロセス一覧及びスレッド
一覧を取得するツールを作成したいのですが、アドバイス下さい。

プロセス一覧に関しては、EnumProcessesを使用すればいいのかな?
とめぼしはついたのですが、スレッド一覧の取得で壁に当たって
います。

NT5.0以降であればCreateToolhelp32Snapshotなんかを使用して
いけそうな感じもするのですが。

よろしくお願いします。

A 回答 (4件)

実行中スレッド監視という処理概念で定義しますね。



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を列挙します。

複雑で申し訳ないのですが一例としてどうでしょうか・・?
    • good
    • 0

別スレッドが属するウインドウがアクティブにならない限り


自己スレッドのままになりますね・・・。
ブロードキャストでアクティブにすることもできますが、
処理がグズグスになるためフックは避けたほうがよさそうです。
スレッドIDを引数として取るAPI関数などでエラー(無効ID)
検出を使って0からスレッド最大個数整数値のループから拾う
こともできるかもしれませんが・・。

あとはキー名はわかりませんが、レジストリ参照とか・・。
(結局参考にならず、すみません・・・)
    • good
    • 0
この回答へのお礼

ありがとうございました。

完全に満足するものは作成できませんでしたが、それなりのものは作成することが出来ました。何より、いろいろとフック関係の勉強になりました。

お礼日時:2007/06/26 11:04

#1です。


"pEnd"変数は無視してください、未定義ゴミ変数です。
    • good
    • 0
この回答へのお礼

度々のフォローありがとうございます。
再度、質問させてください。

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

お礼日時:2007/06/13 15:33

<定義>


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一致するタイトル名をツリー階層表示するのが良いと思いますよ。
参考にしてみてください。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
おっしゃっている意味は大体理解できました。

ただ、GetWindowThreadProcessIdだと、トップレベルウィンドウを
作成したスレッドのIDを取得する感じですよね。

例えば、マルチスレッドのアプリケーションなどの場合は複数の
スレッドが生成されていると思うのですが、その複数のスレッド
すべてのIDを取得するのは難しいのですかね?

質問ばかりで申し訳ありません。

お礼日時:2007/05/31 14:20

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!