ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Win32APIコミュの各プロセスのユーザー(アカウント)を取得したい

  • mixiチェック
  • このエントリーをはてなブックマークに追加
プロセス一覧自体は、PSAPI の EnumProcesses または PDH の PdhEnumObjectItems(オブジェクトを"Process"としてインスタンス一覧を取得)によって取得できています。

そこから、各プロセスのユーザー(タスクマネージャの「ユーザー名」の列に表示されている、SYSTEM、NETWORK SERVICE、ログインアカウント等の値)を取得する方法が分かりません。

ご存知の方、ご教示よろしくお願いします。

コメント(4)

 実際にやってみた事は無いので的外れな回答になってしまうかも知れませんが、次のような感じで出来るのではないかと思います。

 EnumProcesses( ) で得られたプロセス ID の配列の各要素に対して OpenProcess( ) してプロセスハンドルを取得し、そのプロセスハンドルから OpenProcessToken( ) でプロセストークンを取得し、GetTokenInformation( ) で TokenUser を指定し、トークンに関連するユーザ情報構造体 TOKEN_USER を得ます。
 TOKEN_USER 内にはセキュリティ識別子がメンバ要素 .Sid として格納されているので、これを使って LookupAccountSid( ) を実行すれば、アカウント名とドメイン名を得られると思います。

 各 API 関数に関しては MSDN を参照してみてください。
khurataさん、早速のアドバイスありがとうございました。教えていただいた方針に沿って、あれこれ調べながら、なんとか出来ました。
以下、100%は理解できていませんが、C++のソースです。(QtCreatorを使っているのでQt固有のコードが若干混じっています)

QString qStr = ""; //データ表示用
//
// プロセス一覧取得処理
//
const int MAX_LEN = 1024; //プロセスID格納配列のサイズ
DWORD procID[MAX_LEN]; //プロセスID格納配列
DWORD rtnLen; //返されるデータのサイズ
EnumProcesses(procID, MAX_LEN, &rtnLen);

//プロセスの個数
DWORD cntProc = rtnLen / sizeof(DWORD);

//以下、プロセスの個数分、繰り返し
for(DWORD i=0; i<cntProc; i++)
{
    TCHAR procName[MAX_PATH] = TEXT("<unknown>"); //プロセス名格納配列
    TCHAR procUser[MAX_PATH] = TEXT("<unknown>"); //プロセスのユーザー格納配列
    TCHAR procDomain[MAX_PATH] = TEXT("<unknown>"); //プロセスのドメイン格納配列
    
    //プロセスのハンドルを取得
    HANDLE hProc = OpenProcess(
                        PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                        FALSE,
                        procID[i]);
    //
    // プロセス名取得処理
    //
    if (NULL != hProc)
    {
        HMODULE hMod;
        DWORD cbNeeded;
        if (EnumProcessModules(hProc, &hMod, sizeof(hMod), &cbNeeded))
        {
            GetModuleBaseName(hProc, hMod, procName, sizeof(procName)/sizeof(TCHAR));
        }
    }
(つづく)
(つづき)
    //
    // プロセスのユーザーおよびドメイン取得処理
    //
    if (NULL != hProc)
    {
        //トークンのハンドルを取得
        DWORD dwLength;
        HANDLE hToken;
        PTOKEN_USER pTokenUser;
        OpenProcessToken(hProc, TOKEN_QUERY, &hToken);
        //トークンユーザー情報を取得
        GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength);
        pTokenUser = (PTOKEN_USER)LocalAlloc(LPTR, dwLength);
        GetTokenInformation(hToken, TokenUser, pTokenUser, dwLength, &dwLength);
        //SID(セキュリティ識別子)からユーザー名とドメイン名を取得
        DWORD dwSizeUser = sizeof(procUser) / sizeof(TCHAR);
        DWORD dwSizeDomain = sizeof(procDomain) / sizeof(TCHAR);
        SID_NAME_USE sidName;
        LookupAccountSid(
            NULL,
            pTokenUser->User.Sid,
            procUser,
            &dwSizeUser,
            procDomain,
            &dwSizeDomain,
            &sidName);
        //破棄
        LocalFree(pTokenUser);
        CloseHandle(hToken);
    }
    CloseHandle(hProc);

    // プロセスID : プロセス名 : ユーザー : ドメイン
    qStr += QString::number(procID[i])
         + " : " + QString::fromWCharArray(procName)
         + " : " + QString::fromWCharArray(procUser)
         + " : " + QString::fromWCharArray(procDomain)
         + "\n";
}
//表示
ui->txtTest->setText(qStr);
 良かったです、少しはお役に立てたようで幸いです。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Win32API 更新情報

Win32APIのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング