diff --git a/README.md b/README.md index 6c623c7..e7c14aa 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ 本程序通过以下三个命令行参数进行控制: -* `--pid `: 指定目标进程的 ID。此参数在模式 `1` 和 `2` 中为必需参数。 +* `--pid `: 指定目标进程的 ID。此参数在模式 `1` 中为必需参数。模式 `2` 如果没提供 PID,将会排除自身 (把自己的 PID 输入进去)。 * `--mode `: 设置录制模式。此参数必需。 * `0`: 全局环回模式 * `1`: 进程包含模式 @@ -101,6 +101,18 @@ ProcessAudioRecorder.exe --pid 9999 --mode 2 --path D:\meeting_audio.wav ``` +**模式3增强模式:进程排除模式 (排除自身)** + +* **场景**:您需要录制所有系统声音 (模式1),但录出来的音质很差,这时候就可尝试这种模式。 +* **命令**: + ```shell + ProcessAudioRecorder.exe --mode 2 --path d:\Recording.wav + ``` +也可以用简单写法: + ```shell + ProcessAudioRecorder.exe d:\Recording.wav + ``` + ##### **2.2.4 停止录制** 当命令执行成功后,程序将开始录音,您将在控制台窗口看到类似于如下实时状态信息: diff --git a/source/ProcessAudioRecorder.cpp b/source/ProcessAudioRecorder.cpp index 5f039e8..de6c2d8 100644 --- a/source/ProcessAudioRecorder.cpp +++ b/source/ProcessAudioRecorder.cpp @@ -37,6 +37,7 @@ struct CommandLineArgs { int captureMode = 1; std::wstring outputPath; bool isValid = false; + bool pidProvided = false; std::wstring errorMessage; }; @@ -46,6 +47,34 @@ CommandLineArgs ParseCommandLine(int argc, wchar_t* argv[]) { args.errorMessage = L"Error: Too few arguments."; return args; } + + bool hasOptionArgs = false; + for (int i = 1; i < argc; i++) { + std::wstring arg = argv[i]; + if (arg.rfind(L"--", 0) == 0) { + hasOptionArgs = true; + break; + } + } + + if (!hasOptionArgs) { + if (argc != 2) { + args.errorMessage = L"Error: Invalid positional arguments. Expected: ."; + return args; + } + + args.outputPath = argv[1]; + if (args.outputPath.empty()) { + args.errorMessage = L"Error: Output path cannot be empty."; + return args; + } + + args.captureMode = 2; + args.processId = GetCurrentProcessId(); + args.pidProvided = false; + args.isValid = true; + return args; + } std::map params; for (int i = 1; i < argc; i++) { std::wstring arg = argv[i]; @@ -89,14 +118,21 @@ CommandLineArgs ParseCommandLine(int argc, wchar_t* argv[]) { if (args.captureMode == 1 || args.captureMode == 2) { if (params.find(L"pid") == params.end()) { - args.errorMessage = L"Error: Missing required argument --pid for mode 1 or 2."; - return args; + if (args.captureMode == 1) { + args.errorMessage = L"Error: Missing required argument --pid for mode 1."; + return args; + } + args.processId = GetCurrentProcessId(); + args.pidProvided = false; } - args.processId = std::wcstoul(params[L"pid"].c_str(), &endPtr, 10); - if (endPtr == params[L"pid"].c_str() || *endPtr != L'\0' || args.processId == 0) { - args.errorMessage = L"Error: Invalid process ID: " + params[L"pid"] + - L"\nMust be a positive integer."; - return args; + else { + args.processId = std::wcstoul(params[L"pid"].c_str(), &endPtr, 10); + if (endPtr == params[L"pid"].c_str() || *endPtr != L'\0' || args.processId == 0) { + args.errorMessage = L"Error: Invalid process ID: " + params[L"pid"] + + L"\nMust be a positive integer."; + return args; + } + args.pidProvided = true; } } @@ -106,7 +142,8 @@ CommandLineArgs ParseCommandLine(int argc, wchar_t* argv[]) { void usage() { std::wcout << L"Process Audio Recorder - Captures audio from processes or the entire system\n\n" - << L"Usage: ProcessAudioRecorder [--pid ] --mode --path \n\n" + << L"Usage: ProcessAudioRecorder [--pid ] --mode --path \n" + << L" ProcessAudioRecorder \n\n" << L"Options:\n" << L" --pid Target process ID (required for mode 1 and 2)\n" << L" --mode Capture mode (required):\n" @@ -117,7 +154,10 @@ void usage() { << L"Examples:\n" << L" ProcessAudioRecorder --mode 0 --path C:\\system_audio.wav\n" << L" ProcessAudioRecorder --pid 1234 --mode 1 --path C:\\record.wav\n" - << L" ProcessAudioRecorder --pid 5678 --path D:\\audio.wav\n\n" + << L" ProcessAudioRecorder --pid 5678 --path D:\\audio.wav\n" + << L" ProcessAudioRecorder --mode 2 --path D:\\audio.wav\n" + << L" ProcessAudioRecorder --mode 2 --pid 12345 --path D:\\audio.wav\n" + << L" ProcessAudioRecorder D:\\audio.wav\n\n" << L"Exit conditions:\n" << L" - Target process exits (for mode 1 and 2)\n" << L" - User presses Ctrl+C\n"; @@ -174,6 +214,10 @@ int wmain(int argc, wchar_t* argv[]) { hr = loopbackCapture.StartGlobalCaptureAsync(args.outputPath.c_str()); } else { + if (args.captureMode == 2 && !args.pidProvided) { + std::wcout << L"No --pid provided for mode 2. Defaulting to exclude self (PID " + << args.processId << L")." << std::endl; + } if (!IsProcessRunning(args.processId)) { std::wcout << L"Error: Process with ID " << args.processId << L" does not exist or cannot be accessed." << std::endl; return 3;