Skip to content

Commit 0f08b60

Browse files
committed
Improve command-line help and user experience
Changes: - Show help automatically when no arguments provided - Add examples in help description - Improve error messages with full help text - Use more descriptive parameter names (process_id instead of id) - Better help formatting with custom_help() Now running './ghostinjector.exe' without arguments shows help page.
1 parent 9da0afe commit 0f08b60

1 file changed

Lines changed: 15 additions & 16 deletions

File tree

src/main.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,26 @@ int main(int argc, char *argv[])
4141
return EXIT_FAILURE;
4242

4343
// Parse command line arguments with cxxopts
44-
cxxopts::Options options("GhostInjector", "DLL Injection tool for Windows processes");
44+
cxxopts::Options options("GhostInjector",
45+
"DLL Injection tool for Windows processes\n\n"
46+
"Examples:\n"
47+
" ghostinjector.exe 1234 mydll.dll\n"
48+
" ghostinjector.exe 5678 first.dll second.dll third.dll");
4549

4650
options.add_options()
47-
("h,help", "Print usage")
48-
("positional", "Positional arguments: <id> <dll_paths...>",
51+
("h,help", "Print this help message")
52+
("positional", "Process ID and DLL path(s)",
4953
cxxopts::value<std::vector<std::string>>());
5054

5155
options.parse_positional({"positional"});
52-
options.positional_help("<id> <dll_path> [dll_path2 ...]");
56+
options.positional_help("<process_id> <dll_path> [dll_path2 ...]");
57+
options.custom_help("[OPTIONS] <process_id> <dll_path> [dll_path2 ...]");
5358

5459
try {
5560
auto result = options.parse(argc, argv);
5661

57-
if (result.count("help")) {
62+
// Show help if no arguments or --help flag
63+
if (argc == 1 || result.count("help")) {
5864
#ifdef LOG_LEVEL_1
5965
LOG_INFO("%s", options.help().c_str());
6066
#else
@@ -65,24 +71,17 @@ int main(int argc, char *argv[])
6571
}
6672

6773
if (!result.count("positional")) {
68-
#ifdef LOG_LEVEL_1
69-
LOG_INFO("Usage: %s <id> <dll_path> [dll_path2 ...]", argv[0]);
70-
#else
71-
std::cout << "Usage: " << argv[0] << " <id> <dll_path> [dll_path2 ...]" << std::endl;
72-
#endif
74+
std::cerr << "Error: Missing required arguments" << std::endl;
75+
std::cerr << std::endl << options.help() << std::endl;
7376
neptune_destroy();
7477
return 0x10;
7578
}
7679

7780
auto& positional = result["positional"].as<std::vector<std::string>>();
7881

7982
if (positional.size() < 2) {
80-
#ifdef LOG_LEVEL_1
81-
LOG_ERROR("Not enough arguments. Usage: %s <id> <dll_path> [dll_path2 ...]", argv[0]);
82-
#else
83-
std::cerr << "Not enough arguments. Usage: " << argv[0]
84-
<< " <id> <dll_path> [dll_path2 ...]" << std::endl;
85-
#endif
83+
std::cerr << "Error: Not enough arguments (need at least PID and one DLL path)" << std::endl;
84+
std::cerr << std::endl << options.help() << std::endl;
8685
neptune_destroy();
8786
return 0x10;
8887
}

0 commit comments

Comments
 (0)