2014-01-15 6 views
0

Я работаю над простой консольной программой, написанной на C# последние пару дней на моей стажировке (я программист newb, так что мне потребовались дни, чтобы сделать да).Почему моя программа цикла?

Весь код можно найти здесь:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.IO; 

namespace ConsoleApplication5 
{ 
    class Program 
    { 
     static int maxcheck = 1000; 
     static int stopsearch = 0; 

     public static void ProcessDirectory(string targetDirectory, List<string> foundFiles, List<string> errorFiles) 
     { 
     try 
     { 
      // Process the list of files found in the directory. 
      string [] fileEntries = Directory.GetFiles(targetDirectory); 
      foreach(string fileName in fileEntries) 
      { 
       if (foundFiles.Count() >= maxcheck) 
       { 
        ConsoleKeyInfo answer; 
        Console.Clear(); 
        Console.SetCursorPosition(2, 2); 
        Console.ForegroundColor = ConsoleColor.White; 
        Console.WriteLine("{0} files has been searched.",maxcheck); 
        Console.Write(" Do you wish to continue (Y/N): "); 
        Console.ForegroundColor = ConsoleColor.Green; 
        answer = Console.ReadKey(); 
        Console.Clear(); 
        if(answer.Key == ConsoleKey.Y) 
        { 
         maxcheck = maxcheck + 1000; 
        } 
        if(answer.Key ==ConsoleKey.N) 
        { 
         stopsearch = stopsearch + 1; 
        } 
       } 
       else 
       { 
        ProcessFile(fileName, foundFiles, errorFiles); 
       } 
      } 

      // Recurse into subdirectories of this directory. 
      string [] subdirectoryEntries = Directory.GetDirectories(targetDirectory); 
      foreach(string subdirectory in subdirectoryEntries) 
       ProcessDirectory(subdirectory, foundFiles, errorFiles); 
     } 
     catch(Exception) 
     { 
      errorFiles.Add(targetDirectory); 
     }  

     // Insert logic for processing found files here. 
     public static void ProcessFile(string fileName, List<string> changedFiles, List<string> errorfiles) 
     { 
      //Console.WriteLine("Processed file '{0}'.", path); 
      try 
      { 
       System.IO.FileAttributes attr = System.IO.File.GetAttributes(fileName); 
       if ((attr & System.IO.FileAttributes.ReadOnly) == 0) 
       { 
        attr = attr | System.IO.FileAttributes.ReadOnly; 

        System.IO.File.SetAttributes(fileName, attr); 
        changedFiles.Add(fileName); 
       } 
      } 
      catch (UnauthorizedAccessException) 
      { 
       errorfiles.Add(fileName); 
      } 
      catch (InvalidOperationException) 
      { 
       errorfiles.Add(fileName); 
      } 
      catch (Exception) 
      { 
       errorfiles.Add(fileName); 
      } 
     } 

     static void SetAllFilesAsReadOnly(string rootPath) 
     { 
      Console.ForegroundColor = ConsoleColor.White; 

      List<string> errorfiles = new List<string>(); 
      List<string> changedfiles = new List<string>(); 

      if (stopsearch < 1) 
      { 
       ProcessDirectory(rootPath, changedfiles, errorfiles); 
      } 

      if (changedfiles.Count() > 0) 
      { 
       Console.SetCursorPosition(2, 2); 
       Console.Write("Press any key to see the files that was changed"); 
       Console.ForegroundColor = ConsoleColor.Green; 
       Console.ReadKey(); 
       Console.Clear(); 
       Console.SetCursorPosition(2, 2); 

       foreach (string file in changedfiles) 
       { 
        Console.WriteLine(" " + file); 
       } 

       Console.ForegroundColor = ConsoleColor.White; 
       Console.WriteLine(""); 
       Console.WriteLine(" Write-protection was set on {0} files.", changedfiles.Count()); 
      } 
      else 
      { 
       Console.SetCursorPosition(2, 2); 
       Console.Write("Write-protection was not changed on any files."); 
      } 
      Console.ForegroundColor = ConsoleColor.Black; 
      Console.ReadKey(); 

      if (errorfiles.Count() > 0) 
      { 
       Console.WriteLine(""); 
       Console.WriteLine(" These are the files that was NOT changed:"); 

       foreach (string file in errorfiles) 
       { 
        Console.ForegroundColor = ConsoleColor.Red; 
        Console.WriteLine(" " + file); 
       } 

       Console.ForegroundColor = ConsoleColor.Green; 
       Console.WriteLine(""); 
       Console.WriteLine(" Write-protection could not be set on {0} files.", errorfiles.Count()); 
       Console.ReadKey(); 
      } 
     } 

     static void Main(string[] args) 
     { 
      string pathstring; 

      if ((args.Count() == 0) || (args[0] == "")) 
      { 
       Console.SetCursorPosition(2, 2); 
       Console.Write("Please enter the path of the directory you wish to check: "); 
       Console.ForegroundColor = ConsoleColor.Green; 
       pathstring = Console.ReadLine(); 
      } 
      else 
      { 
       pathstring = args[0]; 
      } 

      Console.Clear(); 
      SetAllFilesAsReadOnly(pathstring);  
     } 
    } 
} 

В основном то, что он делает то, что пользователь записывает путь к папке в окне консоли, и программа сканирует все файлы, там только для чтения атрибут.

Файлы, которые не имеют его, получают, а их имя добавляется в список (changedFiles).

После сканирования всех файлов он останавливается и перечисляет файлы, которые он изменил, и те, которые он не мог (например, файлы, которые в настоящее время используются, не могут быть изменены).

Теперь я пытаюсь сделать так, что после сканирования 1.000 файлов он спрашивает: «Вы хотите продолжить?». Если пользователь нажимает Y, он продолжает и снова запрашивает после 1.000 файлов, и это продолжается до тех пор, пока все файлы не будут отсканированы, тогда программа продолжит работу и перечислит файлы и т. Д.).

Проблема в том, что если пользователь нажимает N (для нет), он просто петли. Сидит, снова спрашивая: «Вы хотите продолжить?».

Как это изменить? Как я могу заставить свою программу просто останавливаться после тех 1.000 файлов (если пользователь ответил НЕТ), но все же у вас есть список файлов, которые он изменил?

+1

Пожалуйста, укажите код, связанный с вашей проблемой в вопросе самого –

+0

Хорошо, извини. В прошлый раз, когда я задал вопрос, меня попросили скопировать код в пастебин. – JFBN

+1

Используйте 'Environment.Exit (0);' http://msdn.microsoft.com/en-us/library/system.environment.exit(v=vs.110).aspx – Chandan

ответ

2

Проблема здесь состоит в том, что вы используете рекурсию, и вы можете быть несколько уровней рекурсии глубоко в точке, где вы хотите, чтобы отменить. Только отмена самой внутренней рекурсии не отменяет внешние вызовы.

Чтобы решить эту проблему, вы можете вернуть булево значение из рекурсивного метода, чтобы увидеть, если он был отменен, как так:

public static bool ProcessDirectory(string targetDirectory, List<string> foundFiles, List<string> errorFiles) 
{ 
    try 
    { 
     // Process the list of files found in the directory. 
     string [] fileEntries = Directory.GetFiles(targetDirectory); 
     foreach (string fileName in fileEntries) 
     { 
      if (foundFiles.Count() >= maxcheck) 
      { 

       ConsoleKeyInfo answer; 
       Console.Clear(); 
       Console.SetCursorPosition(2, 2); 
       Console.ForegroundColor = ConsoleColor.White; 
       Console.WriteLine("{0} files has been searched.", maxcheck); 
       Console.Write(" Do you wish to continue (Y/N): "); 
       Console.ForegroundColor = ConsoleColor.Green; 
       answer = Console.ReadKey(); 
       Console.Clear(); 

       if (answer.Key == ConsoleKey.Y) 
       { 
        maxcheck = maxcheck + 1000; 
       } 
       if (answer.Key == ConsoleKey.N) 
       { 
        return false; 
       } 
      } 
      else 
      { 
       ProcessFile(fileName, foundFiles, errorFiles); 
      } 
     } 

     // Recurse into subdirectories of this directory. 
     string [] subdirectoryEntries = Directory.GetDirectories(targetDirectory); 

     foreach (string subdirectory in subdirectoryEntries) 
      if (!ProcessDirectory(subdirectory, foundFiles, errorFiles)) 
       return false; 

     return true; 
    } 

    catch (Exception) 
    { 
     errorFiles.Add(targetDirectory); 
     return false; // or true if you want to continue in the face of exceptions. 
    } 
} 
+0

Это дает мне ошибку: 'ConsoleApplication5.Program.ProcessDirectory (строка, System.Collections.Generic.List , System.COllections.Generic.Список ) ': не все пути кода возвращают значение. ' – JFBN

+0

@JFBN Попробуйте последнюю версию ... –

+0

Большое спасибо. Это работает для меня. Я не знаю, что такое значение bool, но, похоже, работает. – JFBN

0

Вы можете использовать заявление перерыв, чтобы решить эту проблему

if(answer.Key == ConsoleKey.Y) 
{ 
    maxcheck = maxcheck + 1000; 
}     
if(answer.Key ==ConsoleKey.N) 
{ 
    return; 
} 
+0

Я пробовал: 'if (answer.Key == ConsoleKey.Y) { maxcheck = maxcheck + 1000; } если (ответ.Key == ConsoleKey.N) { break; } ' Это не решило проблему. – JFBN

+0

Вы хотите выполнить нижний цикл foreach, даже если ответ N? – Nil23

+0

Я хочу, чтобы он выполнял «SetAllFilesAsReadOnly», даже если ответ равен N. Попробуйте запустить код в папке с более чем 1.000 файлами и вместо этого нажмите Y. Вы можете увидеть, как он красиво перечисляет все файлы, которые были изменены. Это то, что я хочу, чтобы это делалось, даже если я нажимаю N, чтобы не продолжать. – JFBN

Смежные вопросы