https://git.reactos.org/?p=reactos.git;a=commitdiff;h=633ece90258d09106ff5d0d01c85640b7dfba443

commit 633ece90258d09106ff5d0d01c85640b7dfba443
Author:     He Yang <[email protected]>
AuthorDate: Wed Feb 24 18:05:15 2021 +0800
Commit:     GitHub <[email protected]>
CommitDate: Wed Feb 24 19:05:15 2021 +0900

    [TASKLIST] Implement tasklist command-line utility (#3440)
    
    Add command-line program "tasklist" for ReactOS.
    It works fine on Windows as well.
---
 base/applications/cmdutils/CMakeLists.txt          |   1 +
 base/applications/cmdutils/tasklist/CMakeLists.txt |   8 +
 base/applications/cmdutils/tasklist/lang/bg-BG.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/ca-ES.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/cs-CZ.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/de-DE.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/el-GR.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/en-US.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/es-ES.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/et-EE.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/fr-FR.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/it-IT.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/lt-LT.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/no-NO.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/pl-PL.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/pt-BR.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/ro-RO.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/ru-RU.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/sk-SK.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/sq-AL.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/sv-SE.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/tr-TR.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/uk-UA.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/zh-CN.rc  |  20 ++
 base/applications/cmdutils/tasklist/lang/zh-TW.rc  |  20 ++
 base/applications/cmdutils/tasklist/resource.h     |  16 +
 base/applications/cmdutils/tasklist/tasklist.c     | 335 +++++++++++++++++++++
 base/applications/cmdutils/tasklist/tasklist.h     |  29 ++
 base/applications/cmdutils/tasklist/tasklist.rc    |  80 +++++
 29 files changed, 929 insertions(+)

diff --git a/base/applications/cmdutils/CMakeLists.txt 
b/base/applications/cmdutils/CMakeLists.txt
index dd8a7ab2b06..43b10eb6c73 100644
--- a/base/applications/cmdutils/CMakeLists.txt
+++ b/base/applications/cmdutils/CMakeLists.txt
@@ -21,6 +21,7 @@ add_subdirectory(reg)
 add_subdirectory(schtasks)
 add_subdirectory(sort)
 add_subdirectory(taskkill)
+add_subdirectory(tasklist)
 add_subdirectory(timeout)
 add_subdirectory(tree)
 add_subdirectory(whoami)
diff --git a/base/applications/cmdutils/tasklist/CMakeLists.txt 
b/base/applications/cmdutils/tasklist/CMakeLists.txt
new file mode 100644
index 00000000000..a0995d79652
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/CMakeLists.txt
@@ -0,0 +1,8 @@
+
+include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/conutils)
+
+add_executable(tasklist tasklist.c tasklist.rc)
+set_module_type(tasklist win32cui UNICODE)
+target_link_libraries(tasklist conutils ${PSEH_LIB})
+add_importlibs(tasklist msvcrt user32 kernel32 ntdll)
+add_cd_file(TARGET tasklist DESTINATION reactos/system32 FOR all)
diff --git a/base/applications/cmdutils/tasklist/lang/bg-BG.rc 
b/base/applications/cmdutils/tasklist/lang/bg-BG.rc
new file mode 100644
index 00000000000..341da7be914
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/bg-BG.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/ca-ES.rc 
b/base/applications/cmdutils/tasklist/lang/ca-ES.rc
new file mode 100644
index 00000000000..23626df83fb
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/ca-ES.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_CATALAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/cs-CZ.rc 
b/base/applications/cmdutils/tasklist/lang/cs-CZ.rc
new file mode 100644
index 00000000000..08d67e6f556
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/cs-CZ.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/de-DE.rc 
b/base/applications/cmdutils/tasklist/lang/de-DE.rc
new file mode 100644
index 00000000000..d4da3146480
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/de-DE.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/el-GR.rc 
b/base/applications/cmdutils/tasklist/lang/el-GR.rc
new file mode 100644
index 00000000000..fadac1934c6
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/el-GR.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_GREEK, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/en-US.rc 
b/base/applications/cmdutils/tasklist/lang/en-US.rc
new file mode 100644
index 00000000000..7b9e4fdb50a
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/en-US.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/es-ES.rc 
b/base/applications/cmdutils/tasklist/lang/es-ES.rc
new file mode 100644
index 00000000000..e0272ce79e2
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/es-ES.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/et-EE.rc 
b/base/applications/cmdutils/tasklist/lang/et-EE.rc
new file mode 100644
index 00000000000..0bd164f5079
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/et-EE.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_ESTONIAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/fr-FR.rc 
b/base/applications/cmdutils/tasklist/lang/fr-FR.rc
new file mode 100644
index 00000000000..8cb7f76e4cb
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/fr-FR.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/it-IT.rc 
b/base/applications/cmdutils/tasklist/lang/it-IT.rc
new file mode 100644
index 00000000000..3f00e07d32d
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/it-IT.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/lt-LT.rc 
b/base/applications/cmdutils/tasklist/lang/lt-LT.rc
new file mode 100644
index 00000000000..e67893e2ec8
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/lt-LT.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_LITHUANIAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/no-NO.rc 
b/base/applications/cmdutils/tasklist/lang/no-NO.rc
new file mode 100644
index 00000000000..c7422dfa78e
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/no-NO.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/pl-PL.rc 
b/base/applications/cmdutils/tasklist/lang/pl-PL.rc
new file mode 100644
index 00000000000..f4df68a082c
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/pl-PL.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/pt-BR.rc 
b/base/applications/cmdutils/tasklist/lang/pt-BR.rc
new file mode 100644
index 00000000000..66879279545
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/pt-BR.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/ro-RO.rc 
b/base/applications/cmdutils/tasklist/lang/ro-RO.rc
new file mode 100644
index 00000000000..036983fd87a
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/ro-RO.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/ru-RU.rc 
b/base/applications/cmdutils/tasklist/lang/ru-RU.rc
new file mode 100644
index 00000000000..ed72ca602b7
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/ru-RU.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/sk-SK.rc 
b/base/applications/cmdutils/tasklist/lang/sk-SK.rc
new file mode 100644
index 00000000000..6dd000b022f
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/sk-SK.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/sq-AL.rc 
b/base/applications/cmdutils/tasklist/lang/sq-AL.rc
new file mode 100644
index 00000000000..79a7f1581b2
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/sq-AL.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/sv-SE.rc 
b/base/applications/cmdutils/tasklist/lang/sv-SE.rc
new file mode 100644
index 00000000000..7f9938e5cee
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/sv-SE.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/tr-TR.rc 
b/base/applications/cmdutils/tasklist/lang/tr-TR.rc
new file mode 100644
index 00000000000..70723b7bfa6
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/tr-TR.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/uk-UA.rc 
b/base/applications/cmdutils/tasklist/lang/uk-UA.rc
new file mode 100644
index 00000000000..75d9bef68d6
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/uk-UA.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/zh-CN.rc 
b/base/applications/cmdutils/tasklist/lang/zh-CN.rc
new file mode 100644
index 00000000000..04f49dd27f5
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/zh-CN.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/lang/zh-TW.rc 
b/base/applications/cmdutils/tasklist/lang/zh-TW.rc
new file mode 100644
index 00000000000..797b464fed4
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/lang/zh-TW.rc
@@ -0,0 +1,20 @@
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE, "Usage: TASKLIST [/?] [/NH]\n"
+    IDS_DESCRIPTION, "\n\
+Desciption:\
+    This tool displays a list of currently running processes on\n\
+    the machine.\n"
+    IDS_OPTION_TOO_MUCH, "Error: Invalid syntax. '%1' option is not allowed 
more than '%2!d!' time(s).\n"
+    IDS_INVALID_SYNTAX, "Error: Invalid syntax.\n"
+    IDS_INVALID_OPTION, "Error: Unknown or invalid command line option 
specified.\n"
+    IDS_ENUM_FAILED, "Error: Unable to enumerate the process list.\n"
+    IDS_OUT_OF_MEMORY, "Error: Out of memory.\n"
+    IDS_HEADER_IMAGENAME, "Image Name"
+    IDS_HEADER_PID, "PID"
+    IDS_HEADER_SESSION, "Session#"
+    IDS_HEADER_MEMUSAGE, "Mem Usage"
+    IDS_MEMORY_STR, "%s K"
+END
diff --git a/base/applications/cmdutils/tasklist/resource.h 
b/base/applications/cmdutils/tasklist/resource.h
new file mode 100644
index 00000000000..3093a019f75
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/resource.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#define IDS_USAGE           1000
+#define IDS_DESCRIPTION     1001
+#define IDS_OPTION_TOO_MUCH 1002
+#define IDS_INVALID_SYNTAX  1003
+#define IDS_INVALID_OPTION  1004
+#define IDS_ENUM_FAILED     1005
+#define IDS_OUT_OF_MEMORY   1006
+
+#define IDS_HEADER_IMAGENAME 1007
+#define IDS_HEADER_PID       1008
+#define IDS_HEADER_SESSION   1009
+#define IDS_HEADER_MEMUSAGE  1010
+
+#define IDS_MEMORY_STR 1011
diff --git a/base/applications/cmdutils/tasklist/tasklist.c 
b/base/applications/cmdutils/tasklist/tasklist.c
new file mode 100644
index 00000000000..4248e7204f1
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/tasklist.c
@@ -0,0 +1,335 @@
+/*
+ * PROJECT:     ReactOS Tasklist Command
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Displays a list of currently running processes on the computer.
+ * COPYRIGHT:   Copyright 2021 He Yang ([email protected])
+ */
+
+#include "tasklist.h"
+
+// the strings in OptionList are the command-line options.
+// should always correspond with the defines below, in sequence (except 
OPTION_INVALID)
+static PCWSTR OptionList[] = { L"?", L"nh" };
+
+#define OPTION_INVALID    -1
+#define OPTION_HELP       0
+#define OPTION_NOHEADER    1
+
+// the max string length PrintResString can handle
+#define RES_STR_MAXLEN 64
+
+// Print split line
+VOID PrintSplitLine(UINT Length)
+{
+    for (; Length; Length--)
+    {
+        ConPuts(StdOut, L"=");
+    }
+}
+
+// Print spaces
+VOID PrintSpace(UINT Length)
+{
+    ConPrintf(StdOut, L"%*ls", (INT)Length, L"");
+}
+
+// Print a string.
+// if bAlignLeft == TRUE then aligned to left, otherwise aligned to right
+// MaxWidth is the width for printing.
+VOID PrintString(LPCWSTR String, UINT MaxWidth, BOOL bAlignLeft)
+{
+    ConPrintf(StdOut, bAlignLeft ? L"%-*.*ls" : L"%*.*ls", MaxWidth, MaxWidth, 
String);
+}
+
+// Print a string from resource
+// if bAlignLeft == TRUE then aligned to left, otherwise aligned to right
+// MaxWidth is the width for printing.
+// The string WILL be truncated if it's longer than RES_STR_MAXLEN
+VOID PrintResString(HINSTANCE hInstance, UINT uID, UINT MaxWidth, BOOL 
bAlignLeft)
+{
+    if (!hInstance)
+        return;
+    
+    WCHAR StringBuffer[RES_STR_MAXLEN];
+    LoadStringW(hInstance, uID, StringBuffer, _countof(StringBuffer));
+    PrintString(StringBuffer, MaxWidth, bAlignLeft);
+}
+
+// Print a number, aligned to right.
+// MaxWidth is the width for printing.
+// the number WILL NOT be truncated if it's longer than MaxWidth
+VOID PrintNum(LONGLONG Number, UINT MaxWidth)
+{
+    ConPrintf(StdOut, L"%*lld", MaxWidth, Number);
+}
+
+// Print memory size using KB as unit, with comma-separated number, aligned to 
right.
+// MaxWidth is the width for printing.
+// the number WILL be truncated if it's longer than MaxWidth
+BOOL PrintMemory(SIZE_T MemorySizeByte, UINT MaxWidth, HINSTANCE hInstance)
+{
+    if (!hInstance)
+        return FALSE;
+
+    SIZE_T MemorySize = MemorySizeByte >> 10;
+
+    WCHAR NumberString[27] = { 0 }; // length 26 is enough to display 
ULLONG_MAX in decimal with comma, one more for zero-terminated.
+    C_ASSERT(sizeof(SIZE_T) <= 8);
+
+    PWCHAR pNumberStr = NumberString;
+
+    // calculate the length
+    UINT PrintLength = 0;
+    SIZE_T Tmp = MemorySize;
+    UINT Mod = 1;
+
+    do
+    {
+        Tmp /= 10;
+        PrintLength++;
+        Mod *= 10;
+    } while (Tmp);
+
+    for (UINT i = PrintLength; i; i--)
+    {
+        Mod /= 10;
+        *pNumberStr = L'0' + (MemorySize / Mod);
+        MemorySize %= Mod;
+        pNumberStr++;
+        
+        if (i != 1 && i % 3 == 1)
+        {
+            *pNumberStr = L',';
+            pNumberStr++;
+        }
+    }
+
+    WCHAR FormatStr[RES_STR_MAXLEN];
+    LoadStringW(hInstance, IDS_MEMORY_STR, FormatStr, _countof(FormatStr));
+
+    WCHAR String[RES_STR_MAXLEN + _countof(NumberString)] = { 0 };
+
+    StringCchPrintfW(String, _countof(String), FormatStr, NumberString);
+    PrintString(String, MaxWidth, FALSE);
+
+    return TRUE;
+}
+
+VOID PrintHeader(HINSTANCE hInstance)
+{
+    if (!hInstance)
+        return;
+
+    PrintResString(hInstance, IDS_HEADER_IMAGENAME, COLUMNWIDTH_IMAGENAME, 
TRUE);
+    PrintSpace(1);
+    PrintResString(hInstance, IDS_HEADER_PID,       COLUMNWIDTH_PID,       
FALSE);
+    PrintSpace(1);
+    PrintResString(hInstance, IDS_HEADER_SESSION,   COLUMNWIDTH_SESSION,   
FALSE);
+    PrintSpace(1);
+    PrintResString(hInstance, IDS_HEADER_MEMUSAGE,  COLUMNWIDTH_MEMUSAGE,  
FALSE);
+
+    ConPuts(StdOut, L"\n");
+
+    PrintSplitLine(COLUMNWIDTH_IMAGENAME);
+    PrintSpace(1);
+    PrintSplitLine(COLUMNWIDTH_PID);
+    PrintSpace(1);
+    PrintSplitLine(COLUMNWIDTH_SESSION);
+    PrintSpace(1);
+    PrintSplitLine(COLUMNWIDTH_MEMUSAGE);
+
+    ConPuts(StdOut, L"\n");
+}
+
+BOOL EnumProcessAndPrint(BOOL bNoHeader)
+{
+    // Call NtQuerySystemInformation for the process information
+    ULONG ProcessInfoBufferLength = 0;
+    ULONG ResultLength = 0;
+    PBYTE ProcessInfoBuffer = NULL;
+
+    // Get the buffer size we need
+    NTSTATUS Status = NtQuerySystemInformation(SystemProcessInformation, NULL, 
0, &ResultLength);
+
+    // New process/thread might appear before we call for the actual data.
+    // Try to avoid this by retrying several times.
+    for (UINT Retry = 0; Retry < NT_SYSTEM_QUERY_MAX_RETRY; Retry++)
+    {
+        // (Re)allocate buffer
+        ProcessInfoBufferLength = ResultLength;
+        ResultLength = 0;
+        if (ProcessInfoBuffer)
+        {
+            PBYTE NewProcessInfoBuffer = HeapReAlloc(GetProcessHeap(), 0,
+                                                     ProcessInfoBuffer,
+                                                     ProcessInfoBufferLength);
+            if (NewProcessInfoBuffer)
+            {
+                ProcessInfoBuffer = NewProcessInfoBuffer;
+            }
+            else
+            {
+                // out of memory
+                ConResMsgPrintf(StdErr, 0, IDS_OUT_OF_MEMORY);
+                HeapFree(GetProcessHeap(), 0, ProcessInfoBuffer);
+                return FALSE;
+            }
+        }
+        else
+        {
+            ProcessInfoBuffer = HeapAlloc(GetProcessHeap(), 0, 
ProcessInfoBufferLength);
+            if (!ProcessInfoBuffer)
+            {
+                // out of memory
+                ConResMsgPrintf(StdErr, 0, IDS_OUT_OF_MEMORY);
+                return FALSE;
+            }
+        }
+
+        // Query information
+        Status = NtQuerySystemInformation(SystemProcessInformation,
+                                          ProcessInfoBuffer,
+                                          ProcessInfoBufferLength,
+                                          &ResultLength);
+        if (Status != STATUS_INFO_LENGTH_MISMATCH)
+        {
+            break;
+        }
+    }
+
+    if (!NT_SUCCESS(Status))
+    {
+        // tried NT_SYSTEM_QUERY_MAX_RETRY times, or failed with some other 
reason
+        ConResMsgPrintf(StdErr, 0, IDS_ENUM_FAILED);
+        HeapFree(GetProcessHeap(), 0, ProcessInfoBuffer);
+        return FALSE;
+    }
+
+    HINSTANCE hInstance = GetModuleHandleW(NULL);
+    assert(hInstance);
+
+    ConPuts(StdOut, L"\n");
+
+    if (!bNoHeader)
+    {
+        PrintHeader(hInstance);
+    }
+
+    PSYSTEM_PROCESS_INFORMATION pSPI;
+    pSPI = (PSYSTEM_PROCESS_INFORMATION)ProcessInfoBuffer;
+    while (pSPI)
+    {
+        PrintString(pSPI->UniqueProcessId ? pSPI->ImageName.Buffer : L"System 
Idle Process", COLUMNWIDTH_IMAGENAME, TRUE);
+        PrintSpace(1);
+        PrintNum((LONGLONG)(INT_PTR)pSPI->UniqueProcessId, COLUMNWIDTH_PID);
+        PrintSpace(1);
+        PrintNum((ULONGLONG)pSPI->SessionId, COLUMNWIDTH_SESSION);
+        PrintSpace(1);
+        PrintMemory(pSPI->WorkingSetSize, COLUMNWIDTH_MEMUSAGE, hInstance);
+
+        ConPuts(StdOut, L"\n");
+
+        if (pSPI->NextEntryOffset == 0)
+            break;
+        pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + 
pSPI->NextEntryOffset);
+    }
+
+    HeapFree(GetProcessHeap(), 0, ProcessInfoBuffer);
+    return TRUE;
+}
+
+INT GetOptionType(LPCWSTR szOption)
+{
+    if (szOption[0] != L'/' && szOption[0] != L'-')
+    {
+        return OPTION_INVALID;
+    }
+    szOption++;
+
+    for (UINT i = 0; i < _countof(OptionList); i++)
+    {
+        if (!_wcsicmp(OptionList[i], szOption))
+        {
+            return i;
+        }
+    }
+    return OPTION_INVALID;
+}
+
+BOOL ProcessArguments(INT argc, WCHAR **argv)
+{
+    BOOL bHasHelp = FALSE, bHasNoHeader = FALSE;
+
+    for (INT i = 1; i < argc; i++)
+    {
+        INT Option = GetOptionType(argv[i]);
+
+        switch (Option)
+        {
+            case OPTION_HELP:
+            {
+                if (bHasHelp)
+                {
+                    // -? already specified
+                    ConResMsgPrintf(StdErr, 0, IDS_OPTION_TOO_MUCH, argv[i], 
1);
+                    ConResMsgPrintf(StdErr, 0, IDS_USAGE);
+                    return FALSE;
+                }
+                bHasHelp = TRUE;
+                break;
+            }
+            case OPTION_NOHEADER:
+            {
+                if (bHasNoHeader)
+                {
+                    // -nh already specified
+                    ConResMsgPrintf(StdErr, 0, IDS_OPTION_TOO_MUCH, argv[i], 
1);
+                    ConResMsgPrintf(StdErr, 0, IDS_USAGE);
+                    return FALSE;
+                }
+                bHasNoHeader = TRUE;
+                break;
+            }
+            case OPTION_INVALID:
+            default:
+            {
+                ConResMsgPrintf(StdErr, 0, IDS_INVALID_OPTION);
+                ConResMsgPrintf(StdErr, 0, IDS_USAGE);
+                return FALSE;
+            }
+        }
+    }
+
+    if (bHasHelp)
+    {
+        if (argc > 2) // any arguments other than -? exists
+        {
+            ConResMsgPrintf(StdErr, 0, IDS_INVALID_SYNTAX);
+            ConResMsgPrintf(StdErr, 0, IDS_USAGE);
+            return FALSE;
+        }
+        else
+        {
+            ConResMsgPrintf(StdOut, 0, IDS_USAGE);
+            ConResMsgPrintf(StdOut, 0, IDS_DESCRIPTION);
+            return FALSE;
+        }
+    }
+    else
+    {
+        EnumProcessAndPrint(bHasNoHeader);
+    }
+    return TRUE;
+}
+
+int wmain(int argc, WCHAR **argv)
+{
+    /* Initialize the Console Standard Streams */
+    ConInitStdStreams();
+
+    if (!ProcessArguments(argc, argv))
+    {
+        return 1;
+    }
+    return 0;
+}
diff --git a/base/applications/cmdutils/tasklist/tasklist.h 
b/base/applications/cmdutils/tasklist/tasklist.h
new file mode 100644
index 00000000000..1303a34375b
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/tasklist.h
@@ -0,0 +1,29 @@
+/*
+ * PROJECT:     ReactOS Tasklist Command
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Displays a list of currently running processes on the computer.
+ * COPYRIGHT:   Copyright 2020 He Yang ([email protected])
+ */
+
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <assert.h>
+
+#define WIN32_NO_STATUS
+#include <windows.h>
+#include <ntndk.h>
+#include <strsafe.h>
+
+#include <conutils.h>
+
+#include "resource.h"
+
+#define NT_SYSTEM_QUERY_MAX_RETRY 5
+
+#define COLUMNWIDTH_IMAGENAME   25
+#define COLUMNWIDTH_PID         8
+#define COLUMNWIDTH_SESSION     11
+#define COLUMNWIDTH_MEMUSAGE    12
diff --git a/base/applications/cmdutils/tasklist/tasklist.rc 
b/base/applications/cmdutils/tasklist/tasklist.rc
new file mode 100644
index 00000000000..533a21bbc66
--- /dev/null
+++ b/base/applications/cmdutils/tasklist/tasklist.rc
@@ -0,0 +1,80 @@
+#include <windef.h>
+
+#include "resource.h"
+
+#define REACTOS_STR_FILE_DESCRIPTION    "ReactOS Tasklist Command"
+#define REACTOS_STR_INTERNAL_NAME       "tasklist"
+#define REACTOS_STR_ORIGINAL_FILENAME   "tasklist.exe"
+#include <reactos/version.rc>
+
+/* UTF-8 */
+#pragma code_page(65001)
+#ifdef LANGUAGE_BG_BG
+    #include "lang/bg-BG.rc"
+#endif
+#ifdef LANGUAGE_CA_ES
+    #include "lang/ca-ES.rc"
+#endif
+#ifdef LANGUAGE_CS_CZ
+    #include "lang/cs-CZ.rc"
+#endif
+#ifdef LANGUAGE_DE_DE
+    #include "lang/de-DE.rc"
+#endif
+#ifdef LANGUAGE_EL_GR
+    #include "lang/el-GR.rc"
+#endif
+#ifdef LANGUAGE_EN_US
+    #include "lang/en-US.rc"
+#endif
+#ifdef LANGUAGE_ES_ES
+    #include "lang/es-ES.rc"
+#endif
+#ifdef LANGUAGE_ET_EE
+    #include "lang/et-EE.rc"
+#endif
+#ifdef LANGUAGE_FR_FR
+    #include "lang/fr-FR.rc"
+#endif
+#ifdef LANGUAGE_IT_IT
+    #include "lang/it-IT.rc"
+#endif
+#ifdef LANGUAGE_LT_LT
+    #include "lang/lt-LT.rc"
+#endif
+#ifdef LANGUAGE_NB_NO
+    #include "lang/no-NO.rc"
+#endif
+#ifdef LANGUAGE_PL_PL
+    #include "lang/pl-PL.rc"
+#endif
+#ifdef LANGUAGE_PT_BR
+    #include "lang/pt-BR.rc"
+#endif
+#ifdef LANGUAGE_RO_RO
+    #include "lang/ro-RO.rc"
+#endif
+#ifdef LANGUAGE_SK_SK
+    #include "lang/sk-SK.rc"
+#endif
+#ifdef LANGUAGE_SV_SE
+    #include "lang/sv-SE.rc"
+#endif
+#ifdef LANGUAGE_RU_RU
+    #include "lang/ru-RU.rc"
+#endif
+#ifdef LANGUAGE_SQ_AL
+    #include "lang/sq-AL.rc"
+#endif
+#ifdef LANGUAGE_TR_TR
+    #include "lang/tr-TR.rc"
+#endif
+#ifdef LANGUAGE_UK_UA
+    #include "lang/uk-UA.rc"
+#endif
+#ifdef LANGUAGE_ZH_CN
+    #include "lang/zh-CN.rc"
+#endif
+#ifdef LANGUAGE_ZH_TW
+    #include "lang/zh-TW.rc"
+#endif

Reply via email to