консольное приложение c # отвечает на каждую вторую команду? - PullRequest
0 голосов
/ 28 июня 2018

Я пишу консольное приложение "Диспетчер задач" для лучшего изучения 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();
        }
    }

Чтобы лучше представить мою проблему, я добавил скриншот к этому вопросу. Screenshot Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Это потому, что вы читаете консоль 2 раза.

Console.ReadLine ()

ожидает взаимодействия с пользователем.

Прочитайте один раз и сохраните значение, затем проверьте, является ли это командой, а затем передайте ее в свой метод для чтения процесса.

0 голосов
/ 28 июня 2018

У вас возникла эта проблема, потому что у вас есть 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();
    }
}

Edit: Если вы хотите расширить это и добавить дополнительные команды, вы можете сделать что-то вроде этого, где у вас есть новая функция, которая анализирует команду.

/// <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();
  }
}
...