Mendax M.
Mendax M.

Reputation: 5

c# console application respond every second command?

i'm writing a console application "task manager" to learning better C#.

I got a little problem in it. Every times the user (me) type something what isnt an command, the application should looking for processes with the name/text i've typed.

So far it works, but it just respont every second time i type my text.

Here's my code:

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

For better imagine of my problem, i've added a screenshot to this question. Screenshot Thank you for help.

Upvotes: 0

Views: 265

Answers (1)

gunnerone
gunnerone

Reputation: 3572

You're having this problem because you have Console.ReadLine() in two places. The first Console.ReadLine() is used to check for exiting. The second one is used to get the process name. Then the first one gets called again, and so on.

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

If you look at the program flow it's like this:

readline 1 (which is only used to check for exit)
GetProcesses
readline 2 - to get process name
GetProcesses returns
readline 1
GetProcesses
readline 2 - to get process name
GetProcesses returns
...

One way to fix it would be to do something like this:

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: If you want to extend this further and add additional commands, you might do something like this, where you have a new function that parses the command.

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

Upvotes: 4

Related Questions