- Made cmt unicode compatible.

- Enabled time counting.
- Improved the waiting of key input events.

svn path=/trunk/; revision=11150
This commit is contained in:
Hartmut Birr 2004-10-02 10:26:48 +00:00
parent d2a8a1bc51
commit acb1dd91c6
2 changed files with 146 additions and 81 deletions

View file

@ -44,7 +44,7 @@
#include "ctm.h" #include "ctm.h"
#define MAX_PROC 17 #define MAX_PROC 17
//#define TIMES #define TIMES
HANDLE hStdin; HANDLE hStdin;
HANDLE hStdout; HANDLE hStdout;
@ -116,96 +116,143 @@ void RestoreConsole()
void DisplayScreen() void DisplayScreen()
{ {
COORD pos; COORD pos;
char lpStr[80]; TCHAR lpStr[80];
int idx; int posStr;
DWORD numChars; DWORD numChars;
int lines; int lines;
int idx;
static int first = 0;
// Header if (first == 0)
pos.X = 2; pos.Y = 2; {
strcpy(lpStr, "Console TaskManager v0.1 by Aleksey Bragin <aleksey@studiocerebral.com>"); // Header
WriteConsoleOutputCharacter(hStdout, lpStr, strlen(lpStr), pos, &numChars); pos.X = 2; pos.Y = 2;
_tcscpy(lpStr, _T("Console TaskManager v0.1 by Aleksey Bragin <aleksey@studiocerebral.com>"));
WriteConsoleOutputCharacter(hStdout, lpStr, _tcslen(lpStr), pos, &numChars);
pos.X = 2; pos.Y = 3; pos.X = 2; pos.Y = 3;
strcpy(lpStr, "+-------------------------------+-------+-----+-----------+-------------+"); _tcscpy(lpStr, _T("+-------------------------------+-------+-----+-----------+-------------+"));
WriteConsoleOutputCharacter(hStdout, lpStr, strlen(lpStr), pos, &numChars); WriteConsoleOutputCharacter(hStdout, lpStr, _tcslen(lpStr), pos, &numChars);
pos.X = 2; pos.Y = 4; pos.X = 2; pos.Y = 4;
strcpy(lpStr, "| Image name | PID | CPU | Mem Usage | Page Faults |"); _tcscpy(lpStr, _T("| Image name | PID | CPU | Mem Usage | Page Faults |"));
WriteConsoleOutputCharacter(hStdout, lpStr, strlen(lpStr), pos, &numChars); WriteConsoleOutputCharacter(hStdout, lpStr, _tcslen(lpStr), pos, &numChars);
pos.X = 2; pos.Y = 5; pos.X = 2; pos.Y = 5;
strcpy(lpStr, "+-------------------------------+-------+-----+-----------+-------------+"); _tcscpy(lpStr, _T("+-------------------------------+-------+-----+-----------+-------------+"));
WriteConsoleOutputCharacter(hStdout, lpStr, strlen(lpStr), pos, &numChars); WriteConsoleOutputCharacter(hStdout, lpStr, _tcslen(lpStr), pos, &numChars);
// Footer // Footer
pos.X = 2; pos.Y = 23; pos.X = 2; pos.Y = 23;
strcpy(lpStr, "+-------------------------------+-------+-----+-----------+-------------+"); _tcscpy(lpStr, _T("+-------------------------------+-------+-----+-----------+-------------+"));
WriteConsoleOutputCharacter(hStdout, lpStr, strlen(lpStr), pos, &numChars); WriteConsoleOutputCharacter(hStdout, lpStr, _tcslen(lpStr), pos, &numChars);
// Menu // Menu
pos.X = 2; pos.Y = 24; pos.X = 2; pos.Y = 24;
strcpy(lpStr, "Press: q - quit, k - kill process "); _tcscpy(lpStr, _T("Press: q - quit, k - kill process "));
WriteConsoleOutputCharacter(hStdout, lpStr, strlen(lpStr), pos, &numChars); WriteConsoleOutputCharacter(hStdout, lpStr, _tcslen(lpStr), pos, &numChars);
// Processess first = 1;
}
// Processess
lines = ProcessCount; lines = ProcessCount;
if (lines > MAX_PROC) if (lines > MAX_PROC)
lines = MAX_PROC; lines = MAX_PROC;
for (idx=0; idx<lines; idx++) for (idx=0; idx<MAX_PROC; idx++)
{ {
int len; int len, i;
char imgName[MAX_PATH]; TCHAR imgName[MAX_PATH];
char lpPid[8]; TCHAR lpPid[8];
char lpCpu[6]; TCHAR lpCpu[6];
char lpMemUsg[12]; TCHAR lpMemUsg[12];
char lpPageFaults[15]; TCHAR lpPageFaults[15];
WORD wColor; WORD wColor;
// data // data
// image name // image name
pos.X = 3; pos.Y = 6+idx; if (idx < lines && scrolled + idx < ProcessCount)
memset(imgName, 0, MAX_PATH); {
WideCharToMultiByte(CP_ACP, 0, pPerfData[scrolled+idx].ImageName, -1, #ifdef _UNICODE
imgName, MAX_PATH, NULL, NULL); len = wcslen(pPerfData[scrolled+idx].ImageName);
len = strlen(imgName); #else
WriteConsoleOutputCharacter(hStdout, " ", 30, pos, &numChars); WideCharToMultiByte(CP_ACP, 0, pPerfData[scrolled+idx].ImageName, -1,
WriteConsoleOutputCharacter(hStdout, imgName, (len > 30) ? 30 : len, pos, &numChars); imgName, MAX_PATH, NULL, NULL);
len = strlen(imgName);
#endif
if (len > 31)
{
len = 31;
}
#ifdef _UNICODE
wcsncpy(&lpStr[2], pPerfData[scrolled+idx].ImageName, len);
#else
strncpy(&lpStr[2], imgName, len);
#endif
}
else
{
len = 0;
}
if (len < 31)
{
_tcsncpy(&lpStr[2 + len], _T(" "), 31 - len);
}
// PID // PID
pos.X = 35; pos.Y = 6+idx; if (idx < lines && scrolled + idx < ProcessCount)
sprintf(lpPid, "%6ld", pPerfData[scrolled+idx].ProcessId); {
WriteConsoleOutputCharacter(hStdout, lpPid, strlen(lpPid), pos, &numChars); _stprintf(lpPid, _T("%6ld "), pPerfData[scrolled+idx].ProcessId);
_tcsncpy(&lpStr[34], lpPid, 7);
}
else
{
_tcsncpy(&lpStr[34], _T(" "), 7);
}
// CPU // CPU
pos.X = 43; pos.Y = 6+idx; if (idx < lines && scrolled + idx < ProcessCount)
sprintf(lpCpu, "%3d%%", pPerfData[scrolled+idx].CPUUsage); {
WriteConsoleOutputCharacter(hStdout, lpCpu, strlen(lpCpu), pos, &numChars); _stprintf(lpCpu, _T("%3d%% "), pPerfData[scrolled+idx].CPUUsage);
_tcsncpy(&lpStr[42], lpCpu, 5);
}
else
{
_tcsncpy(&lpStr[42], _T(" "), 5);
}
// Mem usage // Mem usage
pos.X = 49; pos.Y = 6+idx; if (idx < lines && scrolled + idx < ProcessCount)
sprintf(lpMemUsg, "%6ld", pPerfData[scrolled+idx].WorkingSetSizeBytes / 1024); {
WriteConsoleOutputCharacter(hStdout, lpMemUsg, strlen(lpMemUsg), pos, &numChars); _stprintf(lpMemUsg, _T("%6ld "), pPerfData[scrolled+idx].WorkingSetSizeBytes / 1024);
_tcsncpy(&lpStr[48], lpMemUsg, 11);
}
else
{
_tcsncpy(&lpStr[48], _T(" "), 11);
}
// Page Fault // Page Fault
pos.X = 61; pos.Y = 6+idx; if (idx < lines && scrolled + idx < ProcessCount)
sprintf(lpPageFaults, "%12ld", pPerfData[scrolled+idx].PageFaultCount); {
WriteConsoleOutputCharacter(hStdout, lpPageFaults, strlen(lpPageFaults), pos, &numChars); _stprintf(lpPageFaults, _T("%12ld "), pPerfData[scrolled+idx].PageFaultCount);
_tcsncpy(&lpStr[60], lpPageFaults, 13);
}
else
{
_tcsncpy(&lpStr[60], _T(" "), 13);
}
// columns // columns
pos.X = 2; pos.Y = 6+idx; lpStr[0] = _T(' ');
WriteConsoleOutputCharacter(hStdout, "|", 1, pos, &numChars); lpStr[1] = _T('|');
pos.X = 34; pos.Y = 6+idx; lpStr[33] = _T('|');
WriteConsoleOutputCharacter(hStdout, "|", 1, pos, &numChars); lpStr[41] = _T('|');
pos.X = 42; pos.Y = 6+idx; lpStr[47] = _T('|');
WriteConsoleOutputCharacter(hStdout, "|", 1, pos, &numChars); lpStr[59] = _T('|');
pos.X = 48; pos.Y = 6+idx; lpStr[73] = _T('|');
WriteConsoleOutputCharacter(hStdout, "|", 1, pos, &numChars); pos.X = 1; pos.Y = 6+idx;
pos.X = 60; pos.Y = 6+idx; WriteConsoleOutputCharacter(hStdout, lpStr, 74, pos, &numChars);
WriteConsoleOutputCharacter(hStdout, "|", 1, pos, &numChars);
pos.X = 74; pos.Y = 6+idx;
WriteConsoleOutputCharacter(hStdout, "|", 1, pos, &numChars);
// Attributes now... // Attributes now...
pos.X = 3; pos.Y = 6+idx; pos.X = 3; pos.Y = 6+idx;
@ -241,7 +288,7 @@ int ProcessKeys(int numEvents)
if ((ProcessCount-scrolled < 17) && (ProcessCount > 17)) if ((ProcessCount-scrolled < 17) && (ProcessCount > 17))
scrolled = ProcessCount-17; scrolled = ProcessCount-17;
unsigned char key = GetKeyPressed(numEvents); TCHAR key = GetKeyPressed(numEvents);
if (key == VK_Q) if (key == VK_Q)
return TRUE; return TRUE;
else if (key == VK_K) else if (key == VK_K)
@ -249,11 +296,11 @@ int ProcessKeys(int numEvents)
// user wants to kill some process, get his acknowledgement // user wants to kill some process, get his acknowledgement
DWORD pId; DWORD pId;
COORD pos; COORD pos;
char lpStr[100]; TCHAR lpStr[100];
pos.X = 2; pos.Y = 24; pos.X = 2; pos.Y = 24;
strcpy(lpStr, "Are you sure you want to kill this process? (y/n)"); _tcscpy(lpStr, _T("Are you sure you want to kill this process? (y/n)"));
WriteConsoleOutputCharacter(hStdout, lpStr, strlen(lpStr), pos, &pId); WriteConsoleOutputCharacter(hStdout, lpStr, _tcslen(lpStr), pos, &pId);
do { do {
GetNumberOfConsoleInputEvents(hStdin, &pId); GetNumberOfConsoleInputEvents(hStdin, &pId);
@ -270,8 +317,8 @@ int ProcessKeys(int numEvents)
{ {
if (!TerminateProcess(hProcess, 0)) if (!TerminateProcess(hProcess, 0))
{ {
strcpy(lpStr, "Unable to terminate this process... "); _tcscpy(lpStr, _T("Unable to terminate this process... "));
WriteConsoleOutputCharacter(hStdout, lpStr, strlen(lpStr), pos, &pId); WriteConsoleOutputCharacter(hStdout, lpStr, _tcslen(lpStr), pos, &pId);
Sleep(1000); Sleep(1000);
} }
@ -279,8 +326,8 @@ int ProcessKeys(int numEvents)
} }
else else
{ {
sprintf(lpStr, "Unable to terminate process %3d (unable to OpenProcess) ", pId); _stprintf(lpStr, _T("Unable to terminate process %3d (unable to OpenProcess) "), pId);
WriteConsoleOutputCharacter(hStdout, lpStr, strlen(lpStr), pos, &pId); WriteConsoleOutputCharacter(hStdout, lpStr, _tcslen(lpStr), pos, &pId);
Sleep(1000); Sleep(1000);
} }
} }
@ -347,15 +394,15 @@ void PerfDataRefresh()
#ifdef TIMES #ifdef TIMES
for (CurrentKernelTime=0, Idx=0; Idx<1/*SystemBasicInfo.bKeNumberProcessors*/; Idx++) { for (CurrentKernelTime=0, Idx=0; Idx<1/*SystemBasicInfo.bKeNumberProcessors*/; Idx++) {
CurrentKernelTime += Li2Double(SysProcessorTimeInfo[Idx].KernelTime); CurrentKernelTime += Li2Double(SysProcessorTimeInfo[Idx].TotalProcessorTime);
CurrentKernelTime += Li2Double(SysProcessorTimeInfo[Idx].DpcTime); CurrentKernelTime += Li2Double(SysProcessorTimeInfo[Idx].TotalDPCTime);
CurrentKernelTime += Li2Double(SysProcessorTimeInfo[Idx].InterruptTime); CurrentKernelTime += Li2Double(SysProcessorTimeInfo[Idx].TotalInterruptTime);
} }
// If it's a first call - skip idle time calcs // If it's a first call - skip idle time calcs
if (liOldIdleTime.QuadPart != 0) { if (liOldIdleTime.QuadPart != 0) {
// CurrentValue = NewValue - OldValue // CurrentValue = NewValue - OldValue
dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime); dbIdleTime = Li2Double(SysPerfInfo.IdleTime) - Li2Double(liOldIdleTime);
dbKernelTime = CurrentKernelTime - OldKernelTime; dbKernelTime = CurrentKernelTime - OldKernelTime;
dbSystemTime = Li2Double(SysTimeInfo.CurrentTime) - Li2Double(liOldSystemTime); dbSystemTime = Li2Double(SysTimeInfo.CurrentTime) - Li2Double(liOldSystemTime);
@ -369,7 +416,7 @@ void PerfDataRefresh()
} }
// Store new CPU's idle and system time // Store new CPU's idle and system time
liOldIdleTime = SysPerfInfo.liIdleTime; liOldIdleTime = SysPerfInfo.IdleTime;
liOldSystemTime = SysTimeInfo.CurrentTime; liOldSystemTime = SysTimeInfo.CurrentTime;
OldKernelTime = CurrentKernelTime; OldKernelTime = CurrentKernelTime;
#endif #endif
@ -409,8 +456,10 @@ void PerfDataRefresh()
// Clear out process perf data structure // Clear out process perf data structure
memset(&pPerfData[Idx], 0, sizeof(PERFDATA)); memset(&pPerfData[Idx], 0, sizeof(PERFDATA));
if (pSPI->ProcessName.Buffer) if (pSPI->ProcessName.Buffer) {
wcsncpy(pPerfData[Idx].ImageName, pSPI->ProcessName.Buffer, pSPI->ProcessName.MaximumLength); wcsncpy(pPerfData[Idx].ImageName, pSPI->ProcessName.Buffer, pSPI->ProcessName.Length / sizeof(WCHAR));
pPerfData[Idx].ImageName[pSPI->ProcessName.Length / sizeof(WCHAR)] = 0;
}
else else
wcscpy(pPerfData[Idx].ImageName, L"System Idle Process"); wcscpy(pPerfData[Idx].ImageName, L"System Idle Process");
@ -499,6 +548,9 @@ unsigned int GetKeyPressed(int events)
for (i=0; i<events; i++) for (i=0; i<events; i++)
{ {
if (!ReadConsoleInput(hStdin, &record, 0, &bytesRead)) {
return 0;
}
if (!ReadConsoleInput(hStdin, &record, 1, &bytesRead)) { if (!ReadConsoleInput(hStdin, &record, 1, &bytesRead)) {
return 0; return 0;
} }
@ -546,6 +598,11 @@ int main(int *argc, char **argv)
DisplayScreen(); DisplayScreen();
//WriteConsole(hStdin, " ", 1, &numEvents, NULL); // TODO: Make another way (this is ugly, I know) //WriteConsole(hStdin, " ", 1, &numEvents, NULL); // TODO: Make another way (this is ugly, I know)
#if 1
/* WaitForSingleObject for console handles is not implemented in ROS */
WaitForSingleObject(hStdin, 1000);
#endif
GetNumberOfConsoleInputEvents(hStdin, &numEvents); GetNumberOfConsoleInputEvents(hStdin, &numEvents);
if (numEvents > 0) if (numEvents > 0)
@ -553,8 +610,13 @@ int main(int *argc, char **argv)
if (ProcessKeys(numEvents) == TRUE) if (ProcessKeys(numEvents) == TRUE)
break; break;
} }
#if 0
else else
Sleep(40); // TODO: Should be done more efficient (might be another thread handling input/etc)*/ {
/* Should be removed, if WaitForSingleObject is implemented for console handles */
Sleep(40); // TODO: Should be done more efficient (might be another thread handling input/etc)*/
}
#endif
} }
RestoreConsole(); RestoreConsole();

View file

@ -24,7 +24,7 @@
#ifndef TMTM_H #ifndef TMTM_H
#define TMTM_H #define TMTM_H
#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart)) #define Li2Double(x) ((double)((x).u.HighPart) * 4.294967296E9 + (double)((x).u.LowPart))
typedef struct _PERFDATA typedef struct _PERFDATA
{ {
@ -53,4 +53,7 @@ typedef struct _PERFDATA
TIME KernelTime; TIME KernelTime;
} PERFDATA, *PPERFDATA; } PERFDATA, *PPERFDATA;
#define SystemTimeInformation 3
#endif #endif