Консольное приложение C# отвечает на каждую вторую команду?
Я пишу консольное приложение "диспетчер задач", чтобы лучше изучить C#.
У меня есть небольшая проблема в этом. Каждый раз, когда пользователь (я) вводит что-то, что не является командой, приложение должно искать процессы с введенным мной именем / текстом.
Пока это работает, но он просто отвечает каждый раз, когда я набираю свой текст.
Вот мой код:
static void Main(string[] args)
{
string s = "Console Task Manager v1.0.0";
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.SetCursorPosition((Console.WindowWidth - s.Length) / 2, Console.CursorTop);
Console.WriteLine(s);
Console.WriteLine("Type 'exit' for close this application.");
Console.WriteLine("\nPlease type the process what are you looking for:");
while (Console.ReadLine() != "exit")
{
GetProcesses();
}
}
static void GetProcesses()
{
Process[] processes = Process.GetProcessesByName(Console.ReadLine());
foreach(Process process in processes)
{
Console.WriteLine("ID: " + process.Id + " | Name: " + process.ProcessName);
//process.Kill();
}
}
Чтобы лучше представить мою проблему, я добавил скриншот к этому вопросу.Спасибо за помощь.
2 ответа
У вас есть эта проблема, потому что у вас есть Console.ReadLine()
в двух местах. Первый Console.ReadLine()
используется для проверки на выход. Второй используется для получения имени процесса. Затем снова вызывается первый и так далее.
static void Main(string[] args)
{
string s = "Console Task Manager v1.0.0";
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.SetCursorPosition((Console.WindowWidth - s.Length) / 2, Console.CursorTop);
Console.WriteLine(s);
Console.WriteLine("Type 'exit' for close this application.");
Console.WriteLine("\nPlease type the process what are you looking for:");
while (Console.ReadLine() != "exit") // readline 1
{
GetProcesses();
}
}
static void GetProcesses()
{
Process[] processes = Process.GetProcessesByName(Console.ReadLine()); // readline 2
foreach(Process process in processes)
{
Console.WriteLine("ID: " + process.Id + " | Name: " + process.ProcessName);
//process.Kill();
}
}
Если вы посмотрите на поток программы, это выглядит так:
readline 1 (который используется только для проверки выхода)
GetProcesses
readline 2 - чтобы получить имя процесса
GetProcesses возвращает
readline 1
GetProcesses
readline 2 - чтобы получить имя процесса
GetProcesses возвращает
...
Один из способов исправить это - сделать что-то вроде этого:
static void Main(string[] args)
{
string s = "Console Task Manager v1.0.0";
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.SetCursorPosition((Console.WindowWidth - s.Length) / 2, Console.CursorTop);
Console.WriteLine(s);
Console.WriteLine("Type 'exit' for close this application.");
Console.WriteLine("\nPlease type the process what are you looking for:");
string lastCommand = string.Empty;
do
{
lastCommand = Console.ReadLine();
if (lastCommand != "exit")
{
KillProcess(lastCommand);
}
} while (lastCommand != "exit");
}
static void KillProcess(string processName)
{
Process[] processes = Process.GetProcessesByName(processName);
foreach(Process process in processes)
{
Console.WriteLine("ID: " + process.Id + " | Name: " + process.ProcessName);
//process.Kill();
}
}
Изменить: Если вы хотите расширить это и добавить дополнительные команды, вы можете сделать что-то вроде этого, где у вас есть новая функция, которая анализирует команду.
/// <summary>
/// Field that indicates whether or not the program should keep running.
/// </summary>
static bool keepRunning = true;
static void Main(string[] args)
{
string s = "Console Task Manager v1.0.0";
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.SetCursorPosition((Console.WindowWidth - s.Length) / 2, Console.CursorTop);
Console.WriteLine(s);
Console.WriteLine("Type 'exit' for close this application.");
Console.WriteLine("\nPlease type the process what are you looking for:");
do
{
string lastCommand = Console.ReadLine();
ProcessCommand(lastCommand);
} while (keepRunning);
}
/// <summary>
/// Processes a command we've received.
/// </summary>
/// <param name="command">The command that was entered.</param>
static void ProcessCommand(string command)
{
if (string.IsNullOrEmpty(command))
{
return;
}
// A command might have one or more parameters, these will be separated
// by spaces (i.e. "kill 12345").
string[] commandParts = command.Split(' ');
// Process each command we know about.
if (commandParts[0] == "exit")
{
keepRunning = false;
}
else if (commandParts[0] == "kill")
{
// This command needs 1 parameter.
if (commandParts.Length < 2)
{
Console.WriteLine("kill command requires process name or ID");
return;
}
// Try checking if the second value can be parsed to an integer. If so
// we'll assume it's the process ID to kill. Otherwise, we'll try to
// kill the process by that name.
int id;
if (int.TryParse(commandParts[1], out id))
{
KillProcessByID(id);
}
else
{
KillProcessByName(commandParts[1]);
}
}
// More commands can be added here.
// This isn't a known command.
else
{
Console.WriteLine("Unknown command \"" + command + "\"");
}
}
static void KillProcessByName(string processName)
{
Process[] processes = Process.GetProcessesByName(processName);
foreach (Process process in processes)
{
Console.WriteLine("ID: " + process.Id + " | Name: " + process.ProcessName);
//process.Kill();
}
}
static void KillProcessByID(int processID)
{
Process process = Process.GetProcessById(processID);
if (process != null)
{
Console.WriteLine("ID: " + process.Id + " | Name: " + process.ProcessName);
//process.Kill();
}
}
Это потому, что вы читаете консоль 2 раза.
Console.ReadLine ()
действительно ждет взаимодействия с пользователем.
Прочитайте один раз и сохраните значение, затем проверьте, является ли это командой, затем передайте ее вашему методу, чтобы прочитать процесс.