Code::Blocks ConsoleRunner改进版

Code::Blocks是开源的,好处就在于可以随意的修改它,然后自己编译。Code::Blocks默认提供了一个 ConsoleRunner程序,在Windows平台下它可以提供程序的返回码与程序启动到运行结束的时间,很实用。貌似,仅仅是返回码和时间是不够的,偶给它来了个小小的修改,添加了几个小功能:

* 显示程序运行内存使用峰值
* 显示程序运行用户时间
* 显示程序运行内核时间
* 显示程序运行时间(用户时间与内核时间和)

这样改进后更方便更实用了,喜欢自己动手的童鞋可以继续修改添加自己喜欢的功能。
使用方法很简单,下载后直接替换Code::Blocks安装目录下的cb_console_runner.exe文件即可。

以下是源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
* This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
* http://www.gnu.org/licenses/gpl-3.0.html
*
* $Revision: 4909 $
* $Id: main.cpp 4909 2008-02-27 13:15:26Z mortenmacfly $
* $HeadURL: svn://svn.berlios.de/codeblocks/tags/8.02/src/tools/ConsoleRunner/main.cpp $
*Modify by COCO<4341322@gmail.com>
*/
 
#include <stdio.h>
#include <stdlib.h>
#ifndef __WXMSW__
#define __WXMSW__ 1
#endif
#ifdef __WXMSW__
#include <windows.h>
#include <psapi.h>
#include <time.h>
#include <conio.h>
#define wait_key getch
#else
#define wait_key getchar
#endif
#include <string.h>
 
#ifdef __MINGW32__
int _CRT_glob = 0;
#endif
 
bool hasSpaces(const char* str)
{
char last = 0;
while (str && *str)
{
if ((*str == ' ' || *str == '\t') && last != '\\')
return true;
last = *str++;
}
return false;
}
 
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("Usage: cb_console_runner <filename> <args ...>\n");
return 1;
}
 
// count size of arguments
int fullsize = 0;
for (int i = 1; i < argc; ++i)
{
fullsize += strlen(argv[i]);
}
// add some slack for spaces between args plus quotes around executable
fullsize += argc + 32;
 
char* cmdline = new char[fullsize];
memset(cmdline, 0, fullsize);
 
// 1st arg (executable) enclosed in quotes to support filenames with spaces
bool sp = hasSpaces(argv[1]);
if (sp)
strcat(cmdline, "\"");
strcat(cmdline, argv[1]);
if (sp)
strcat(cmdline, "\"");
strcat(cmdline, " ");
 
for (i = 2; i < argc; ++i)
{
sp = hasSpaces(argv[i]);
if (sp)
strcat(cmdline, "\"");
strcat(cmdline, argv[i]);
if (sp)
strcat(cmdline, "\"");
strcat(cmdline, " ");
}
 
//printf("Would run '%s'\n", cmdline);
#ifdef __WXMSW__
//Windows's system() seems to not be able to handle parentheses in
//the path, so we have to launch the program a different way.
 
SetConsoleTitle(cmdline);
 
STARTUPINFO si;
PROCESS_INFORMATION pi;
 
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
 
// Start the child process.
clock_t cl = clock();
CreateProcess( NULL, TEXT(cmdline), NULL, NULL, FALSE, 0,
NULL, NULL, &si, &pi );
 
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
 
PROCESS_MEMORY_COUNTERS memInfo;
GetProcessMemoryInfo(pi.hProcess,&memInfo,sizeof(memInfo));
FILETIME ftCreate, ftExit, ftKernel, ftUser;
GetProcessTimes(pi.hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser);
LONGLONG tUser64 = *(LONGLONG*) &ftUser;
LONGLONG tKernel64 = *(LONGLONG*) &ftKernel;
DWORD tUser, tKernel;
tUser = (DWORD)(tUser64 / 10000);
tKernel = (DWORD)(tKernel64 / 10000);
 
cl = clock() - cl;
cl *= 1000;
cl /= CLOCKS_PER_SEC;
 
// Get the return value of the child process
DWORD ret;
GetExitCodeProcess( pi.hProcess, &ret );
 
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
 
printf("\nProcess returned %ld (0x%lX)   execution time : %0.3f s", ret, ret, ((float)cl)/1000);
printf("\nPeakWorkingSetSize : %d K ~ %d Mb",memInfo.PeakWorkingSetSize/1024,memInfo.PeakWorkingSetSize/1024/1024);
printf("\nUser Time:%d ms ~ %0.3f S Kernel Time:%d ms ~ %0.3f S\nTotal Time:%d ms ~ %0.3f S",tUser,tUser/1000.0,tKernel,tKernel/1000.0,tUser+tKernel,(tUser+tKernel)/1000.0);
printf("\nPress any key to continue.\n");
#else
int ret = system(cmdline);
printf("\nPress ENTER to continue.\n");
#endif
 
wait_key();
 
delete[] cmdline;
return ret;
}

-EOF-