429

Разработка программы Каталогизатор дисков

Курсовая

Информатика, кибернетика и программирование

В данной пояснительной записке рассматривается описание программы Dark Catalog. В качестве основного инструмента разработки применяется Microsoft Visual Studio 2005. Язык программирования C#.

Русский

2012-11-16

605.5 KB

58 чел.

Федеральное агентство по образованию  (Рособразование)

Архангельский государственный технический университет

 Информационных технологий

 (наименование кафедры)

 

  

(фамилия, имя, отчество студента)

 

Факультет курс группа  

 

 

 

 КУРСОВАЯ  РАБОТА 

  

По дисциплине Технология программирования

  

На тему Разработка программы «Каталогизатор дисков»

 (наименование темы)

  

  

       

Работа допущена к защите    

  (подпись руководителя)  (дата)

       

       

       

Признать, что работа   

 выполнена и защищена с оценкой  

   

    

Руководитель  ст. преп.    М.Ю. Веретнов

  (должность)  (подпись)  (и.,о., фамилия)

      

  (дата)     

       

       

       

Архангельск

 2008


Федеральное агентство по образованию  (Рособразование)

Архангельский государственный технический университет

Информационных технологий

(наименование кафедры)

ЗАДАНИЕ  НА  КУРСОВУЮ РАБОТУ

по

Технологии программирования

(наименование дисциплины)

студенту

ОНОТ

факультета

1

курса

7282

группы

(фамилия, имя, отчество студента)

ТЕМА:

Разработка программного средства

ИСХОДНЫЕ ДАННЫЕ:

разработать программное средство в

соответствии с выданной темой на языке программирования  C#

В пояснительной записке рассмотреть следующие вопросы:

  1.  Разработать техническое задание на разработку ПС
  •  определить образ и границы проекта;
  •  построить модель качества программного средства;
  •  определить информационную среду, в которой должно работать ПС;
  •  Определить функциональные характеристики
  •  Рассмотреть критические состояния информационной среды и реакцию ПС для каждого состояния.

  1.  Спроектировать архитектуру приложения и структуру данных
  •  Выбрать архитектуру разрабатываемого ПС;
  •  При необходимости спроектировать структуру данных.

  1.  Разработать программное средство
  •  Привести спецификацию модулей;
  •  Рассмотреть основные алгоритмы, реализованные в ПС.

  1.  Разработать пользовательскую документацию

  1.  Провести аттестацию ПС

Срок проектирования с

«

1

»

июня

2009 г. по

«

1

»

ноября

2009 г.

Руководитель проекта

ст. преп.

М.Ю. Веретнов

(должность)

(подпись)

(и.,о., фамилия)


СОДЕРЖАНИЕ

ВВЕДЕНИЕ           5

  1.  ВНЕШНЕЕ ОПИСАНИЕ
    1.  Определение требований к программному средству   6
    2.  Терминология         6
    3.  Спецификация качества программного обеспечения   6
    4.  Функциональная спецификация      7
  2.  ПРОЕКТИРОВАНИЕ
    1.  Проектирование архитектуры приложения     8
    2.  Проектирование структуры данных       8
    3.  Проектирование графического интерфейса     9
  3.  ПРОГРАММИРОВАНИЕ
    1.  Спецификация классов                15
    2.  Описание алгоритма на естественном языке            16
  4.  АТТЕСТАЦИЯ
    1.  Тестирование                 20
    2.  Руководство администратора               22
    3.  Руководство пользователя               22

ЗАКЛЮЧЕНИЕ                  23

СПИСОК ЛИТЕРАТУРЫ                24

ПРИЛОЖЕНИЕ А - Листинг программы              25


Введение

В данной пояснительной записке рассматривается описание программы «Dark Catalog».

Данная программа предназначена для управления коллекцией дисков пользователя со смешанным содержимым (исполняемые файлы, аудио, видео, изображения и прочее). Пользователь может создавать образы своих дисков и распределять их по категориям с целью быстрого поиска нужных файлов. В программе реализована гибкая система поиска нужных файлов в образах, также присутствует возможность поиска вставленного в дисковод диска в базе образов. Со стороны пользователя программа очень проста в использовании и имеет простой и интуитивно-понятный интерфейс.

В качестве основного инструмента разработки применяется Microsoft Visual Studio 2005. Язык программирования C#.


1 ВНЕШНЕЕ ОПИСАНИЕ

1.1 Определение требований к программному средству

Программа должна сканировать компакт-диски (CD, DVD) и сохранять их образы в базу образов на жесткий диск. Также должны быть гибкая система поиска, возможность экспорта списка файлов в популярные текстовые форматы. Должна быть реализована справочная система.

1.2 Терминология

Образ – файл, содержащий информацию о файловой системе какого либо диска или каталога. Данные файлы находятся в рабочем каталоге программы.

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

Элемент образа – файл или папка в образе, содержит в себе информацию о:

  •  имени и типе элемента
  •  атрибутах (только для чтения, архивный, скрытый, системный);
  •  дате создания и изменения;
  •  размере в байтах.

1.3 Спецификация качества программного обеспечения

Функциональность: программа должна являться полностью завершенным программным продуктом, не требующим каких-либо дополнительных специальных компонентов.

Надёжность: программа должна быть автономной.

Эффективность: программа должна функционировать без наличия привода CD/DVD-дисков, должна предъявлять минимальные требования к аппаратному обеспечению,  требования к аппаратным ресурсам должны быть намного ниже, чем для самой ОС. Программа должна иметь интуитивно понятный пользовательский графический интерфейс.

1.3 Функциональная спецификация

Минимальные технические характеристики компьютера, на котором гарантируется стабильная работа программы:

  •  компьютер/процессор: компьютер с процессором класса Pentium II 450 МГц;
  •  память: 64 МБ ОЗУ;
  •  монитор: монитор Super VGA с разрешением 800x600 точек или более высоким, поддерживающий 256 цветов;
  •  операционная система: операционная система Windows 2000, необходимо наличие Microsoft .NET Framework Runtime v2.0;
  •  наличие свободного дискового пространства на жёстком диске (порядка 2-4 мегабайт для одного образа).

Внешние функции:

  •  создание образа диска или папки;
  •  управление категориями и образами (создание, удаление, переименование);
  •  гибкая система поиска файлов и папок в базе образов;
  •  фильтр категорий (отображение только определённых категорий);
  •  экспорт списка файлов в несколько текстовых форматов файлов;
  •  программа должна выполнять все функции за конечное количество времени;
  •  программа должна иметь контекстную справку.

Критические случаи:

  •  отсутствие свободного места на жёстком диске при сохранении образов. Любая операция с файловой системой должна быть отменена;
  •  отсутствие разрешения на чтения файла или директории. Данные директория или файл должны быть пропущены;
  •  завершение работы Windows. В этом случае программа должна завершать свою работу, не применяя выбранные пользователем настройки.

2 ПРОЕКТИРОВАНИЕ

2.1 Проектирование архитектуры приложения

Данное программное средство можно разбить на подсистемы, взаимодействующие друг с другом.

Рисунок 1 - Структура программы

Подсистема работы с образом предоставляет методы управления образом. Реализованы функции создания образа, его сохранения и загрузки, доступ к элементам образа, поиска в образе элемента по его пути.

Подсистема работы с базой предоставляет доступ к управлению базой:

  •  создание, удаление, переименование категорий;
  •  ручная сортировка категорий;
  •  создание, удаление, переименование образов;
  •  перемещение и копирование образа из одной категории в другую;
  •  предоставление подробной информации об элементе образа.

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

Подсистема управления настройками – реализованы методы сохранения и загрузки настроек пользовательского интерфейса и параметров поиска.

2.2 Проектирование структуры данных

Структура базы образов.

База образов представляет собой структуру каталогов и файлов образов. Корневым каталогов для базы является каталог «db», который в свою очередь находится в рабочем каталоге программы.

Рисунок 2 – Организация базы образов

В корневом каталоге базы содержать папки и файл «category.txt». Каждая папка соответствует одноименной категории и содержит файлы образов. При перемещении или копировании образа, он перемещается или копируется соответственно из исходной папки категории в папку категорию назначения.

Файл «category.txt» текстовый файл, каждая строка которого является именем категории. Порядок строк в этом файле определяет сортировку категорий в дереве образов.

Структура файла образа.

Файл образа – XML-файл следующей структуры:

<Element>

     <Name>Имя элемента: string</Name>

     <Type>Тип элемента: dir | file</Type>

     <Size>Размер в байтах: integer</Size>

     <CreateTime>Дата создания: DateTime</CreateTime>

     <ChangeTime>Дата изменения: DateTime</ChangeTime>

     <Attr

AttrHidden="false" – атрибут «Скрытый»: bool

AttrSystem="false" – атрибут «Системный»: bool

AttrReadOnly="false" – атрибут «Только для чтения»: bool

AttrArchive="false" – атрибут «Архивный»: bool

/>

     <Sub>

 <Element>

  …

 </Element>

     </Sub>

</Element>

Образы имеют расширение «.xml». Файл создаётся стандартными средствами библиотек .NET через сериализацию.

2.3 Проектирование графического интерфейса

Главная форма содержит основные элементы интерфейса и даёт доступ к большинству функциям.

Рисунок 3 - главная форма программы

Форма FMain содержит следующие элементы управления:

  •  дерево категорий и образов. В дереве отображается файловая система дисков в древовидной структуре. Управление элементами дерева осуществляется через контекстное меню;
  •  список файлов. Показывает список файлов в выбранной в дереве папке;
  •  главное меню. Через главное меню осуществляется доступ к основным функциям программы;
  •  поле поиска;
  •  строка состояния.

Главное меню содержит следующие пункты:

  •  Программа: подменю включает в себя пункты вызова мастера создания образов и интерфейс для поиска диска в базе;

Рисунок 4 - Меню «Программа»

  •  Поиск: настройки поиска;

Рисунок 5 - Меню «Поиск»

  •  Вид: настройки внешнего вида;

Рисунок 6 - Меню «Вид»

  •  Категория: подменю реализует интерфейс для фильтра категорий (в дерево образов будут отображаться только выделенные в фильтре категории);

Рисунок 7 - Меню «Категории»

  •  Экспорт: экспорт текущего списка файлов в один из трёх текстовых форматов;

Рисунок 8 - Меню «Экспорт»

  •  Помощь: подменю даёт доступ к вызову справочной системы, просмотру истории версий и окну «О программе»;

Рисунок 9 - Меню «Помощь»

  •  Отменить действие: временный пункт, который виден только в процессе операций загрузки дерева и поиска. Позволяет остановить текущую операцию.

Форма FMaster предоставляет пользователю удобный интерфейс для создания образов в виде мастера.

Рисунок 10 - Окно мастера создание образа - шаг 1

Рисунок 11 - Окно мастера создание образа - шаг 3

Рисунок 12 - Окно мастера создание образа - шаг 4

Рисунок 13 - Окно мастера создание образа - шаг 5

Форма FProperties выводит окно свойств файла или папки.

Рисунок 14 - Окно свойств

Форма FAbout отображает информацию о программе и и разработчике, а также историю версий программы.

Рисунок 15 - Окно «О программе»

3 ПРОГРАММИРОВАНИЕ

3.1 Спецификация классов

Подсистема работы с образом. В этой подсистеме реализованы методы сканирования заданной папки, методы сохранения и загрузки образа из файла (при указании пути к нему). После загрузки образа есть возможность получить доступ к любому из его элементов. Все функции подсистемы реализованы в классе FolderStruct:

  •  public Element Folders - поле предоставляющее доступ к файловой системе. Структура Element описана в файле «FolderStruct.cs»;
  •  public FolderStruct(string Path, FolderStructCreateMode Mode) - конструктор класса, в зависимости от параметра Mode будет производится загрузка образа или сканирование указанного каталога;
  •  public void XmlSerialization(string Path) - запись образа в файл;
  •  public void XmlDeserialization(string Path) - загрузка образа из файла;
  •  public Element Find(string Path) - поиск папки или файла в образе по заданному пути.

Подсистема управления базой. Сюда входят методы создания, переименования, удаления категорий и образов, а также функции копирования или перемещения образов из одной категории в другую. Эта подсистема очень тесно связана с подсистемой интерфейса. Кроме обработчиков событий контекстного меню к основным методам этой подсистемы можно отнести следующие методы:

  •  void CategoryListSave() - сохраниение списка категорий;
  •  void CategoryListLoad() - загрузка списка категорий;
  •  void CategoryListMenu() - создание меню «Категории» по текущему списку категорий.

Подсистема чтения и сохранения настроек - включает в себя функции управления настройками. При запуске программы настройки считываются из файла, после чего необходимым элементам интерфейса присваиваются нужные значения. Перед закрытием программы все настройки записываются в файл. Методы этой подсистемы:

  •  void CFGSave() – сохранение настроек в файл;
  •  void CFGLoad() – загрузка настроек из файла.

Подсистема экспорта - реализует возможность сохранять список файлов в один из трёх доступных текстовых форматов:

  •  текстовый файл;
  •  файл гипертекстовой разметки (HTML);
  •  текстовый файл с разделителем полей (CSV).

Подсистема интерфейса - объединяет все остальные подсистемы. Здесь реализован весь пользовательский интерфейс, а также функции поиска и загрузки дерева образов. Основные методы:

  •  void TreeRefresh() - обновление дерева образов;
  •  void TreeSearchStart() - поиск;
  •  void GetList(string Path) - загрузка списка файла по выбранному в дерево элементу;
  •  private void listView_DoubleClick() - обработчик события - двойной клик по списку файлов;
  •  private void treeView_AfterLabelEdit() - обработчик события - вызывается при смене выделения в дереве.

3.2 Описание алгоритма на естественном языке

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

Алгоритм сканирования диска и сохранения образа. В каждом каталоге выбранной папки рекурсивно ищутся все файлы, и информация о них заносится в поле Folders класса FolderStruct. Далее это поле сохраняется в файл, используя средства сериализации данных в формат XML.

Рисунок 16 – Блок-схема алгоритма создания образа

Алгоритм поиска диска в базе. Сканируется выбранный диск и затем поэлементно сравнивается с образами из базы. В случае 100% совпадения диск считается найденным.

Алгоритм загрузки дерева. Сначала загружается список категорий, после для каждой категории создаётся список входящих в неё образов, далее каждый образ сканируется и добавляется в дерево.

Рисунок 17 – Блок-схема алгоритма загрузки дерева образов

Алгоритм поиска базе. Перед началом поиска дерево категорий обновляется (опционально). Далее осуществляется рекурсивный спуск (до узла без дочерних элементов) по дереву загружая список файлов в структуру Element для каждого узла дерева. В этом списке ищутся совпадения искомой строки в именах файлов.

Рисунок 18 – Блок-схема алгоритма поиска в базе


4 АТТЕСТАЦИЯ

4.1 Тестирование

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

Тест 1. Создание образа диска.

При создании образа в качестве пути к каталогу был указан путь к CD-диску. Сканирование диска прошло успешно. Далее была выбрана одна из категории и введено имя образа. Образ был успешно сохранён. При вводе некорректного имени или имени уже существующего файла выдавалось сообщение с предупреждением.

Рисунок 19 – Реакция программы на совпадение имён образов

Рисунок 20 – Реакция программы на некорректное имя образа

Тест 2. Создание категории.

При выборе соответствующего пункта меню, была создана пустая категорию и, было предложено ввести её имя. После ввода имени категория была успешно создана. При потере фокуса деревом образов или при нажатии клавиши Esc создание отменялось.

Рисунок 21 – Создание категории

Тест 3. Поиск файла в базе образов.

В текстовое поле поиска была введена часть имени искомого файла. После нажатия кнопки «->» был начат поиск. По окончании поиска в дереве образов остались только те узлы, которые либо сами удовлетворяют критериям поиска, либо содержать в себе элементы, удовлетворяющие критериям поиска. При нажатии на пункт меню «Отменить операцию» поиск останавливался.

Рисунок 22 – Результат поиска

Тест 4. Сканирование каталогов с запрещённым доступом.

При создании образа был указан путь содержащий каталоги с запрещённым доступом. Сканирование и сохранение прошло успешно. Сканирование в закрытых папках было пропущено.

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

4.2 Руководство администратора.

Программа поставляется в виде исполнимого файла «dc_setup.exe» размером 1.14 Мб (версия 1.2). Для установки запустите файл установки и следуйте дальнейшим указаниям мастера установки.

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

4.3 Руководство пользователя.

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

Для создания нового образа выберите пункт «Создать новый образ» в меню «Программа». После этого будет запущен мастер создания образов. Следуя его указаниям, создайте новый образ.

Для управления категориями и образами используйте контекстное меню дерева образов.

Что бы найти нужный файл в базе, введите имя или часть имени файла в поле поиска и нажмите кнопку «->». Параметры поиска можно задать в меню «Поиск».

В случае возникновения трудностей в работе программы воспользуйтесь справочной системой. Её можно вызвать, нажав клавишу F1 на вашей клавиатуре или выбрав пункт «Справка» в меню «Помощь».


ЗАКЛЮЧЕНИЕ

В рамках курсовой работы была  разработана программа-каталогизатор дисков «Dark Catalog». В процессе проектирования использовались методологии модульного и объектно-ориентированного программирования.

Для разработки данной программы, нужно было грамотно спроектировать внутреннюю архитектуру программы и реализацию необходимых классов. Главная сложность в реализации данной программы - создание класса, описывающего файловую систему и написание методов для работы с этим классом, а так же операции с деревьями (рекурсивный поиск, загрузка из нескольких файлов). Опыт, полученный при написании данной программы можно применить в таких проектах, например как медиабиблиотека.

При разработке данного программного средства применялся  язык программирования С#, как один из наиболее современных и перспективных языков программирования.


СПИСОК ИСПОЛЬЗУЕМЫХ ИСТОЧНИКОВ

  1.  Microsoft Corporation, MSDN Library – 2005
  2.  Е. А. Жоголев «Технология программирования» - М., Научный мир, 2004, 216 с.
  3.  Э. Троелсен «С# и платформа .NET. Библиотека программиста.» - Спб., Питер, 2004, 796 с.


ПРИЛОЖЕНИЕ А

Листинг модуля FolderStruct.cs

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Xml.Serialization;

using System.Security;

using System.Security.Permissions;

namespace Lenny.FolderStruct

{

   public struct fsAttribute

   {

       [XmlAttribute]

       public bool AttrHidden;

       [XmlAttribute]

       public bool AttrSystem;

       [XmlAttribute]

       public bool AttrReadOnly;

       [XmlAttribute]

       public bool AttrArchive;

       public fsAttribute(string Path)

       {

           AttrHidden = false;

           AttrSystem = false;

           AttrReadOnly = false;

           AttrArchive = false;

           FileAttributes fa = File.GetAttributes(Path);

           if ((fa & FileAttributes.Hidden) == FileAttributes.Hidden)

               AttrHidden = true;

           if ((fa & FileAttributes.System) == FileAttributes.System)

               AttrSystem = true;

           if ((fa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)

               AttrReadOnly = true;

           if ((fa & FileAttributes.Archive) == FileAttributes.Archive)

               AttrArchive = true;

       }

   }

   public struct Element

   {

       public string Name;

       public string Type;

       public uint Size;

       public DateTime CreateTime;

       public DateTime ChangeTime;

       public fsAttribute Attr;

       public List<Element> Sub;

       public override string ToString()

       {

           return Name;

       }

       void GetFilesRec(Element E, ref string[] S)

       {

           Array.Resize(ref S, S.Length + 1);

           S[S.Length - 1] = E.Name;

           for (int i = 0; i < E.Sub.Count; i++)

               GetFilesRec(E.Sub[i], ref S);

       }

       public string[] GetFiles()

       {

           string[] S = new string[0];

           GetFilesRec(this, ref S);

           return S;

       }

       static bool EqualsByFiles(Element A, Element B)

       {

           string[] s1 = A.GetFiles();

           string[] s2 = B.GetFiles();

           if (s1.Length != s2.Length)

               return false;

           for (int i = 0; i < s1.Length; i++)

               if (s1[i] != s2[i])

                   return false;

           return true;

       }

       public static bool operator ==(Element A, Element B)

       {

           return EqualsByFiles(A, B);

       }

       public static bool operator !=(Element A, Element B)

       {

           return !EqualsByFiles(A, B);

       }

   }

   enum FolderStructCreateMode { Scan, XmlDeserialization }

   class FolderStruct

   {

       Element FFolders;

       public Element Folders

       {

           get { return FFolders; }

           set { FFolders = value; }

       }        

       public FolderStruct()

       {

       }

       public FolderStruct(string Path, FolderStructCreateMode Mode)

       {

           FFolders = new Element();

           switch (Mode)

           {

               case FolderStructCreateMode.Scan:

                   FFolders = ScanFolder(Path);

                   break;

               case FolderStructCreateMode.XmlDeserialization:

                   XmlDeserialization(Path);

                   break;

           }

       }

       public Element ScanFolder(string Path)

       {

           Element E = ScanFolderRec(Path);

           DriveInfo[] adi = DriveInfo.GetDrives();

           foreach (DriveInfo di in adi)

               if (E.Name.ToUpper() + '\\' == di.Name.ToUpper())

               {

                   E.Name = di.VolumeLabel;

                   break;

               }

           return E;

       }

       public void XmlSerialization(string Path)

       {

           XmlSerializer xmls = new XmlSerializer(typeof(Element));

           TextWriter writer = new StreamWriter(Path);

           xmls.Serialize(writer, FFolders);

           writer.Close();

       }

       public void XmlDeserialization(string Path)

       {

           XmlSerializer xmls = new XmlSerializer(typeof(Element));

           TextReader reader = new StreamReader(Path);

           FFolders = (Element)xmls.Deserialize(reader);

           reader.Close();

       }

       public Element Find(string Path)

       {

           return Search(FFolders, Path.Split('\\'), 0);

       }

       

       static Element Search(Element E, string[] P, int i)

       {

           if (P.Length == i)

           {

               return E;

           }

           if (E.Type == "dir")

               for (int j = 0; j < E.Sub.Count; j++)

                   if (E.Sub[j].Name == P[i])

                   {

                       E = Search(E.Sub[j], P, ++i);

                       break;

                   }

           return E;

       }

       static uint GetFileSize(string Path)

       {

           return (uint)new FileInfo(Path).Length;

       }

       static string GetName(string S)

       {

           S = S.Replace('/', '\\');

           if (S[S.Length - 1] == '\\')

               S = S.Remove(S.Length - 1, 1);

           string[] aTmp = S.Split('\\');

           return aTmp[aTmp.Length - 1];

       }

       static Element ScanFolderRec(string Path)

       {

           Element folder = new Element();

           folder.Sub = new List<Element>();

           string[] astr = new string[0];

           try

           {

               astr = Directory.GetDirectories(Path);

           }

           catch { }

           for (int i = 0; i < astr.Length; i++)

               folder.Sub.Add(ScanFolderRec(astr[i]));

           Element file = new Element();

           file.Sub = new List<Element>();

           try

           {

               astr = Directory.GetFiles(Path);

           }

           catch { }

           for (int i = 0; i < astr.Length; i++)

           {

               file.Name = GetName(astr[i]);

               file.Type = "file";

               file.CreateTime = File.GetCreationTime(astr[i]);

               file.ChangeTime = File.GetLastWriteTime(astr[i]);

               file.Size = GetFileSize(astr[i]);

               file.Attr = new fsAttribute(astr[i]);

               folder.Sub.Add(file);

           }

           folder.Name = GetName(Path);

           folder.Type = "dir";

           try

           {

               folder.CreateTime = Directory.GetCreationTime(Path);

               folder.Attr = new fsAttribute(Path);

           }

           catch { }

           return folder;

       }        

   }

}

Листинг модуля FMain.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.IO;

using Lenny.FolderStruct;

using Microsoft.Win32;

using System.Diagnostics;

namespace cdb

{

   public partial class FMain : Form

   {

       Config CFG = new Config();

       string[] LastPath = new string[2];

       string SearchString = "";

       bool isAdding = false;

       bool isCopy = false;

       bool Cancel = false;

       public List<string> Category = new List<string>();

       FolderStruct FS = new FolderStruct();

       FMaster MasterForm = new FMaster();

       FProperties PropertiesForm = new FProperties();

       void CFGSave()

       {

           CFG.Settings.view_ShowGrid = Menu_Вид_ПоказыватСетку.Checked;

           CFG.Settings.view_FullRowSelect = Menu_Вид_ВыделятьСтроку.Checked;

           CFG.Settings.view_ShowHidden = Menu_Вид_Системные.Checked;

           CFG.Settings.view_ShowSystem = Menu_Вид_Скрытые.Checked;

           CFG.Settings.search_ShowGroups = Menu_Поиск_Группы.Checked;

           CFG.Settings.search_Refresh = Menu_Поиск_Обновлять.Checked;

           CFG.Settings.search_AbsName = Menu_Поиск_ПлнСовпадение.Checked;

           CFG.Settings.search_AdventSearch = Menu_Поиск_СтрогийПоиск.Checked;

           CFG.Settings.form_WndState = WindowState;

           CFG.Settings.form_SplitPos = splitContainer1.SplitterDistance;

           CFG.Save();

       }

       void CFGLoad()

       {

           CFG.Load();

           Menu_Вид_ПоказыватСетку.Checked = CFG.Settings.view_ShowGrid;

           listView.GridLines = CFG.Settings.view_ShowGrid;

           Menu_Вид_ВыделятьСтроку.Checked = CFG.Settings.view_FullRowSelect;

           Menu_Вид_Системные.Checked = CFG.Settings.view_ShowHidden;

           Menu_Вид_Скрытые.Checked = CFG.Settings.view_ShowSystem;

           Menu_Поиск_Группы.Checked = CFG.Settings.search_ShowGroups;

           Menu_Поиск_Обновлять.Checked = CFG.Settings.search_Refresh;

           Menu_Поиск_ПлнСовпадение.Checked = CFG.Settings.search_AbsName;

           Menu_Поиск_СтрогийПоиск.Checked = CFG.Settings.search_AdventSearch;

           WindowState = CFG.Settings.form_WndState;

           splitContainer1.SplitterDistance = CFG.Settings.form_SplitPos;

       }

       void ExportTXT(string FileName)

       {

           StreamWriter sw = new StreamWriter(FileName, false, Encoding.Default);

           sw.WriteLine(String.Join("\\", LastPath, 1, LastPath.Length - 1));

           for (int i = 0; i < listView.Items.Count; i++)

               sw.WriteLine(listView.Items[i].Text);

           sw.Close();

       }

       void ExportCSV(string FileName)

       {

           StreamWriter sw = new StreamWriter(FileName, false, Encoding.Default);

           for (int i = 0; i < listView.Items.Count; i++)

               sw.WriteLine(String.Format("{0};{1};{2}", listView.Items[i].Text,

                   listView.Items[i].SubItems[1].Text, listView.Items[i].SubItems[2].Text));

           sw.Close();

       }

       void ExportHTML(string FileName)

       {

           StreamWriter sw = new StreamWriter(FileName, false, Encoding.Default);

           sw.WriteLine("<html><head>");

           sw.WriteLine("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1251\">");

           sw.WriteLine("<title>Dark Catalog</title></head><body>");

           sw.WriteLine("<font face=Verdana Size=2>");

           sw.WriteLine("Каталог: " + String.Join("\\", LastPath, 1, LastPath.Length - 1));

           sw.WriteLine("<hr color=black size=1><table border=0 cellspacing=1 width=100% bgcolor=Gray>");

           for (int i = 0; i < listView.Items.Count; i++)

           {

               sw.WriteLine("<tr><td style=\"background-color: White\"><font face=Verdana size=2>");

               sw.WriteLine(listView.Items[i].Text);

               sw.WriteLine("</font></td><td align=right style=\"background-color: White\"><font face=Verdana size=2>");

               sw.WriteLine(listView.Items[i].SubItems[1].Text);

               sw.WriteLine("</font></td><td align=right style=\"background-color: White\"><font face=Verdana size=2>");

               sw.WriteLine(listView.Items[i].SubItems[2].Text + "</font></td></tr>");

           }

           sw.WriteLine("</table></font></body></html>");

           sw.Close();

       }

       void CategoryListSave()

       {

           StreamWriter sw = new StreamWriter("db" + '\\' + "category.txt", false, Encoding.Default);

           sw.Write(String.Join("\r\n", Category.ToArray()));

           sw.Close();

       }

       void CategoryListLoad()

       {

           StreamReader sr = new StreamReader("db" + '\\' + "category.txt", Encoding.Default);

           string[] cats = sr.ReadToEnd().Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);

           sr.Close();

           Category.AddRange(cats);

       }

       void CategoryListMenu()

       {

           MenuItem_Категории.DropDownItems.Clear();

           MenuItem_Категории.DropDownItems.Add(new ToolStripMenuItem("Обновить список", Properties.Resources.refresh, обновитьСписок_Click));

           MenuItem_Категории.DropDownItems.Add(new ToolStripMenuItem("Показать всё", null, показатьВсё_Click));

           MenuItem_Категории.DropDownItems.Add(new ToolStripSeparator());

           for (int i = 0; i < Category.Count; i++)

           {

               ToolStripMenuItem tsmi = new ToolStripMenuItem(Category[i]);

               tsmi.Checked = true;

               tsmi.CheckOnClick = true;

               MenuItem_Категории.DropDownItems.Add(tsmi);

           }

       }

       void TreeAddNode(ref TreeNode treeNode, Element element, string FileName)

       {

           TreeNode treeNodeTmp;

           if (FileName.Length != 0)

               treeNodeTmp = treeNode.Nodes.Add(FileName);

           else

               treeNodeTmp = treeNode.Nodes.Add(element.Name);

           foreach (Element e in element.Sub)

               if (e.Type == "dir")

                   TreeAddNode(ref treeNodeTmp, e, "");

       }

       void TreeCreate(ref TreeNode Node, string Category)

       {

           string[] img = Directory.GetFiles("db" + '\\' + Category, "*.xml");

           FolderStruct FS = new FolderStruct();

           for (int j = 0; j < img.Length; j++)

           {

               if (Cancel)

                   break;

               FS.XmlDeserialization(img[j]);

               TreeAddNode(ref Node, FS.Folders, Path.GetFileNameWithoutExtension(img[j]));

               Application.DoEvents();

           }

       }

       void TreeLoad(string Category)

       {

           StatusLabel.Text = "Загрузка списка: " + Category;

           Refresh();

           TreeNode tn = treeView.Nodes.Add(Category);

           TreeCreate(ref tn, Category);

           StatusLabel.Text = "";

       }

       void TreeRefresh()

       {

           Menu_Отменить.Visible = true;

           Cancel = false;

           treeView.Nodes.Clear();

           SearchString = "";

           listView.ShowGroups = false;

           listView.Items.Clear();

           for (int i = 0; i < Category.Count; i++)

           {

               if (Cancel)

                   break;

               ToolStripMenuItem tsmi = (ToolStripMenuItem)MenuItem_Категории.DropDownItems[i + 3];

               if (tsmi.Checked)

                   TreeLoad(Category[i]);

           }

           Menu_Отменить.Visible = false;

       }

       void TreeSearchDisk(string Path)

       {

           Menu_Отменить.Visible = true;

           Cancel = false;

           StatusLabel.Text = "Поиск: сканирование диска";

           Refresh();

           FolderStruct fs1 = new FolderStruct(Path, FolderStructCreateMode.Scan);

           foreach (TreeNode treeNode1 in treeView.Nodes)

               foreach (TreeNode treeNode2 in treeNode1.Nodes)

               {

                   Application.DoEvents();

                   if (Cancel)

                       break;

                   StatusLabel.Text = "Поиск: " + treeNode2.Text;

                   Refresh();

                   FolderStruct fs2 = new FolderStruct("db" + '\\' + treeNode2.FullPath + ".xml",

                       FolderStructCreateMode.XmlDeserialization);

                   if (fs1.Folders == fs2.Folders)

                   {

                       treeNode2.ForeColor = Color.Blue;

                       if (MessageBox.Show(String.Format("Для диска \"{0}\" найден образ \"{1}\"\nПродолжать поиск?",

                           fs1.Folders.Name, treeNode2.Text), "Поиск", MessageBoxButtons.YesNo,

                           MessageBoxIcon.Question) == DialogResult.No)

                       {

                           StatusLabel.Text = "";

                           Menu_Отменить.Visible = false;

                           treeView.SelectedNode = treeNode2;

                           return;

                       }

                   }

               }

           Menu_Отменить.Visible = false;

           StatusLabel.Text = "Поиск завершён";

       }

       void TreeSearchStart()

       {

           Menu_Отменить.Visible = true;

           Cancel = false;

           if (Menu_Поиск_Обновлять.Checked)

               TreeRefresh();

           SearchString = textBox1.Text.ToUpper();

           foreach (TreeNode treeNode in treeView.Nodes)

           {

               StatusLabel.Text = "Поиск: " + treeNode.Text;

               Refresh();

               TreeSearch(treeNode, true);

               if (Cancel)

                   break;

           }

           StatusLabel.Text = "Поиск завершён";

           LastPath = new string[2];

           Menu_Отменить.Visible = false;

       }

       bool TreeSearchFile(TreeNode Node)

       {

           if (Node.Level < 1)

               return false;

           if (Node.Level == 1)

               FS.XmlDeserialization("db" + '\\' + Node.FullPath + ".xml");

           string[] aPath = Node.FullPath.Split('\\');

           Element E = FS.Find(String.Join("\\", aPath, 2, aPath.Length - 2));

           foreach (Element e in E.Sub)

               if (TreeSearchEquals(e.Name))

               {

                   Node.ForeColor = Color.Green;

                   return false;

               }

           return true;

       }

       bool TreeSearch(TreeNode Node, bool isDelete)

       {

           Application.DoEvents();

           if (Cancel)

               return false;

           if (Node.Level == 1)

               FS.XmlDeserialization("db" + '\\' + Node.FullPath + ".xml");

           for (int i = 0; i < Node.Nodes.Count; i++)

           {

               if (TreeSearchEquals(Node.Nodes[i].Text))

                   isDelete = false;

               if (Node.Nodes[i].Nodes.Count != 0)

               {

                   if (TreeSearch(Node.Nodes[i], isDelete))

                       if (isDelete || Menu_Поиск_СтрогийПоиск.Checked)

                           Node.Nodes[i--].Remove();

               }

               else

               {

                   if (TreeSearchFile(Node.Nodes[i]))

                       if (isDelete || Menu_Поиск_СтрогийПоиск.Checked)

                           Node.Nodes[i--].Remove();

               }

           }

           if (TreeSearchEquals(Node.Text))

           {

               Node.ForeColor = Color.Blue;

               return false;

           }

           if (TreeSearchFile(Node) && Node.Nodes.Count == 0)

               return true;

           return false;

       }

       bool TreeSearchEquals(string SearchIn)

       {

           int i = SearchIn.ToUpper().IndexOf(SearchString);

           if (i >= 0)

           {

               if (Menu_Поиск_ПлнСовпадение.Checked)

                   if (i == 0 && SearchString.Length == SearchIn.Length)

                       return true;

                   else

                       return false;

               return true;

           }

           return false;

       }

       void GetList(string Path)

       {

           string[] p = Path.Split('\\');

           string xmlpath = String.Join("\\", p, 2, p.Length - 2);

           if ((p[0] != LastPath[0]) || (p[1] != LastPath[1]))

           {

               FS = new FolderStruct(String.Format("db\\{0}\\{1}.xml", p[0], p[1]),

                   FolderStructCreateMode.XmlDeserialization);

           }

           Element E = FS.Find(xmlpath);

           listView.Items.Clear();

           for (int i = 0; i < E.Sub.Count; i++)

           {

               if (E.Sub[i].Attr.AttrHidden && !Menu_Вид_Скрытые.Checked)

                   continue;

               if (E.Sub[i].Attr.AttrSystem && !Menu_Вид_Системные.Checked)

                   continue;

               ListViewItem lvi = new ListViewItem(E.Sub[i].Name);

               if (E.Sub[i].Type == "dir")

               {

                   lvi.SubItems.Add("");

                   lvi.ImageIndex = 1;

               }

               else

               {

                   lvi.SubItems.Add(StringFunc.FormatSize(E.Sub[i].Size));

                   lvi.ImageIndex = 2;

                   if (System.IO.Path.GetExtension(E.Sub[i].Name).ToUpper() == ".EXE")

                       lvi.ImageIndex = 0;

               }

               lvi.SubItems.Add(E.Sub[i].CreateTime.ToLongDateString() + ' ' + E.Sub[i].CreateTime.ToLongTimeString());

               if (SearchString.Length != 0)

               {

                   if (Menu_Поиск_Группы.Checked)

                   {

                       listView.ShowGroups = true;

                       if (TreeSearchEquals(lvi.Text))

                           lvi.Group = listView.Groups[0];

                       else

                           lvi.Group = listView.Groups[1];

                   }

                   else

                   {

                       if (TreeSearchEquals(lvi.Text))

                           lvi.ForeColor = Color.Blue;

                   }

               }

               listView.Items.Add(lvi);

           }

           LastPath = Path.Split('\\');

       }

       public static string GetFileTypeByExt(string Ext)

       {

           string ClassName = (string)Registry.GetValue("HKEY_CLASSES_ROOT\\" + Ext, "", "");

           if (ClassName == "")

               return "";

           return (string)Registry.GetValue("HKEY_CLASSES_ROOT\\" + ClassName, "", "");

       }

       Element GetListElement(string Name)

       {

           string xmlpath = "";

           for (int i = 0; i < LastPath.Length - 2; i++)

               xmlpath += LastPath[i + 2] + '\\';

           xmlpath += Name;

           return FS.Find(xmlpath);

       }

       public FMain()

       {

           InitializeComponent();

           CFGLoad();

           CategoryListLoad();

           CategoryListMenu();

       }

       private void Menu11_Click(object sender, EventArgs e)

       {

           MasterForm = new FMaster();

           MasterForm.ShowDialog();

       }

       private void Menu21_Click(object sender, EventArgs e)

       {

       }

       private void treeView_AfterSelect(object sender, TreeViewEventArgs e)

       {

           if (treeView.SelectedNode.Level > 0)

               GetList(treeView.SelectedNode.FullPath);

           switch (treeView.SelectedNode.Level)

           {

               case 0:

                   listView.Items.Clear();

                   treeView.ContextMenuStrip = contextMenuStrip1;

                   break;

               case 1:

                   treeView.ContextMenuStrip = contextMenuStrip3;

                   break;

               default:

                   treeView.ContextMenuStrip = contextMenuStrip2;

                   break;

           }

           StatusLabel.Text = treeView.SelectedNode.FullPath;

       }

       private void listView_DoubleClick(object sender, EventArgs e)

       {

           if (listView.SelectedIndices.Count == 0 || treeView.SelectedNode == null)

               return;

           Element E = GetListElement(listView.Items[listView.SelectedIndices[0]].Text);

           if (E.Type == "dir")

           {

               foreach (TreeNode tn in treeView.SelectedNode.Nodes)

                   if (E.Name == tn.Text)

                   {

                       treeView.SelectedNode = tn;

                       break;

                   }

               GetList(String.Join("\\", LastPath));

           }

           else

           {

               DriveInfo[] driveInfo = DriveInfo.GetDrives();

               List<string> Files = new List<string>();

               ContextMenuStrip cms = new ContextMenuStrip();

               for (int i = 0; i < driveInfo.Length; i++)

               {

                   if (driveInfo[i].Name == "A:\\")

                       continue;

                   string fname = driveInfo[i].Name +

                       String.Join("\\", LastPath, 2, LastPath.Length - 2) + '\\' + listView.SelectedItems[0].Text;

                   if (File.Exists(fname))

                   {

                       ToolStripMenuItem tsmi = new ToolStripMenuItem();

                       tsmi.Tag = fname;

                       string path = Path.GetDirectoryName(fname);

                       if (path.Length > 40)

                       {

                           fname = path.Substring(0, 3) + "...\\" + Path.GetFileName(fname);

                       }

                       tsmi.Text = fname;

                       tsmi.Click += Menu_ЗапуститьФайл_Click;

                       cms.Items.Add(tsmi);

                   }

               }

               cms.Show(Cursor.Position);

           }

       }

       private void обновитьСписок_Click(object sender, EventArgs e)

       {

           TreeRefresh();

       }

       private void показатьВсё_Click(object sender, EventArgs e)

       {

           for (int i = 3; i < MenuItem_Категории.DropDownItems.Count; i++)

               ((ToolStripMenuItem)MenuItem_Категории.DropDownItems[i]).Checked = true;

           TreeRefresh();

       }

       private void переименоватьКатегориюToolStripMenuItem_Click(object sender, EventArgs e)

       {

           if (treeView.SelectedNode != null)

           {

               treeView.LabelEdit = true;

               treeView.SelectedNode.BeginEdit();

           }

       }

       private void treeView_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)

       {

           if (isAdding)

           {

               isAdding = false;

               if (e.Label == null || e.Label.Length == 0)

               {

                   treeView.SelectedNode.Remove();

                   return;

               }

               if (!StringFunc.CheckValidPath(e.Label))

               {

                   MessageBox.Show("Имя категории содержит недопустимые символы.", "Ошибка",

                       MessageBoxButtons.OK, MessageBoxIcon.Error);

                   treeView.SelectedNode.BeginEdit();

                   return;

               }

               if (Directory.Exists("db" + '\\' + e.Label))

               {

                   MessageBox.Show("Категория с таким именем уже есть.\nВведите другое имя.", "Ошибка",

                       MessageBoxButtons.OK, MessageBoxIcon.Error);

                   treeView.SelectedNode.BeginEdit();

                   return;

               }

               Directory.CreateDirectory("db" + '\\' + e.Label);

               Category.Insert(treeView.SelectedNode.Index, e.Label);

               CategoryListSave();

               CategoryListMenu();

               treeView.LabelEdit = false;

               return;

           }

           if (e.Label == null)

               return;

           if (treeView.SelectedNode.Level == 0)

           {

               if (!StringFunc.CheckValidPath(e.Label))

               {

                   MessageBox.Show("Имя категории содержит недопустимые символы.", "Ошибка",

                       MessageBoxButtons.OK, MessageBoxIcon.Error);

                   e.CancelEdit = true;

                   treeView.SelectedNode.BeginEdit();

                   return;

               }

               if (Directory.Exists("db" + '\\' + e.Label))

               {

                   MessageBox.Show("Категория с таким именем уже есть.\nВведите другое имя.", "Ошибка",

                       MessageBoxButtons.OK, MessageBoxIcon.Error);

                   e.CancelEdit = true;

                   treeView.SelectedNode.BeginEdit();

                   return;

               }

               string name = treeView.SelectedNode.Text;

               Directory.Move("db" + '\\' + name, "db" + '\\' + e.Label);

               Category[Category.IndexOf(name)] = e.Label;

               CategoryListSave();

               CategoryListMenu();

           }

           if (treeView.SelectedNode.Level == 1)

           {

               if (!StringFunc.CheckValidPath(e.Label))

               {

                   MessageBox.Show("Имя образа содержит недопустимые символы.", "Ошибка",

                       MessageBoxButtons.OK, MessageBoxIcon.Error);

                   e.CancelEdit = true;

                   treeView.SelectedNode.BeginEdit();

                   return;

               }

               if (File.Exists("db" + '\\' + treeView.SelectedNode.Parent.Text + '\\' + e.Label + ".xml"))

               {

                   MessageBox.Show("Образ с таким именем уже есть.\nВведите другое имя.", "Ошибка",

                       MessageBoxButtons.OK, MessageBoxIcon.Error);

                   e.CancelEdit = true;

                   treeView.SelectedNode.BeginEdit();

                   return;

               }

               File.Move("db" + '\\' + treeView.SelectedNode.Parent.Text + '\\' +

                   treeView.SelectedNode.Text + ".xml", "db" + '\\' + treeView.SelectedNode.Parent.Text + '\\' +

                   e.Label + ".xml");

           }

           treeView.LabelEdit = false;

       }

       private void создатьКатегориюToolStripMenuItem_Click(object sender, EventArgs e)

       {

           treeView.LabelEdit = true;

           isAdding = true;

           int index = 0;

           if (treeView.SelectedNode != null)

               index = treeView.SelectedNode.Index;

           treeView.SelectedNode = treeView.Nodes.Insert(index, "");

           treeView.SelectedNode.BeginEdit();

       }

       private void удалитьToolStripMenuItem_Click(object sender, EventArgs e)

       {

           if (treeView.SelectedNode != null)

               if (treeView.SelectedNode.GetNodeCount(false) == 0)

               {

                   Category.RemoveAt(Category.IndexOf(treeView.SelectedNode.Text));

                   CategoryListSave();

                   CategoryListMenu();

                   Directory.Delete("db" + '\\' + treeView.SelectedNode.Text);

                   treeView.SelectedNode.Remove();

               }

               else

               {

                   MessageBox.Show("Удалить можно только пустую категорию.", "Удаление",

                       MessageBoxButtons.OK, MessageBoxIcon.Warning);

               }

       }

       private void сдвинутьВверхToolStripMenuItem_Click(object sender, EventArgs e)

       {

           if (treeView.SelectedNode.Index == 0)

               return;

           TreeNode nt = treeView.SelectedNode;

           int i = treeView.SelectedNode.Index;

           treeView.Nodes.RemoveAt(i);

           treeView.Nodes.Insert(i - 1, nt);

           treeView.SelectedNode = nt;

           i = Category.IndexOf(nt.Text);

           string s = Category[i];

           Category.RemoveAt(i);

           Category.Insert(i - 1, s);

           CategoryListSave();

           CategoryListMenu();

       }

       private void сдвинутьВнизToolStripMenuItem_Click(object sender, EventArgs e)

       {

           if (treeView.SelectedNode.Index == treeView.Nodes.Count - 1)

               return;

           TreeNode nt = treeView.SelectedNode;

           int i = treeView.SelectedNode.Index;

           treeView.Nodes.RemoveAt(i);

           treeView.Nodes.Insert(i + 1, nt);

           treeView.SelectedNode = nt;

           i = Category.IndexOf(nt.Text);

           string s = Category[i];

           Category.RemoveAt(i);

           Category.Insert(i + 1, s);

           CategoryListSave();

           CategoryListMenu();

       }

       private void textBox1_Enter(object sender, EventArgs e)

       {

           if (textBox1.Text == "<поиск>")

           {

               textBox1.Text = "";

               textBox1.ForeColor = Color.Black;

           }

           AcceptButton = button3;

       }

       private void textBox1_Leave(object sender, EventArgs e)

       {

           if (textBox1.Text == "")

           {

               textBox1.Text = "<поиск>";

               textBox1.ForeColor = Color.Gray;

           }

       }

       private void button2_Click(object sender, EventArgs e)

       {

           PropertiesForm.ShowDialog(GetListElement(""), LastPath);

       }

       private void Menu14_Click(object sender, EventArgs e)

       {

           Close();

       }

       private void button3_Click(object sender, EventArgs e)

       {

           TreeSearchStart();

       }

       private void показыватьСеткуToolStripMenuItem_Click(object sender, EventArgs e)

       {

           listView.GridLines = Menu_Вид_ПоказыватСетку.Checked;

       }

       private void выделятьВсюСтрокуToolStripMenuItem_Click(object sender, EventArgs e)

       {

           listView.FullRowSelect = Menu_Вид_ВыделятьСтроку.Checked;

       }

       private void toolStripMenuItem1_Click(object sender, EventArgs e)

       {

           treeView.ExpandAll();

       }

       private void свернутьДеревоToolStripMenuItem_Click(object sender, EventArgs e)

       {

           treeView.CollapseAll();

       }

       private void listView1_SelectedIndexChanged(object sender, EventArgs e)

       {

           if (listView.SelectedIndices.Count == 0)

               return;

           if (treeView.SelectedNode != null)

               StatusLabel.Text = treeView.SelectedNode.FullPath + '\\' + listView.SelectedItems[0].Text;

       }

       private void переименоватьToolStripMenuItem_Click(object sender, EventArgs e)

       {

           treeView.LabelEdit = true;

           treeView.SelectedNode.BeginEdit();

       }

       private void удалитьToolStripMenuItem1_Click(object sender, EventArgs e)

       {

           if (MessageBox.Show("Вы уверены что хотите удалить образ?\nЭту операцию нельзя отменить.",

               "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)

           {

               File.Delete("db" + '\\' + treeView.SelectedNode.FullPath + ".xml");

               treeView.SelectedNode.Remove();

           }

       }

       private void свойстваToolStripMenuItem1_Click(object sender, EventArgs e)

       {

           PropertiesForm.ShowDialog(GetListElement(""), treeView.SelectedNode.FullPath.Split('\\'));

       }

       private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)

       {

           if (e.Button == MouseButtons.Right)

               treeView.SelectedNode = e.Node;

       }

       private TreeNode[] FindInTree(string Str)

       {

           TreeNode[] atn = new TreeNode[0];

           foreach (TreeNode tn in treeView.Nodes)

               if (tn.Text == Str)

               {

                   Array.Resize(ref atn, atn.Length + 1);

                   atn[atn.Length - 1] = tn;

               }

           return atn;

       }

       private void MenuItem_MoveTo_DropDownOpening(object sender, EventArgs e)

       {

           if (((ToolStripMenuItem)sender).Name == "MenuItem_MoveTo")

               isCopy = false;

           else

               isCopy = true;

           ((ToolStripMenuItem)sender).DropDownItems.Clear();

           string s = treeView.SelectedNode.FullPath.Split('\\')[0];

           foreach (string str in Category)

               if (str != s)

                   if (FindInTree(str).Length != 0)

                       ((ToolStripMenuItem)sender).DropDownItems.Add(str, null, MenuItem_MoveCopy_Click);

                   else

                   {

                       ToolStripItem tsi = ((ToolStripMenuItem)sender).DropDownItems.Add(str, null, null);

                       tsi.Enabled = false;

                   }

       }

       private void MenuItem_MoveCopy_Click(object sender, EventArgs e)

       {

           string s1 = treeView.SelectedNode.FullPath.Split('\\')[0];

           string s2 = ((ToolStripMenuItem)sender).Text;

           if (File.Exists(String.Format("{0}\\{1}\\{2}.xml", "db", s2, treeView.SelectedNode.Text)))

           {

               MessageBox.Show("Образ с таким именем уже есть в категории.", "Ошибка",

                       MessageBoxButtons.OK, MessageBoxIcon.Error);

               return;

           }

           TreeNode treeNode = (TreeNode)treeView.SelectedNode.Clone();

           FindInTree(s2)[0].Nodes.Add(treeNode);

           if (isCopy)

           {

               File.Copy(String.Format("{0}\\{1}\\{2}.xml", "db", s1, treeView.SelectedNode.Text),

                   String.Format("{0}\\{1}\\{2}.xml", "db", s2, treeView.SelectedNode.Text));

           }

           else

           {

               File.Move(String.Format("{0}\\{1}\\{2}.xml", "db", s1, treeView.SelectedNode.Text),

                   String.Format("{0}\\{1}\\{2}.xml", "db", s2, treeView.SelectedNode.Text));

               treeView.SelectedNode.Remove();

           }

           treeView.SelectedNode = treeNode;

       }

       private void MenuItem_Экспорт2_Click(object sender, EventArgs e)

       {

           saveDialog.Filter = "Текстовые файлы (*.txt)|*.txt";

           if (saveDialog.ShowDialog() != DialogResult.Cancel)

               ExportTXT(saveDialog.FileName);

       }

       private void MenuItem_СвойстваФайла_Click(object sender, EventArgs e)

       {

           if (listView.SelectedIndices.Count == 0)

               return;

           PropertiesForm.ShowDialog(GetListElement(listView.SelectedItems[0].Text), LastPath);

       }

       private void MenuItem_Программа_Перезапустить_Click(object sender, EventArgs e)

       {

           Application.Restart();

       }

       private void MenuItem_Программа_НайтиДиск_Click(object sender, EventArgs e)

       {

           if (browserDialog.ShowDialog() == DialogResult.Cancel)

               return;

           TreeSearchDisk(browserDialog.SelectedPath);

       }

       private void FMain_Shown(object sender, EventArgs e)

       {

           TreeRefresh();

       }

       private void MenuItem_ОПрограмме_Click(object sender, EventArgs e)

       {

           new FAbout().ShowDialog();

       }

       private void MenuItem_Программа_НайтиДиск_DropDownOpening(object sender, EventArgs e)

       {

           Menu_Программа_НайтиДиск.DropDownItems.Clear();

           DriveInfo[] di = DriveInfo.GetDrives();

           for (int i = 0; i < di.Length; i++)

           {

               if (di[i].DriveType == DriveType.CDRom)

               {

                   ToolStripMenuItem tsmi = new ToolStripMenuItem(di[i].Name);

                   tsmi.Tag = di[i].Name;

                   if (di[i].IsReady)

                   {

                       tsmi.Click += MenuItem_Программа_НайтиДискSub_Click;

                       tsmi.Text = di[i].VolumeLabel + " (" + di[i].Name.Remove(2, 1) + ")";

                   }

                   else

                       tsmi.Enabled = false;

                   Menu_Программа_НайтиДиск.DropDownItems.Add(tsmi);

               }

           }

           Menu_Программа_НайтиДиск.DropDownItems.Add(new ToolStripSeparator());

           Menu_Программа_НайтиДиск.DropDownItems.Add(

               new ToolStripMenuItem("Обзор...", null, MenuItem_Программа_НайтиДиск_Click));

       }

       private void MenuItem_Программа_НайтиДискSub_Click(object sender, EventArgs e)

       {

           TreeSearchDisk((string)((ToolStripMenuItem)sender).Tag);

       }

       private void Menu_ОтменитьОперацию_Click(object sender, EventArgs e)

       {

           Cancel = true;

           Menu_Отменить.Visible = false;

       }

       private void Menu_ЗапуститьФайл_Click(object sender, EventArgs e)

       {

           string FileName = (string)((ToolStripMenuItem)sender).Tag;

           if (File.Exists(FileName))

               Process.Start(new ProcessStartInfo(FileName));

           else

               MessageBox.Show("Не удалось найти файл.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);

       }

       private void FMain_FormClosing(object sender, FormClosingEventArgs e)

       {

           CFGSave();

       }

       private void Menu_Экспорт_CSV_Click(object sender, EventArgs e)

       {

           saveDialog.Filter = "Текстовые файлы с разделителем (*.csv)|*.csv";

           if (saveDialog.ShowDialog() != DialogResult.Cancel)

               ExportCSV(saveDialog.FileName);

       }

       private void Menu_Экспорт_HTML_Click(object sender, EventArgs e)

       {

           saveDialog.Filter = "HTML файлы (*.html)|*.html";

           if (saveDialog.ShowDialog() != DialogResult.Cancel)

               ExportHTML(saveDialog.FileName);

       }

       private void MenuItem_MoveTo_Click(object sender, EventArgs e)

       {

       }

       private void treeView_MouseClick(object sender, MouseEventArgs e)

       {

           if (e.Button == MouseButtons.Right)

               if (treeView.Nodes.Count == 0)

                   treeView.ContextMenuStrip = contextMenuStrip1;

       }

       private void contextMenuStrip3_Opening(object sender, CancelEventArgs e)

       {

           if (treeView.SelectedNode == null)

           {

               e.Cancel = true;

               contextMenuStrip1.Show(Cursor.Position);

           }

       }

       private void историяВерсийToolStripMenuItem_Click(object sender, EventArgs e)

       {

           if (File.Exists("history.txt"))

               Process.Start("history.txt");

           else

               MessageBox.Show("Файл справки не найден.\nДля решения проблемы переустановите программу.",

                   "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);

       }

       private void справкаToolStripMenuItem_Click(object sender, EventArgs e)

       {

           if (File.Exists("help.chm"))

               Process.Start("help.chm");

           else

               MessageBox.Show("Файл справки не найден.\nДля решения проблемы переустановите программу.",

                   "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);

       }

   }

}

Листинг модуля SubFunc.cs

using System;

using System.Collections.Generic;

using System.Text;

using System.Windows.Forms;

using System.IO;

using System.Drawing;

using System.Xml.Serialization;

namespace cdb

{

   class StringFunc

   {

       public static string FormatSize(uint Size)

       {

           double fSize = Size;

           string S = "байт";

           if (fSize >= 1024)

           {

               fSize /= 1024;

               S = "Кб";

           }

           if (fSize >= 1024)

           {

               fSize /= 1024;

               S = "Мб";

           }

           if (fSize >= 1024)

           {

               fSize /= 1024;

               S = "Гб";

           }

           return String.Format("{0:F} {1}", fSize, S);

       }

       public static string FormatSizeByte(uint Size)

       {

           string S = Size.ToString();

           for (int i = S.Length - 3; i > 0; i -= 3)

               S = S.Insert(i, " ");

           return S + " байт";

       }

       public static bool CheckValidPath(string Path)

       {

           char[] ic = System.IO.Path.GetInvalidFileNameChars();

           foreach (char c in ic)

               if (Path.IndexOf(c) != -1)

                   return false;

           return true;

       }

   }

   public class Settings

   {

       public bool search_Refresh = false;

       public bool search_ShowGroups = false;

       public bool search_AbsName = false;

       public bool search_AdventSearch = false;

       public bool view_ShowGrid = true;

       public bool view_FullRowSelect = false;

       public bool view_ShowHidden = false;

       public bool view_ShowSystem = false;

       public FormWindowState form_WndState = FormWindowState.Normal;

       public int form_SplitPos = 200;

   }

   class Config

   {

       public Settings Settings = new Settings();

       string FileName = "app.config";

       public void Load()

       {

           if (!File.Exists(FileName))

               return;

           XmlSerializer xmls = new XmlSerializer(typeof(Settings));

           TextReader reader = new StreamReader(FileName);

           Settings = (Settings)xmls.Deserialize(reader);

           reader.Close();

       }

       public void Save()

       {

           XmlSerializer xmls = new XmlSerializer(typeof(Settings));

           TextWriter writer = new StreamWriter(FileName);

           xmls.Serialize(writer, Settings);

           writer.Close();

       }

   }

}

Листинг модуля FMaster.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.IO;

using Lenny.FolderStruct;

namespace cdb

{

   public partial class FMaster : Form

   {

       FolderStruct FS;

       int State = 0;

       void Refrefh()

       {

           Directory.SetCurrentDirectory("db");

           StreamReader sr = new StreamReader("category.txt", Encoding.Default);

           string[] cats = sr.ReadToEnd().Split('\n');

           sr.Close();

           comboBox1.Items.Clear();

           for (int i = 0; i < cats.Length; i++)

           {

               cats[i] = cats[i].Trim();

               if (Directory.Exists(cats[i]))

                   comboBox1.Items.Add(cats[i]);

           }

           Directory.SetCurrentDirectory("..");

       }

       bool CheckName()

       {

           if (StringFunc.CheckValidPath(textBox2.Text))

               if (!File.Exists(String.Format("{0}\\{1}\\{2}.xml", "db", comboBox1.Text, textBox2.Text)))

               {

                   return true;

               }

               else

               {

                   MessageBox.Show("Файл с таким именем уже есть.", "Ошибка",

                       MessageBoxButtons.OK, MessageBoxIcon.Error);

               }

           else

           {

               MessageBox.Show("Использованы недопустимые символы.", "Ошибка",

                       MessageBoxButtons.OK, MessageBoxIcon.Error);

           }

           return false;

       }

       void State1()

       {

           if (!Directory.Exists(textBox1.Text))

           {

               MessageBox.Show("Указаная папка не существует.", "Ошибка",

                   MessageBoxButtons.OK, MessageBoxIcon.Error);

               return;

           }            

           panel1.Visible = false;

           panel2.Visible = true;            

           State++;

           button4.Enabled = false;

           button6.Enabled = false;

           State2();

       }

       void State2()

       {

           Refresh();

           FS = new FolderStruct(textBox1.Text, FolderStructCreateMode.Scan);

           textBox2.Text = FS.Folders.Name;

           panel2.Visible = false;

           panel3.Visible = true;

           button4.Enabled = true;

           button6.Enabled = true;

           State++;

       }

       void State3()

       {

           if (comboBox1.Text.Length == 0)

           {

               MessageBox.Show("Выберите категорию.", "Предупреждение",

                   MessageBoxButtons.OK, MessageBoxIcon.Warning);

               return;

           }

           panel3.Visible = false;

           panel4.Visible = true;

           State++;

       }

       void State4()

       {

           if (!StringFunc.CheckValidPath(textBox2.Text))

           {

               MessageBox.Show("В имени образа используются запрещённые символы.", "Ошибка",

                  MessageBoxButtons.OK, MessageBoxIcon.Error);

               return;

           }

           if (File.Exists(String.Format("{0}\\{1}\\{2}.xml", "db", comboBox1.Text, textBox2.Text)))

           {

               MessageBox.Show(String.Format("В категории \"{0}\" уже есть образ с именем \"{1}\".", comboBox1.Text, textBox2.Text) +

                   "\nЗадайте другое имя.", "Ошибка",MessageBoxButtons.OK, MessageBoxIcon.Error);

               return;

           }

           FS.XmlSerialization(String.Format("{0}\\{1}\\{2}.xml", "db", comboBox1.Text, textBox2.Text));

           panel4.Visible = false;

           panel5.Visible = true;

           button4.Enabled = false;

           State++;

       }

       public FMaster()

       {

           InitializeComponent();

           panel2.Location = panel1.Location;

           panel3.Location = panel1.Location;

           panel4.Location = panel1.Location;

           panel5.Location = panel1.Location;

       }

       private void FMaster_Load(object sender, EventArgs e)

       {

           Refrefh();

       }

       private void button1_Click(object sender, EventArgs e)

       {

           if (BrowserDialog.ShowDialog() == DialogResult.OK)

               textBox1.Text = BrowserDialog.SelectedPath;

       }        

       private void button4_Click(object sender, EventArgs e)

       {

           switch (State)

           {

               case 0:

                   State1();

                   break;

               case 2:

                   State3();

                   break;

               case 3:

                   State4();

                   break;

           }

       }

       private void button9_Click(object sender, EventArgs e)

       {

           panel1.Visible = true;

           panel2.Visible = false;

           panel3.Visible = false;

           panel4.Visible = false;

           panel5.Visible = false;

           button4.Enabled = true;

           textBox1.Text = "";

           State = 0;

           FS = new FolderStruct();

       }

       private void button6_Click(object sender, EventArgs e)

       {

           Close();

       }

   }

}


 

А также другие работы, которые могут Вас заинтересовать

84892. Hard Surface Tracking With the Rotterdam Holland Police 316.5 KB
  In September of this year I went back to the Police Dog Training Center in Rotterdam Holland with my friend Kevin Scheldahl. We went there with the expressed purpose of getting as much information as possible on hard surface tracking.
84893. Litter Tracking Imprinting 48.5 KB
  I leave them to their business and watch which ones seem most intense and which ones wander off. I especially note which ones stay the longest and which ones return hours later to search the same track. When this is the same puppy, I know I have a star.
84894. Расчёт показателей эксплуатационной надёжности эталонных конструкций верхнего строения пути 102.2 KB
  Расчёт показателей эксплуатационной надёжности эталонных конструкций верхнего строения пути Расчёт количества эталонных объектов пути Оценка показателей эксплуатационной надежности технического состояния элементов верхнего строения пути на различных участках зависит от видов и типов конструкций находящихся в различных условиях эксплуатации окружающей среды а также изза влияния других факторов. Расчет...
84895. Исследование характеристик машин переменного и постоянного тока в различных режимах работы: учебно-методическое пособие 1.48 MB
  Приведены методики и примеры расчета асинхронного двигателя с фазным и короткозамкнутым ротором в различных режимах работы, а также двигателя постоянного тока. Содержатся основные технические данные двигателей различных типов.
84899. Технология производства светлого пива 899.41 KB
  Актуальность темы работы заключается в том, что во всем мире пиво пользуется большим спросом у населения благодаря приятному вкусу, тонизирующему и жаждоутоляющему действию. Пиво, являясь слабоалкогольным напитком, во многих странах выступает соперником крепких алкогольных изделий.
84900. Тоннель, сооружаемый щитовым способом 379 KB
  Инженерно-геологические изыскания осуществляются с полнотой, которая достаточна для оценки условий строительства и разработки прогноза взаимодействия геологической среды и подземного сооружения.