起動しているプロセスのフルパスを取得するには?


コロン  2009-11-02 03:57:25  No: 71043

質問させて頂きます。
現在、起動しているプロセス一覧のフルパスを取得するコードを書いております。
スナップショットからプロセスIDを基にプロセスのフルパスを取得しようとしておりますが
うまく動きません。

OSの関係上、PSAPIは使わず、ToolHelpで解決したいと思っています。
下記に現在試しているコードを記述致しますので、ご教授の程よろしくお願いします。

    HANDLE          hSnapshot;
    HANDLE          hHandle;
    PROCESSENTRY32  process;
    MODULEENTRY32   me;
    TCHAR           szFile[ MAX_PATH + 1 ];

    hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    if( hSnapshot != INVALID_HANDLE_VALUE )
    {
        process.dwSize = sizeof(PROCESSENTRY32);
        if( Process32First( hSnapshot, &process ) )
        {
            do
            {
                hHandle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID );
                if( hHandle != NULL )
                {
                    ZeroMemory( &me, sizeof(me) );
                    me.dwSize = sizeof(MODULEENTRY32);
                    Module32First( hHandle, &me );

                    do
                    {
                        GetModuleFileName( me.hModule, szFile, MAX_PATH );
                    } while( Module32Next( hHandle, &me ) );
                    CloseHandle( hHandle );
                }
            } while ( Process32Next( hSnapshot,&process ) );
        }
        CloseHandle( hSnapshot );
    }


オショウ  2009-11-02 05:51:36  No: 71044

それを動作させたいOSは何でしょう・・・

またそれを扱うプロセスの権限も必要だったかと思います。

因みに、私は、GetModuleFileNameExで取れてます。
尚、OSは、Vista/Win7でできてます。

WinXPなら、そこまでの制限は無い・・・はずなので、できる
と思いますが、WinXPでは未確認です。

※  余談ながら・・・
    Vista/Win7なら、そのプロセスが管理者権限を所有しているかも
    判断できますヨ
    http://social.msdn.microsoft.com/Forums/ja-JP/vcgeneralja/thread/5da58090-7b67-4bd3-84b5-63f8f3332ba8

以上。参考まで


オショウ  2009-11-02 06:36:22  No: 71045

GetModuleFileNameExは、psapi.h/PSAPI.lib/PSAPI.dll必須ですネ〜
すいません・・・

GetModuleFileName の方で可能かは、多分、OSに依存すると思います。
(あくまで多分・・・)

以上。


コロン  2009-11-02 06:48:32  No: 71046

オショウさん、レス有難うございます
記載したコードはXP SP2で動かしましたが、うまく動いてはおりません

process.th32ProcessIDからプロセスハンドルを取得して云々では
うまく行かないのかなと現在色々と調べております

9x系でも動いて欲しい為、PSAPIは使わないようしております
引き続き、ご教授の程よろしくお願いします。


オショウ  2009-11-02 10:03:23  No: 71047

PSAPI使ってますが・・・

C++ CLI でのコードですが、参考にして下さい。
尚、VISTA/Win7で動作するようになってますので、セッションの
判断も加味されてます。

尚、ループで取得している部分のコードです。
詳細については・・・推測して下さい。

    do{
      String^ exeFile;
      String^ exePath;
      String^ UserName;;
      String^ DomainName;;
      WCHAR fileName[MAX_PATH];
      DWORD length;
      HANDLE  hToken;
      MarshalString(procEntry.szExeFile, exeFile);
      DWORD  winlogonSessId = 0;
      if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId ){
        hProcess = OpenProcess(MAXIMUM_ALLOWED, false, procEntry.th32ProcessID);
        p1->Add(procEntry.cntUsage);
        p2->Add(procEntry.th32ProcessID);
        p3->Add(procEntry.th32ModuleID);
        p4->Add(procEntry.cntThreads);
        p5->Add(procEntry.th32ParentProcessID);
        p6->Add(procEntry.pcPriClassBase);
        p7->Add(exeFile);
        bRet = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
        if (bRet){
          PTOKEN_USER  ptu;
              GetTokenInformation(hToken, TokenUser, NULL, 0, &length);
          ptu = (PTOKEN_USER)LocalAlloc(LPTR, length);
              bRet = GetTokenInformation(hToken, TokenUser, (LPVOID)ptu, length, &length);
          if (bRet){
            WCHAR  szUser[MAX_PATH];
            WCHAR  szDomain[MAX_PATH];
            DWORD  lUser;
            DWORD  lDomain;
            SID_NAME_USE  snu;

            lUser = MAX_PATH;
            lDomain = MAX_PATH;
              bRet = LookupAccountSid(NULL, ptu->User.Sid, szUser, &lUser, szDomain, &lDomain, &snu);
            if (bRet){
              MarshalString(szUser, UserName);
              MarshalString(szDomain, DomainName);
              p9->Add(UserName + "/" + DomainName);
            } else
              p9->Add("");
          } else
            p9->Add("");
          LocalFree(ptu);
          CloseHandle(hToken);
        }else
          p9->Add("");
        p10->Add(IsCurrentUserLocalAdministrator((IntPtr)hProcess));
        length = GetModuleFileNameEx(hProcess, (HMODULE)procEntry.th32ModuleID, fileName, length);
        if (length > 0){
          MarshalString(fileName, exePath);
          p8->Add(exePath);
        } else {
          p8->Add("");
        }
        CloseHandle(hProcess);
      }
    } while (Process32Next(hSnap, &procEntry) != 0);


オショウ  2009-11-02 10:10:36  No: 71048

こんなん見つけましたが・・・

http://tokovalue.web.infoseek.co.jp/GetModuleFileName2_U.htm

以上。参考まで


コロン  2009-11-02 17:00:11  No: 71049

オショウさん

細かくご教授頂き有難うございます
挙げて頂きましたURLをざっと見てみましたが、9x系だけは
            Do While f
                sname = StrZToStr(proc.szExeFile)
                List1.AddString sname
                f = Api_Process32Next(hSnap, proc)
            Loop
と処理されていますので、恐らく9x系で動かした場合、EXE名だけで表示されると思います

PSAPIを使わずに解決は、どうやら難しいようですね…
PSAPIを使う場合はオショウさんの書きこんで頂いたコードを参考にさせて頂きたいと思います。

有難うございます。
只、もう少しだけ解決策を募ってみます。
どうぞよろしくお願いします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加