PCでの活動記録をスクリーンキャプチャで残す
これは以前書いた記事 http://d.hatena.ne.jp/itouhiro/20101216 の改訂版です。改善した点:
- BATファイルを実行する代わりに、「タスクスケジューラ」を使うようにした。
- その結果、タスクバーやAlt+Tabに「コマンドプロンプト」が居座らなくなる。
パソコンで作業してると、いつのまにかネットを見ていて時間をつぶしていたりする。で、あとから何してたんだっけ? 思い出せないぞ‥‥ということがある。
よくあるね。
そこで、一定時間、私の場合は5分ごとにスクリーンキャプチャを撮影することにした。それを後で見れば何をしていたか思い出せる。
思い出してどうするの?
毎日どう時間を使っていたか、記録しているんだ。表計算ソフト使って記録に残している。あとで眺めると日記にもなる。
ふーん。
で、その「5分ごとにスクリーンキャプチャに残す方法」を説明する。
できれば軽くてメモリ食わないほうがいいし、Alt+TABキーで作業ウィンドウを選ぶときにでてきてほしくない。
動作環境
OS: Windows 7 / XP
ソフトウェア: MiniCap 1.21.01
スクリーンキャプチャするソフト
MiniCap を使う。このソフトは以下の利点がある。
記録画像をもっと大きくできない?
設定は変更できるよ。あとで説明する。
http://www.donationcoder.com/Software/Mouser/MiniCap/
で、 MiniCapSetup.exe をダウンロードする。
ファイル名の拡張子を7zに変えて、たとえば MiniCapSetup.exe.7z にして解凍する。
今回は C:\home\bin\MiniCap に MiniCap.exeほかのファイルを配置する。
一定時間ごとに起動するには‥‥
Windows標準装備の「タスクスケジューラー」を使用する。
この設定によって、
- 一度設定すると、Windows再起動後も自動的に実行される。
- つまり、普段はまったく意識しなくても自動的に記録し続けてくれる。
- 停止・再開も簡単。
登録方法は http://www.atmarkit.co.jp/fwin2k/win2ktips/1332reptsk/reptsk.html に書いてある。
すこし詳しく説明すると、
具体的には……
- [コントロールパネル-タスク-追加](WindowsXP) [コントロールパネル-管理ツール-タスクスケジューラ-追加](Windows7) でC:\home\bin\MiniCap\MiniCap.exe 指定する。
- [スケジュールtab-詳細設定]で「繰り返し実行」をチェック。[間隔5分、継続時間24時間] にする。これで5分毎にスクリーンキャプチャを撮影できる。
- [タスクtab - ログオン時のみ実行]をチェック。
- [タスクtab - 実行するファイル名]を C:\home\MiniCap\MiniCap.exe -customdate "$Y-$m-$d $H.$M" -save "r:\cap\$customdate$.jpg" -capturedesktop -exit -resizexp 50 -resizeyp 50 -compress 3 にする(WinXP)。Win7の場合はMiniCap.exeの次からは「引数の追加」に指定する。
停止したいときは、タスクスケジューラの [実行する](WinXP)、 [有効](Win7) チェックボックスを外せばいい。
ここではRドライブのcapフォルダに保存しているぞ。 -save "r:\cap\$customdate$.jpg"
という箇所でそれを指定している。
Rドライブがあって、R:\capフォルダが存在しないときは、capフォルダは自動的に作成される。
しかしRドライブがないときはMiniCapのダイアログ(ウインドウ)がでてくる。どこに保存するか聞かれる。キャンセルすればよい。
Windows 7 の設定詳細
Windows7のコントロールパネルはどこに何があるかよくわからない‥‥。[小さいアイコン]にすればなんとかわかるぞ。[管理ツール→タスクスケジューラ]を選ぶ。
[基本タスクの作成]をクリックしてMiniCapという名前(別の名前でもいい)で登録する。最初の登録画面では1日1回実行までしか指定できないので、1日1回実行とする。
登録したMiniCapタスクを選択して [プロパティ] をクリック。[間隔5分、継続時間24時間] にする(画面では継続時間 無制限となっているがこれでもよい)。これで5分毎にスクリーンキャプチャを撮影できる。
Windows XP の設定詳細
記録画像の大きさとかを設定変更する方法は?
-resizexp 50 -resizeyp 50 というのが、縦横ともに 50% に縮小します、という設定なんだ。
書き換えて、 -resizexp 100 -resizeyp 100 とすれば縮小しないで実サイズで保存するし、数字を 25 にすれば、縦横4分の1で保存する。
JPGの圧縮率は -compress 10 なら最もキレイだけどファイル容量が大きい、 -compress 1 なら最も見た目はよくないけどファイルサイズが小さい。
JPGじゃなくてPNG保存するなら -save "...jpg" の jpg を png に変更する。
ほかにも細かな設定は http://www.donationcoder.com/Software/Mouser/MiniCap/ に書いてあるよ。
RAMドライブを使う
上の手順で動作はするのだが、私はさらに変更したい。というのも、このスクリーンキャプチャした画像はプライバシーばればれなので、他人に見られないようにしたい。その方法は2つある。
- 暗号化フォルダに保存。
暗号化フォルダに保存は、TrueCrypt等使えば可能だが、やめておく。キャプチャ画像はそんな大きなファイルサイズでもないし(1時間で360KBくらい)、保存しておいて20年後に眺めるとかもできる。しかし個人的には記録したあとは忘れたいし、消してしまう。 - RAMドライブに保存。
今回はRAMドライブを使う。RAMドライブに保存して、RAMドライブのファイルはPCの電源OFFで消える設定にしておけば、キャプチャ画像は、PCの電源OFFやOS再起動で自動的に削除されるし、HDDの削除ファイル復元でも復活しない(HDDに保存してないから)ので安全だ。
どちらにしても問題がある。暗号化ドライブやRAMドライブは、OS起動直後はマウントされてしなくて存在しない。RAMドライブ作成ソフトにRamPhantomを使ってるんだけど、OS起動後ログインして、デスクトップが表示されて、その40秒後くらいにやっとRドライブがマウントされて使用可能になる。
その40秒のあいだにMiniCapが動作すると、まだRドライブがないから保存先フォルダが作れないので、MiniCapは「フォルダがありませんよ」ダイアログを出してくる。キャンセルボタンを押せばいいんだけど、個人的にはそんなことしたくない。できるだけ裏方でいてほしいので。
そこで、もし保存先フォルダが存在せず、フォルダ作成もできない(Rドライブが存在しない)場合はMiniCapを起動しない、そんなソフトを作成した。
すごく簡単な C言語 + Win32API のプログラムだけど。Rドライブが存在するか確認(confirm)して、あれば実行(execute)するので confexec.exe というファイル名。GitHubに置いてみたいんだけどGitHubの使い方が不明だ‥‥。
追記: https://github.com/itouhiro/confexec でexeを取得できます。
設定方法
さきほどのタスクスケジューラの実行ファイル(と引数)を変える。
C:\home\bin\MiniCap\confexec.exe -w 61 -d "r:\cap" "MiniCap.exe -customdate \"$Y-$m-$d $H.$M\" -save \"r:\cap\$customdate$.jpg\" -capturedesktop -exit -resizexp 50 -resizeyp 50 -compress 3"
作業フォルダは以下になっているはずだが、なっていなければ、以下を指定する。
C:\home\bin\MiniCap
confexecのソース
コンパイラは gnupack-devel http://sourceforge.jp/projects/gnupack/ を使った。devel版には Mingw32のgccが入っているので、Cygwinに依存しないWindowsプログラムを生成できる。
コンパイラオプションに -mwindows を指定すれば、コマンドラインアプリでもDOS窓(コマンドプロンプト)出さずに済む。しかし外部exeファイルを実行するためsystem()関数使うとDOS窓が出てきた。system()の代わりにexternalProcess関数使えばDOS窓出さずにすんだ。余談だが、externalProcess関数の説明が2003年はmsdnにあった(digioTxtという当時作ったプログラムのソースに書いてあった)のだが、今見ると当時のURLでもGoogle検索でも見つからない。Win32APIは使われなくなってきたのか‥‥
て君も64bitOS使ってコンパイルしたじゃない? Win32APIって32bit向けAPIでしょ。今だとdotNET Framework使うのがラクなのかなあ
confexec.c
// -*- coding:utf-8 -*- // Time-stamp: <2012-01-16 12:31 JST> // confirm existance of the directory and execute // this program will do // - Wait seconds 指定秒のウェイト(-w 60) // - Check existance of the directory ドライブ、フォルダの存在確認(-d "r:\cap") // - execute 指定コマンド実行("C:\bin\foo.exe -a 1 -f \"r:\cap\aa.jpg\"") // how to compile (with gnupack-devel 7.02): // gcc -O2 -mwindows -o confexec.exe confexec.c ; strip confexec.exe // func prototype // static int externalProcess(char *app, char *param, int wait); //#include <stdio.h> // printf() #include <stdlib.h> // exit(), system() #include <string.h> // memset(), strncpy() #include "getopt.h" //getopt() #include <Windows.h> // Sleep() #include <dirent.h> // opendir() #include <sys/stat.h> // mkdir() enum {WAIT, NOWAIT}; int main(int argc, char **argv){ // variables for getopt // int opt; extern char *optarg; extern int optind, opterr; // variables // int wait_sec = 0; char dirname[256]; memset(dirname, 0x00, 256); // command line option // while((opt = getopt(argc, argv, "w:d:")) != -1){ switch(opt){ case 'w': //printf("wait = %d\n", atoi(optarg)); wait_sec = atoi(optarg); break; case 'd': //printf("dir = %s\n", optarg); strncpy(dirname, optarg, 255); break; default: break; } } argc -= optind; argv += optind; // confirm existance of argv[0] // if(argc < 1) exit(EXIT_FAILURE); //printf("error arg (%d) = %s\n", argc, argv[0]); exit(-1); // wait // //printf("wait=%d dir=%s)\n", wait_sec, dirname); Sleep(wait_sec * 1000); // confirm existance of a directory // if (*dirname != '\0'){ DIR *dr; dr = opendir(dirname); if(dr == NULL){ if(mkdir(dirname)) exit(EXIT_FAILURE); } // printf("%s is not found\n", dirname); } // execute // externalProcess(NULL, argv[0], NOWAIT); //system(argv[0]); // <- CommandPrompt(MS-DOS prompt) appeared exit(EXIT_SUCCESS); } static int externalProcess(char *app, char *param, int wait){ STARTUPINFO stinfo; PROCESS_INFORMATION psinfo; ZeroMemory( &stinfo, sizeof(stinfo) ); stinfo.cb = sizeof(stinfo); ZeroMemory( &psinfo, sizeof(psinfo) ); CreateProcess(app, param, NULL, NULL, FALSE, 0, NULL, NULL, &stinfo, &psinfo); // Wait until child process exits. if(wait == WAIT) WaitForSingleObject( psinfo.hProcess, INFINITE ); // Close process and thread handles. CloseHandle( psinfo.hProcess ); CloseHandle( psinfo.hThread ); return 0; }
プログラミング .NET Framework 第3版 (マイクロソフト公式解説書)
- 作者: JeffreyRichter
- 出版社/メーカー: 日経BP社
- 発売日: 2011-02-03
- メディア: 大型本