LoginSignup
1
4

More than 3 years have passed since last update.

プロセスを監視して、1秒ごとに、使用中のアプリと、操作中か否かのログを書き出す、ツール

Last updated at Posted at 2020-09-09

ディストピア感があるが、「プロセスを監視して、1秒ごとに、使用中のアプリと、操作中か否かのログを書き出す、ツール」を作った。

(毎日毎日、何をやったかを業務日報を記録する必要がある現場で、毎回手入力をするのがアホくさいので、「わかった。もう全部ログ差し出すから勝手に分析して」という気持ちで、ツール作った。)

ツール作ってみて、自身で計測してみたら、8時間ぐらいの労働時間中、PC操作(キーボードかマウス操作)しているのは、3-4割ぐらいだった。そんなもんかな、とは思った。

※c#のprocessクラスではなくwinapiを利用しているのは、c#の純正では、うまくプロセス名を拾えないケースがあったため

Process_Kanshi.cs
//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe Process_Kanshi.cs

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Text;

public class lCnt{
    public int cntWrk { get; set; }
    public int cntSm { get; set; }
    public string PNm { get; set; }
    public string MWT { get; set; }
    public override string ToString()
    {
         return cntWrk + "\t" + cntSm + "\t" + PNm + "\t" + MWT;
    }
    public void toWin(){
        this.cntWrk++;
        this.cntSm++;
    }
    public void toLose(){
        this.cntSm++;
    }
}

public class Process_Kanshi
{ ///*


[DllImport("user32.dll")]
public static extern int GetAsyncKeyState(long vKey);

[DllImport("USER32.dll", CallingConvention = CallingConvention.StdCall)]
static extern void SetCursorPos(int X, int Y);

[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);

[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr handle);

[DllImport("USER32.DLL")]
private static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

[DllImport("psapi.dll", CharSet = CharSet.Ansi)]
private static extern uint GetModuleBaseName(IntPtr hWnd, IntPtr hModule, [MarshalAs(UnmanagedType.LPStr), Out] StringBuilder lpBaseName, uint nSize);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetWindowTextLength(IntPtr hWnd);

  public static void Main(string[] args)
  { ///**

    //Process[] processList;

    DateTime dt = DateTime.Now;
    string dt_s = dt.ToString("yyyy_MM_dd");

    bool DtMsCr = false;
    bool DtKyBd = false;
    bool isWin = false;

    string s_mc = "";
    string lgT = "";
    string pT = "";

    string pnm0 = "";
    string mwt0 = "";

    Dictionary<string, lCnt> prcLog;// = new Dictionary<string, lCnt>();

    for(;;){ ///***

    prcLog = new Dictionary<string, lCnt>();

    for(int i = 0 ; i<60*5; i++){ //****

    //---------
    DtMsCr = false;
    DtKyBd = false;

    pnm0 = "";
    mwt0 = "";
    pT = "";
    isWin = false;
    //---------

    DateTime mdt1 = DateTime.Now;

    //processList = Process.GetProcesses();

    IntPtr hWnd = GetForegroundWindow();

    uint processId;
    GetWindowThreadProcessId(hWnd, out processId);

    if (hWnd != IntPtr.Zero)
    {
        var hnd = OpenProcess(0x0400 | 0x0010 , false, processId);

        var buffer = new StringBuilder(255);
        GetModuleBaseName(hnd, IntPtr.Zero, buffer, (uint)buffer.Capacity);

        int textLen = GetWindowTextLength(hWnd);

        StringBuilder tsb = new StringBuilder(textLen + 1);
        GetWindowText(hWnd, tsb, tsb.Capacity);

        var processName = buffer.ToString().ToLower();

        //-----
        isWin = true;
        string lmwt = tsb.ToString();
        lmwt = lmwt.Trim().Replace(" ","");
        lmwt = lmwt.Substring(0,Math.Min(30,lmwt.Length));
        pT = processName + "_" + lmwt;
        Console.WriteLine( pT );

        pnm0 = processName;
        mwt0 = lmwt;
        //-----

    }

    if(!isWin && (int)hWnd!=0){
        Console.WriteLine( "Unknown" + " _ " + hWnd);
        pT = "Unknown";
        pnm0 = "Unknown";
    }

    if((int)hWnd==0){
        Console.WriteLine( "LOG_OFF" + " _ " + hWnd);
        pT = "LOG_OFF";
        pnm0 = "LOG_OFF";
    }

    for(int ix = 32 ; ix <= 226; ix ++){
        if(GetAsyncKeyState(ix) != 0){
            DtKyBd = true;
        }
    }
    if(s_mc != Control.MousePosition.ToString()){
        DtMsCr = true;
    }


    //////////////##############
    if (!prcLog.ContainsKey(pT))
    {
        prcLog.Add(pT, new lCnt() { cntWrk=1, cntSm=1, PNm = pnm0, MWT = mwt0 });
    }else{
        if(DtKyBd || DtMsCr){
            prcLog[pT].toWin();
            //Console.WriteLine( "w");
        }else{
            prcLog[pT].toLose();
            //Console.WriteLine( "l");
        }
    }
    //////////////##############
    s_mc = Control.MousePosition.ToString();

            DateTime mdt2 = DateTime.Now;
            TimeSpan mms = mdt2-mdt1;
            int imms = (int)mms.TotalMilliseconds;
            //Console.WriteLine( "imms "+ imms);
            imms = 1000 - imms -10 ;
            if(imms>=1000 || imms < 0 ){imms=700;}
        System.Threading.Thread.Sleep(imms);

    } //****

    dt = DateTime.Now;
    string dt_sl = dt.ToString("yyyy_MM_dd_HHmmss");

    lgT = "";
    foreach (KeyValuePair<string, lCnt> kvp in prcLog)
    {
        lgT = lgT + dt_sl + "\t" + kvp.Key + "\t" +  kvp.Value + Environment.NewLine;
    }

    System.IO.File.AppendAllText(@".\" + dt_s + ".txt", lgT);
    lgT = "";
    pT = "";

    pnm0 = "";
    mwt0 = "";

    DtMsCr = false;
    DtKyBd = false;
    s_mc = Control.MousePosition.ToString();


    } ///***

  } ///**

} ///*
1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4