2013-12-02 7 views
-4
public static void GetInstalledApps() 
{ 

string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; 
    RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key); 
    { 
     foreach (string subkey_name in key.GetSubKeyNames()) 
     { 
      RegistryKey subkey = key.OpenSubKey(subkey_name); 
      { 
       Console.WriteLine(subkey.GetValue("DisplayName")); 
      } 
     } 
    } 

Я использую этот метод в консольном приложении C# для отображения программ, установленных на моем компьютере Windows.как отправить мой вывод метода в файл в C#

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

+3

http://msdn.microsoft.com/en-us/library/6ka1wd3w(v=vs.110).aspx – Habib

+0

http://stackoverflow.com/questions/4501511/c-sharp-realtime-console- output-redirection – Nick

+1

http://www.dotnetperls.com/streamwriter –

ответ

0

Вы могли бы заменить

Console.WriteLine(subkey.GetValue("DisplayName")); 

с

if (subkey.GetValue("DisplayName")!=null) 
{ 
    File.AppendAllText(path, subkey.GetValue("DisplayName").ToString()); 
} 

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

См File Methods

+0

Не делайте этого - в любом случае, внутри цикла. Откройте файл после его использования. Закрой его. – user2864740

+0

строка path = @ "c: \ MyTestOutput.txt"; File.AppendAllText (путь, subkey.GetValue ("DisplayName")); Наилучшее перегруженное соответствие метода для 'System.IO.File.AppendAllText (string, string)' имеет некоторые недопустимые аргументы – user3058620

+0

@ user3058620. Мне пришлось добавить 'ToString', поскольку' GetValue' возвращает объект. – Harrison

1

Вы можете использовать File.WriteAllText для создания и записи в файл

+0

Хотя это «будет работать», это требует изменения кода в необязательных целях. Для удобства, простой TextWriter.Write, вероятно, имеет больше смысла. – user2864740

+0

@ user2864740 Как так? –

+0

Это полностью перезаписывает код (и в настоящее время переписывает его * по-разному *) - пока он будет работать, вводит ряд концепций разницы и требует предварительного построения всего вывода. Файлы - это потоки. – user2864740

1

Вот подсказка: System.Console.WriteLine() довольно много просто обертка для System.Console.Out.WriteLine().

System.Console.Out является примером System.IO.TextWriter, абстрактного класса. Конкретной реализацией которой вы захотите, является StreamWriter.

StreamWriter удобно, обертывает Stream (еще один абстрактный класс).

Конкретная реализация Stream, которую вы захотите, - это очень умное имя FileStream, основное средство записи в файл.

Обратите внимание, что классы File и FileInfo предлагают простое средство для открытия файла для записи и получения StreamWriter для этого файла.

+0

строка path = @ "c: \ MyTestOutput.txt"; File.AppendAllText (путь, subkey.GetValue ("DisplayName")); Наилучшее перегруженное соответствие метода для 'System.IO.File.AppendAllText (string, string)' имеет некоторые недопустимые аргументы – user3058620

0

Как указывает ответ Николаса Кэри, Console.WriteLine просто записывает в поток текста TextWriter Console.Out.

Зная эту информацию, мы можем переписать оригинальный метод следующим образом:

public static void GetInstalledApps(TextWriter writer) 
{  
    string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; 
    RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key); 
    { 
     foreach (string subkey_name in key.GetSubKeyNames()) 
     { 
      RegistryKey subkey = key.OpenSubKey(subkey_name); 
      { 
       // While this won't throw an Exception when GetValue returns null, 
       // as WriteLine will "output nothing" for null values, 
       // this logic might be bugged: the next example has a possible solution. 

       // No more hard-coding of Console.WriteLine, instead we use 
       // writer.WriteLine, where writer is the TextWriter that 
       // has been supplied as an argument. 
       writer.WriteLine(subkey.GetValue("DisplayName")); 
      } 
     } 
    } 
} 

Тогда код можно следующим образом, чтобы получить оригинальную семантику записи на консоль.

GetInstalledApps(Console.Out); 

Теперь предположим, что мы хотим, чтобы написать в различного потока, мы должны просто указать его. Из link provided in a comment мы видим, как легко создать StreamWriter для файла. StreamWriter extends TextWriter может, таким образом, быть передан нашему методу. Таким образом, легко записать в файл:

using (StreamWriter writer = new StreamWriter("theFile.txt")) 
{ 
    GetInstalledApps(writer); 
} 

Однако я бы предложил переместить запись из метода. То есть, метод должен делать только один вещь: он должен только выбрать установленных приложений.

Таким образом, рассмотрим следующий код, который использует yield для создания неявного итератора. Тем не менее, создание/возвращение списка программно или использование LINQ для генерации результата Enumerable также отлично работали бы. Я также модифицировал функцию таким образом, чтобы она возвращала значение, даже если нет DisplayName.

public static IEnumerable<string> GetInstalledApps() 
{  
    string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; 
    RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key); 
    { 
     foreach (string subkey_name in key.GetSubKeyNames()) 
     { 
      RegistryKey subkey = key.OpenSubKey(subkey_name); 
      { 
       // I've also added fix for what I believe that was a "silent bug" 
       // that allowed entries without a display name to be "lost". 
       // This code returns the subkey name if there is no display name. 
       var value = subkey.GetValue("DisplayName") as string; 
       if (!string.IsNullOrEmpty(value)) { 
        yield return value; 
       } else { 
        // No display name, but there is still an entry!!     
        yield return subkey_name; 
       } 
      } 
     } 
    } 
} 

Тогда мы можем двигаться использования данных вне функцию, которая извлекает данные - это уменьшает сцепление и делает код более гибким. Возможно, позже мы захотим использовать код для обновления ListBox вместо записи в файл.

using (StreamWriter writer = new StreamWriter("theFile.txt")) 
{ 
    foreach (var app in GetInstalledApps()) { 
     writer.WriteLine(app); 
    } 
} 

Если GetInstalledApps написано в приведенной выше способом, где она отделяет из концерна IO, то также может быть использован с File.*AllText после простого преобразования IEnumerable<string> в соответствующую строку, например, с String.Join. Тем не менее, я все равно использовал бы цикл и WriteLine в соответствии с приведенным выше, если бы мне не понадобилось возвращать строковый объект.

+0

спасибо большое, что это имело смысл – user3058620

+0

@ user3058620 Добро пожаловать. Я исправил ошибку со вторым GetInstalledApps, который привел бы к ошибке типа - в частности, я добавил GetValue (..) как строку '(поскольку возвращаемый тип GetValue является объектом). – user2864740

+0

@ user3058620 При дальнейших проверках кажется, что вы захотите вернуть значение * даже *, когда GetValue ("DisplayName") возвращает null. Я сделал другое редактирование для второго GetInstalledApps таким образом, что он вернет имя subkey_, если нет названия - это позволит избежать «пропущенных» некоторых установленных приложений. – user2864740

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