アクティブプロセス測定 その4

元々エロゲーの時間を測定しようと思ってたんだけど、エロゲーのプレイ時間ってゲームがアクティブになってるだけじゃなくて、感想書いたりWebみたりする時間も含まれてるトータルの時間ということを考えると、Fateみたいにプロセスの起動時間を測定したほうがいいかな・・・ということで、この企画はボツになりそうだったのですが、Lifehackの一環として仕事中どういうプロセスを起動していたのかを測定すると役立ちそう。一日何してたか・・・というアクティビティは意識してもなかなかつけられないですからね・・・。
んで、できたのですが、使うAPIは前とほとんど同じなので特に書くこともなかったりするんだけど、短いので載せておこう。

ActiveProcInfo.h

#include <vector>
#include <string>
#include <map>
#include <fstream>
#include <iostream>
#include <windows.h>

static const int BUFSIZE = 256;

class ActiveProcInfoNode{
 public:
     ActiveProcInfoNode() : cnt(1) {};
     HWND hWnd;
     DWORD pid;
     std::string module;
     std::string title;
     inline void countup(){ cnt++; }
     inline int count(){ return cnt; }
 private:
     int cnt;
};

class ActiveProcInfo{
 public:
     ActiveProcInfo() : filename(""){
          if((hInstpsapi = LoadLibrary("psapi.dll")) == NULL){
               err=1; return;
          }
          if((fpGetModuleBaseName = (DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD))
              GetProcAddress(hInstpsapi, "GetModuleBaseNameA")) == NULL){
               err=2; return;
          }
     }
     ~ActiveProcInfo(){
          FreeLibrary(hInstpsapi);
          fileoutput();
     }
     std::map<std::string, ActiveProcInfoNode> nodes_title;
     std::map<DWORD, ActiveProcInfoNode> nodes_pid;
     std::map<std::string, ActiveProcInfoNode> nodes_proc;
     void update();
     void fileoutput();
     inline void setfilename(char *name){
          filename = name;
     }
     
 private:
     std::string filename;
     HINSTANCE hInstpsapi;
     DWORD (WINAPI *fpGetModuleBaseName)(HANDLE, HMODULE, LPTSTR, DWORD);
     int err;
};

ActiveProcInfo.cpp

#include "ActiveProcInfo.h"

void ActiveProcInfo::update()
{
     HWND hWnd;
     DWORD pid;
     HANDLE hProc;
     ActiveProcInfoNode p;
     char buf[BUFSIZE];
     
     hWnd = GetForegroundWindow();
     p.hWnd = hWnd;
     GetWindowText(hWnd, buf, BUFSIZE);
     p.title = buf;
     GetWindowThreadProcessId(hWnd, &pid);
     p.pid  = pid;
     if(!(hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid))){
          err=3; return;
     }
     fpGetModuleBaseName(hProc, NULL, buf, BUFSIZE);
     p.module = buf;
     CloseHandle(hProc);
     
     // std::cout << p.pid << "," << p.module << "," << p.title << std::endl;
 
     if(nodes_title.find(p.title) != nodes_title.end())
          nodes_title[p.title].countup();
     else 
          nodes_title[p.title]= p;
     if(nodes_pid.find(p.pid) != nodes_pid.end())
          nodes_pid[p.pid].countup();
     else 
          nodes_pid[p.pid] = p;
     if(nodes_proc.find(p.module) != nodes_proc.end())
          nodes_proc[p.module].countup();
     else
          nodes_proc[p.module] = p;
}

void ActiveProcInfo::fileoutput()
{
     if(filename == "") return;
     std::ofstream ofs(filename.c_str());

     ofs << "**merge by title:" << std::endl;
     ofs << "type\ttime\ttitle\tmodule" << std::endl;
     for(std::map<std::string, ActiveProcInfoNode>::iterator 
              p=nodes_title.begin(); p!=nodes_title.end(); p++){
       ofs << "t\t" << (p->second).count() << "\t" << (p->second).title 
           << "\t" << (p->second).module << std::endl;
     }
     ofs << std::endl;
     ofs << "**merge by pid:" << std::endl;
     ofs << "type\ttime\tpid\tmodule" << std::endl;
     for(std::map<DWORD, ActiveProcInfoNode>::iterator
              p=nodes_pid.begin(); p!=nodes_pid.end(); p++){
          ofs << "p\t" << (p->second).count() << "\t" 
              << (p->second).pid << "\t" << (p->second).module << std::endl;
     }
     ofs << std::endl;
     ofs << "**merge by module:" << std::endl;
     ofs << "type\ttime\tmodule" << std::endl;
     for(std::map<std::string, ActiveProcInfoNode>::iterator
              p=nodes_proc.begin(); p!=nodes_proc.end(); p++){
          ofs << "n\t" << (p->second).count() << "\t" << (p->second).module << std::endl;
     }
}

まあ、ふつーですね。