From: Zhiyi Zhang zzhang@codeweavers.com
--- programs/tasklist/tasklist.c | 85 ++++++++++++++++++++++++++---- programs/tasklist/tasklist.h | 9 ++++ programs/tasklist/tasklist.rc | 1 + programs/tasklist/tests/tasklist.c | 43 +++++++++++++++ 4 files changed, 128 insertions(+), 10 deletions(-)
diff --git a/programs/tasklist/tasklist.c b/programs/tasklist/tasklist.c index d845cfea8e7..ce2028726c9 100644 --- a/programs/tasklist/tasklist.c +++ b/programs/tasklist/tasklist.c @@ -72,6 +72,14 @@ static int tasklist_message(int msg) return tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer); }
+static int tasklist_error(int msg) +{ + WCHAR msg_buffer[MAXSTRING]; + + LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer, ARRAY_SIZE(msg_buffer)); + return tasklist_printfW(GetStdHandle(STD_ERROR_HANDLE), msg_buffer); +} + static DWORD *enumerate_processes(DWORD *list_count) { DWORD *pid_list, *realloc_list, alloc_bytes, needed_bytes; @@ -141,7 +149,8 @@ static NUMBERFMTW *tasklist_get_memory_format(void) return &format; }
-static void tasklist_get_header(struct tasklist_process_info *header) +static void tasklist_get_header(const struct tasklist_options *options, + struct tasklist_process_info *header) { HMODULE module;
@@ -151,6 +160,14 @@ static void tasklist_get_header(struct tasklist_process_info *header) LoadStringW(module, STRING_SESSION_NAME, header->session_name, ARRAY_SIZE(header->session_name)); LoadStringW(module, STRING_SESSION_NUMBER, header->session_number, ARRAY_SIZE(header->session_number)); LoadStringW(module, STRING_MEM_USAGE, header->memory_usage, ARRAY_SIZE(header->memory_usage)); + if (options->format == LIST) + { + wcscat(header->image_name, L":"); + wcscat(header->pid, L":"); + wcscat(header->session_name, L":"); + wcscat(header->session_number, L":"); + wcscat(header->memory_usage, L":"); + } }
static BOOL tasklist_get_process_info(DWORD pid, struct tasklist_process_info *info) @@ -215,15 +232,20 @@ static void tasklist_print(const struct tasklist_options *options) struct tasklist_process_info header, info; DWORD *pid_list, list_count, i;
- tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), L"\r\n"); + if (options->format == TABLE) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), L"\r\n");
+ tasklist_get_header(options, &header); if (!options->no_header) { - tasklist_get_header(&header); - tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), - L"%-25.25s %8.8s %-16.16s %11.11s %12.12s\r\n" - L"========================= ======== ================ =========== ============\r\n", - header.image_name, header.pid, header.session_name, header.session_number, header.memory_usage); + if (options->format == TABLE) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L"%-25.25s %8.8s %-16.16s %11.11s %12.12s\r\n" + L"========================= ======== ================ =========== ============\r\n", + header.image_name, header.pid, header.session_name, header.session_number, header.memory_usage); + else if (options->format == CSV) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), L""%s","%s","%s","%s","%s"\r\n", + header.image_name, header.pid, header.session_name, header.session_number, header.memory_usage); }
pid_list = enumerate_processes(&list_count); @@ -232,9 +254,27 @@ static void tasklist_print(const struct tasklist_options *options) if (!tasklist_get_process_info(pid_list[i], &info)) continue;
- tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), - L"%-25.25s %8.8s %-16.16s %11.11s %12s\r\n", - info.image_name, info.pid, info.session_name, info.session_number, info.memory_usage); + if (options->format == TABLE) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L"%-25.25s %8.8s %-16.16s %11.11s %12s\r\n", + info.image_name, info.pid, info.session_name, info.session_number, info.memory_usage); + else if (options->format == CSV) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L""%s","%s","%s","%s","%s"\r\n", + info.image_name, info.pid, info.session_name, info.session_number, info.memory_usage); + else if (options->format == LIST) + tasklist_printfW(GetStdHandle(STD_OUTPUT_HANDLE), + L"\r\n" + L"%-13.13s %s\r\n" + L"%-13.13s %s\r\n" + L"%-13.13s %s\r\n" + L"%-13.13s %s\r\n" + L"%-13.13s %s\r\n", + header.image_name, info.image_name, + header.pid, info.pid, + header.session_name, info.session_name, + header.session_number, info.session_number, + header.memory_usage, info.memory_usage); } free(pid_list); } @@ -259,6 +299,31 @@ int __cdecl wmain(int argc, WCHAR *argv[]) { options.no_header = TRUE; } + else if (!wcsicmp(argv[i], L"/fo")) + { + if (i + 1 >= argc) + { + tasklist_error(STRING_INVALID_SYNTAX); + return 1; + } + else if (!wcsicmp(argv[i + 1], L"TABLE")) + { + options.format = TABLE; + } + else if (!wcsicmp(argv[i + 1], L"CSV")) + { + options.format = CSV; + } + else if (!wcsicmp(argv[i + 1], L"LIST")) + { + options.format = LIST; + } + else + { + tasklist_error(STRING_INVALID_SYNTAX); + return 1; + } + } else { WINE_WARN("Ignoring option %s\n", wine_dbgstr_w(argv[i])); diff --git a/programs/tasklist/tasklist.h b/programs/tasklist/tasklist.h index 6add1f30277..5e4e90960ea 100644 --- a/programs/tasklist/tasklist.h +++ b/programs/tasklist/tasklist.h @@ -27,6 +27,14 @@ #define STRING_SESSION_NUMBER 105 #define STRING_MEM_USAGE 106 #define STRING_K 107 +#define STRING_INVALID_SYNTAX 108 + +enum tasklist_format +{ + TABLE = 0, + CSV = 1, + LIST = 2, +};
struct tasklist_process_info { @@ -40,4 +48,5 @@ struct tasklist_process_info struct tasklist_options { BOOL no_header; + enum tasklist_format format; }; diff --git a/programs/tasklist/tasklist.rc b/programs/tasklist/tasklist.rc index d0776f1f6d9..10bb965318c 100644 --- a/programs/tasklist/tasklist.rc +++ b/programs/tasklist/tasklist.rc @@ -32,6 +32,7 @@ STRINGTABLE STRING_SESSION_NUMBER, "Session#" STRING_MEM_USAGE, "Mem Usage" STRING_K, "K" + STRING_INVALID_SYNTAX, "ERROR: Invalid syntax\r\n" }
#define WINE_FILEDESCRIPTION_STR "Wine tasklist" diff --git a/programs/tasklist/tests/tasklist.c b/programs/tasklist/tests/tasklist.c index 2c4d77855b0..011bfdeb382 100644 --- a/programs/tasklist/tests/tasklist.c +++ b/programs/tasklist/tests/tasklist.c @@ -122,6 +122,48 @@ static void test_no_header(void) ok(!pos, "Got header.\n"); }
+static void test_format(void) +{ + char *pos; + + /* /fo */ + run_tasklist("/fo", 1); + ok(stdout_size == 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size > 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + + /* /fo invalid */ + run_tasklist("/fo invalid", 1); + ok(stdout_size == 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size > 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + + /* /fo TABLE */ + run_tasklist("/fo TABLE", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "\r\n" + "Image Name PID Session Name Session# Mem Usage\r\n" + "========================= ======== ================ =========== ============\r\n"); + ok(pos == stdout_buffer, "Got the wrong first line.\n"); + pos = strstr(stdout_buffer, "tasklist.exe"); + ok(!!pos, "Failed to list tasklist.exe.\n"); + + /* /fo CSV */ + run_tasklist("/fo CSV", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, ""Image Name","PID","Session Name","Session#","Mem Usage""); + ok(pos == stdout_buffer, "Got the wrong first line.\n"); + pos = strstr(stdout_buffer, ""tasklist.exe","); + ok(!!pos, "Failed to list tasklist.exe.\n"); + + /* /fo LIST */ + run_tasklist("/fo LIST", 0); + ok(stdout_size > 0, "Unexpected stdout buffer size %ld.\n", stdout_size); + ok(stderr_size == 0, "Unexpected stderr buffer size %ld.\n", stderr_size); + pos = strstr(stdout_buffer, "Image Name: tasklist.exe"); + ok(!!pos, "Failed to list tasklist.exe.\n"); +} + START_TEST(tasklist) { if (PRIMARYLANGID(GetUserDefaultUILanguage()) != LANG_ENGLISH) @@ -132,4 +174,5 @@ START_TEST(tasklist)
test_basic(); test_no_header(); + test_format(); }