Системна утиліта керування доступом до використовуваних файлів

Методика управління каталогами та атрибутами файлів. Аналіз вихідних даних, вибір підходу та технології реалізації програмного продукту. Розробка узагальненого та деталізованих алгоритмів роботи програми, інтеграція компонентів та комплексне тестування.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык украинский
Дата добавления 23.01.2012
Размер файла 2,8 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

Размещено на http://www.allbest.ru/

Системна утиліта керування доступом до використовуваних файлів

ЗМІСТ

ВСТУП

РОЗДІЛ 1. Методика управління каталогами та атрибутами файлів

1.1 Засоби WinAPI

1.2 Засоби DOS

1.3 Засоби візуалізації С#

РОЗДІЛ 2. Формування запиту до компонентів операційної системи з метою отримання інформації про створені та використовувані нею файли

2.1 Дизайн головної форми

2.2 Реалізація методів відображення інформації про директорії та файли

2.3 Основні події

РОЗДІЛ 3. Зміна атрибутів доступу до файлів за вибором користувача

3.1 Дизайн та події діалогового вікна зміни атрибутів

3.2 Результати тестування

РОЗДІЛ 4. Практичне використання програми

4.1 Засоби попередження помилок користувача та аварійних виходів

4.2 Підготовка установочного пакету

4.3 Установка утілити користувачем

ВИСНОВКИ

СПИСОК ВИКОРИСТАНОЇ ЛІТЕРАТУРИ

ДОДАТКИ

ВСТУП

Робота з файлами - звичайна і найбільш необхідна функція будь-якої файлової системи. Управління доступом до використовуваних файлів - досить поширена задача, для вирішення якої доцільно створити окрему утиліту.

Метою даної роботи є розробка системної утиліти керування доступом до використовуваних файлів, що надає засоби організації роботи з ними в багатозадачних операційних системах сімейства Microsoft Windows.

У відповідності із поставленою метою, в роботі вирішуються наступні завдання:

дослідження предметної області, методів та засобів створення програмного продукту;

аналіз вихідних даних, вибір підходу, технології реалізації розроблюваного програмного продукту;

розробка структури програмного продукту, що полягає у визначенні набору необхідних програмних компонентів, апаратного забезпечення та способів взаємодії з зовнішнім прикладним програмним забезпеченням;

розробка узагальненого та деталізованих алгоритмів роботи програми;

проектування компонентів програми, їх реалізація та автономне тестування;

інтеграція компонентів програми в єдиний продукт. Комплексне тестування.

РОЗДІЛ 1. Методика управління каталогами та атрибутами файлів

1.1 Засоби WinAPI

Створення або видалення каталогу виконується двома простими функціями.

BOOL CreateDirectory (

LPCTSTR lpszPath,

LPSECURITY_ATTRIBUTES lpsa)

BOOL RemoveDirectory (LPCTSTR lpszPath)

lpszPath - указує на рядок із завершальним нулем, що містить ім'я каталогу, що повинен бути створений або вилучений. Другий параметр (атрибути безпеки) дорівнює NULL. Видалити можна тільки порожній каталог.

Кожний процес має поточний, або робочий, каталог. Програміст може як довідатися про поточний каталог, так і встановити його. Функція SetCurrentDirectory установлює каталог:

BOOL SetCurrentDirectory (LPCTSTR lpszCurDir)

lpszCurDir - шлях до нового поточного каталогу. Це може бути відносний шлях або точний шлях, що починається з назви диска й двокрапки, наприклад D:\.

Якщо шлях до каталогу - просте позначення пристрою (наприклад, А: або С:), тоді поточним стає робочий каталог зазначеного диска. Наприклад, якщо робочі каталоги встановлені в послідовності

С:\MSDEV

INCLUDE

то в результаті поточний каталог буде С: \MSDEV\INCLUDE.

Функція GetCurrentDirectory повертає в буфер, заданий програмістом, повний шлях.

DWORD GetCurrentDirectory (

DWORD cchCurDir,

LPTSTR lpszCurDir)

Значення, що повертається - довжина рядка повернутого шляху або необхідний розмір буфера, якщо він недостатньо великий; нуль при невдачі. cchCurDir - довжина в символах (не в байтах) буфера для імені каталогу. Довжина повинна враховувати завершальний нульовий символ, lpszCurDir - указує на буфер, у який записується рядок шляху. Якщо буфер занадто малий, повідомляє його необхідну величину. Тому, при перевірці на невдале виконання функції повинен перевірятися як нульовий результат функції, так і результат, що перевищує значення параметра cchCurDir.

У каталозі можна шукати файли й інші каталоги, що задовольняють зазначеному зразку імені, а також одержувати атрибути файлів. Для цього необхідний дескриптор пошуку, котрий вертається функцією FindFirstFile. Для одержання потрібних файлів служить функція FindNextFile, а для завершення пошуку - FindClose.

HANDLE FindFirstFile (

LPCTSTR lpszSearchFile,

LPWIN32_FIND_DATA lpffd);

Значення, що повертається: дескриптор пошуку. INVALID_HANDLE_VALUE указує на невдачу.

FindFirstFile шукає відповідність імені як серед файлів, так і серед підкаталогів. Дескриптор, що повертається, використовується надалі в пошуку.

lpszSearchFile указує на каталог або повне ім'я, що може містити підстановочні знаки (? і *).

lpffd указує на структуру WIN32_FIND_DATA, що містить інформацію про знайдений файл або каталог.

Структура WIN32_FIND_DATA визначена в такий спосіб:

typedef struct WIN32_FIND_DATA {

DWORD dwFileAttributes;

FILETIME ftCreationTime;

FILETIME ftLastAccessTime;

FILETIME ftLastWriteTime;

DWORD nFileSizeHigh;

DWORD nFileSizeLow;

DWORD dwReserved0 ;

DWORD dwReservedl;

TCHAR cFileName [MAX_PATH];

TCHAR cAlternateFilename [14 ];}

WIN32 _FIND_DATA;

dwFileAttributes можна перевірити на відповідність значенням, наведеним в описі CreateFile. Далі йдуть три значення часу (час створення файлу, час останнього доступу й останнього запису). Поля розміру файлу, що містять його поточну довжину, не вимагають пояснень, cFileName - це не повне ім'я, а власне ім'я файлу, cAlternateFile - версія імені файлу для DOS формату 8.3 (включаючи крапку). Це те ж скорочення імені файлу, що відображається в провіднику Windows. Обидва імені - рядки із завершальним нулем.

Часто потрібно знайти в каталозі файли, імена яких задовольняють зразку, що містить підстановочні знаки ? і *. Для цього потрібно одержати з FindFirstFile дескриптор пошуку, що містить інформацію про шукане ім'я, і викликати функцію FindNextFile.

BOOL FindNextFile (

HANDLE hFindFile,

LPWIN32_FIND_DATA lpffd);

Функція FindNextFile повертає FALSE або при неприпустимих параметрах, або якщо відповідність даному зразку вже не можна знайти. В останньому випадку GetLastError повертає ERROR_NO_MORE_FILES.

Коли пошук закінчений, необхідно закрити дескриптор пошуку. Не можна використовувати для цього функцію CloseHandle. (Це рідке виключення із правила, за яким CloseHandle придатна для закриття всіх дескрипторів; закриття дескриптора пошуку викличе виняткову ситуацію) Для закриття дескрипторів пошуку призначено функцію FindClose:

BOOL FindClose (

HANDLE hFindFile);

Функція GetFileInformationByHandle дозволяє одержати ту ж інформацію для певного файлу, указавши його відкритий дескриптор.

Функції FindFirstFile і FindNextFile дозволяють одержувати наступну інформацію про атрибути файлу: прапори атрибутів, три штампи часу й розмір файлу. Для роботи з атрибутами є декілька інших функцій, включаючи ту, що дозволяє їх установлювати, і вони можуть працювати

безпосередньо з дескриптором відкритого файлу без перегляду каталогу або вказівки імені файлу. Інші функції служать для одержання інших атрибутів.

Функція GetFileAttributes за зазначеним іменем файлу й каталогу повертає тільки атрибути.

DWORD GetFileAttributes (

LPCTSTR lpszFileName);

Значення, що повертається: атрибути файлу або OxFFFFFFFF у випадку невдачі.

Атрибути можна перевірити на відповідність комбінаціям певних значень. Деякі атрибути, такі як прапор тимчасового файлу, установлюються при виклику CreateFile. Значення атрибутів можуть бути наступними:

FILE_ATTRIBUTE_DIRECTORY

FILE_ATTRIBUTE_NORMAL

FILE_ATTRIBUTE_READONLY

FILE_ATTRIBUTE_TEMPORARY

Функція SetFileAttributes змінює ці атрибути в зазначеному за іменем файлі.

Сформулюємо наступну підзадачу: в поточному каталозі встановити для всіх файлів із розширенням *.txt режим доступу Read Only.

Розв'яжемо задачу з можливістю «відкату». Використаємо функцію CopyFile, щоб копіювати всі текстові файли у поточному каталозі, у новий каталог файлів тільки для читання, названий \TextRO. Файли в новому каталозі, якщо необхідно, змінюються у файли тільки для читання. Створюємо каталог \TextRO, використовуючи функцію CreateDirectory.

Програма шукає в поточний каталог всі текстові файли, використовуючи функції FindFirstFile і FindNextFile. Кожний текстовий файл копіюється в каталог \TextRO. Після того, як копія файлу створена, функція GetFileAttributes з'ясовує, чи є цей файл - файлом тільки для читання. Якщо цей файл - не тільки для читання, додаток змінює каталоги в \TextRO і перетворить скопійований файл у файл тільки для читання, використовуючи функцію SetFileAttributes.

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

#include <windows.h>

#include <stdio.h>

int main()

{

WIN32_FIND_DATA FileData;

HANDLE hSearch;

DWORD dwAttrs;

TCHAR szDirPath[] = TEXT("c:\\TextRO\\");

TCHAR szNewPath[MAX_PATH];

BOOL fFinished = FALSE;

// Створюєм новий каталог.

if (!CreateDirectory(szDirPath, NULL))

{

printf("Could not create new directory.\n");

return;

}

// Начинаємо пошук текстових файлів в даному каталозі.

hSearch = FindFirstFile(TEXT("*.txt"), &FileData);

if (hSearch == INVALID_HANDLE_VALUE)

{

printf("No text files found.\n");

return;

}

// Копіюєм кажний .TXT файл в новий каталог

// і змінюєм його в "тільки для читання", якщо цього нема.

while (!fFinished)

{

lstrcpy(szNewPath, szDirPath);

lstrcat(szNewPath, FileData.cFileName);

if (CopyFile(FileData.cFileName, szNewPath, FALSE))

{

dwAttrs = GetFileAttributes(FileData.cFileName);

if( GetLastError() != 0 ) return;

if (!(dwAttrs & FILE_ATTRIBUTE_READONLY))

{

SetFileAttributes(szNewPath,

dwAttrs | FILE_ATTRIBUTE_READONLY);

}

}

else

{

printf("Could not copy file.\n");

return;

}

if (!FindNextFile(hSearch, &FileData))

{

if (GetLastError() == ERROR_NO_MORE_FILES)

{

printf("Copied all text files.\n");

fFinished = TRUE;

}

else

{

printf("Could not find next file.\n");

return;

}

}

}

// Закрываем дескриптор поиска.

FindClose(hSearch);

}

Аналогічно можна розв'язати інші підзадачі зміни атрибутів різноманітних файлів.

1.2 Засоби DOS

Зазначимо також, що в багатьох випадках зміна атрибутів легко може бути виконана також і за допомогою BAT-файлів з використанням команди attrib.

attrib [{+r|-r}] [{+a|-a}] [{+s|-s}] [{+h|-h}]

[[диск:][путь] им'я_файлу] [/s[/d]]

+r Установка атрибуту «Тільки читання».

-r Зняття атрибуту «Тільки читання».

+a Установка атрибуту «Архівний».

-a Зняття атрибуту «Архівний».

+s Установка атрибуту «Системний».

-s Зняття атрибуту «Системний».

+h Установка атрибуту «Схований».

-h Зняття атрибуту «Схований».

[диск:][шлях]ім'я_файлу Задання місцезнаходження й імені каталогу, файлу або набору файлів, атрибути яких потрібно переглянути або змінити. Для обробки групи файлів допускається застосування пыдстановочних знаків (? і *) у параметрі ім'я_файлу.

/s Виконання команди attrib і всіх параметрів командного рядка для відповідних файлів у поточному каталозі й всіх його підкаталогах.

/d Виконання команди attrib і всіх параметрів командного рядка для каталогів.

1.3 Засоби візуалізації С#

Візуалізація здійснюється засобами С#. Для управління атрибутами файлів необхідно скористатися статичними методами: File.GetAttributes та File.SetAttributes.

string filePath = @"c:\test.txt";

// отримати атрибути файлу

FileAttributes fileAttributes = File.GetAttributes(filePath);

// очистити всі атрибути файлу

File.SetAttributes(filePath, FileAttributes.Normal);

// встановити тільки атрибути Архівний і Тільки для читання

File.SetAttributes(filePath, FileAttributes.Archive |

FileAttributes.ReadOnly);

// очистити від атрибуту Схований

File.SetAttributes(filePath,

File.GetAttributes(filePath) & ~FileAttributes.Hidden);

Інтерфейс програми схожий на файловий менеджер. Для початку вам необхідно перейти в папку, у якій перебувають файли, атрибути й властивості яких вам необхідно змінити (рис.1.1).

Рис.1.1. Головне вікно додатку

Для зміни атрибуту домучу до певного файлу необхідно двічі клацнути по ньому мишкою. В результаті з'являється вікно «Змінити атрибути доступу» (рис.1.2).

Рис.2. Вікно зміни атрибутів

Для зміни чотирьох стандартних файлових атрибутів необхідно вибрати напроти кожного атрибута його значення: Reset (Убрати), Set (Установити) або Do not modify (Залишити без змін). Якщо задано прапор Preview results, то перед остаточною зміною будуть показані дійсні атрибути і їхні майбутні значення (рис.3).

Рис.3. Попередній перегляд змін

Для прийняття зазначених змін досить нажати кнопку Apply Changes (Застосувати зміни).

На нашу думку для вирішення поставленого завдання доцільно скористатися можливостями C#, що забезпечить дружній для користувача інтерфейс та широкі можливості обробки помилок вводу та виключень.

РОЗДІЛ 2. Формування запиту до компонентів операційної системи з

метою отримання інформації про створені та використовувані нею

файли

2.1 Дизайн головної форми

Для реалізації даної функції використовуємо Windows Forms в середовищі програмування Visual Studio. Мова програмування С#.

Звичайним рішенням в багатьох задачах при створенні інтерфейсу користувача (UI) є використання елементів управління List View та Tree View, що надає можливість побудувати браузер з властивостями Windows Explorer. Даний браузер є інструментом, що відображає ієрархічну структуру файлів та папок на комп'ютері користувача.

Щоб створити форму з елементами управління List View та Tree View, здійснюємо наступне:

1) в меню File обираємо New, і натискаємо на Project.

Рис.2.1. Вікно властивостей SplitContainer

2) в діалоговому вікні New Project виконуємо наступне:

Обираємо тип проекту: Visual C# Projects;

Обираємо шаблон проекту: Windows Application.

Натискаємо OK. Новий проект Windows Forms створено.

3) додаємо елемент управління SplitContainer на форму та встановлюємо його властивість Dock на Left. (рис.2.1)

4) Додаємо ImageList під назвою imageList1 на форму і використовуємо браузер властивостей, щоб додати зображення (рис.2.2).

Рис.2.2. Зображення, що використовуються у програмі

Додавання зображень повинно логічно відповідати використанню у програмі (рис.2.3)

Рис.2.3 Додавання іконок до ImageList

5) Додаємо елемент управління TreeView під назвою treeview1 на форму і розміщуємо його зліва від SplitContainer. В браузері властивостей treeView1 додаємо наступне:

встановлюємо його властивість Dock на Left;

встановлюємо властивість ImageList на imageList1.

6) Додаємо елемент управління ListView під назвою listView1 на форму і розміщуємо його справа від SplitContainer. В браузері властивостей listView1 додаємо наступне:

встановлюємо його властивість Dock на Fill;

встановлюємо його властивість View на Details;

відкриваємо ColumnHeader Collection Editor (рис.2.4)

Рис.2.4. Формування колонок з інформацією про файли

Додаємо п'ять колонок, в який буде відображатися така інформація про файл:

назва;

розмір;

дата останнього редагування;

час останнього редагування;

атрибути.

Натискаємо ОК і закриваємо ColumnHeader Collection Editor.

7) Додаємо елемент управління mainMenu1.

Отримаємо наступний дизайн форми (рис.2.5).

Рис.2.5. Дизайн головної форми додатку

2.2 Реалізація методів відображення інформації про директорії та

файли

Додаємо код для реалізації методів.

Метод відображення інформації о директоріях на дисках або в інших директоріях в елементі treeView1:

private void AddDirectories(TreeNode tnSubNode)

{

treeView1.BeginUpdate();

iDirectories = 0;

try

{

DirectoryInfo diRoot;

// Якщо це драйвер, отримати директорії з драйвера

if(tnSubNode.SelectedImageIndex < 11)

{

diRoot = new DirectoryInfo(tnSubNode.FullPath + "\\");

}

// Якщо ні, отримати директорії з директорій

else

{

diRoot = new DirectoryInfo(tnSubNode.FullPath);

}

DirectoryInfo[] dirs = diRoot.GetDirectories();

// необхідно очистити, інакше директорії будуть дублюватися у дереві

tnSubNode.Nodes.Clear();

// Додаємо субдиректорії до дерева

foreach(DirectoryInfo dir in dirs)

{

iDirectories++;

TreeNode subNode = new TreeNode(dir.Name);

subNode.ImageIndex = 11;

subNode.SelectedImageIndex = 12;

tnSubNode.Nodes.Add(subNode);

}

}

// виключенння при досутпу до директорії : C:\System Volume Information // do nothing

catch{;}

treeView1.EndUpdate();

}

Метод відображення інформації о файлах на дисках або в директоріях в елементі listView1:

private void AddFiles(string strPath)

{

// починаємо оновлення списку

listView1.BeginUpdate();

// очищуємо список

listView1.Items.Clear();

iFiles = 0;

try

{

DirectoryInfo di = new DirectoryInfo(strPath + "\\");

// масив файлів

FileInfo[] theFiles = di.GetFiles();

foreach(FileInfo theFile in theFiles)

{

iFiles++;

// формуємо запис по колонкам у списку

ListViewItem lvItem = new ListViewItem(theFile.Name);

lvItem.SubItems.Add(theFile.Length.ToString());

lvItem.SubItems.Add(theFile.LastWriteTime.ToShortDateString());

lvItem.SubItems.Add(theFile.LastWriteTime.ToShortTimeString());

lvItem.SubItems.Add(theFile.Attributes.ToString());

listView1.Items.Add(lvItem);

}

}

// виключенння при досутпу до файлу

catch(Exception Exc)

{statusBar1.Text = Exc.ToString();}

// закінчення оновлення списку

listView1.EndUpdate();

}

2.3 Основні події

Дані методи використовуються при реалізації відповідних подій.

Подія: завантаження форми

private void Form1_Load(object sender, System.EventArgs e)

{

// Додаємо всі дайвера компютера до кореневих вузлів treeView1

string[] aDrives = Environment.GetLogicalDrives();

treeView1.BeginUpdate();

foreach(string strDrive in aDrives)

{

TreeNode dnMyDrives = new TreeNode(strDrive.Remove(2,1));

switch (strDrive)

{

case "A:\\":

dnMyDrives.SelectedImageIndex = 0;

dnMyDrives.ImageIndex = 0;

break;

case "C:\\":

// активізуємо подію treeView1_AfterSelect Event відразу при завантаженні.

// C:\ обирається вузол

// автоматично при завантаженні бачимо вузол C:\ treeView1treeView1.SelectedNode = dnMyDrives;

dnMyDrives.SelectedImageIndex = 1;

dnMyDrives.ImageIndex = 1;

break;

case "D:\\":

dnMyDrives.SelectedImageIndex = 2;

dnMyDrives.ImageIndex = 2;

break;

default:

dnMyDrives.SelectedImageIndex = 3;

dnMyDrives.ImageIndex = 3;

break;

}

treeView1.Nodes.Add(dnMyDrives);

}

treeView1.EndUpdate();

}

Подія: вибір директорії у дереві

private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)

{

// отримуємо субдиректорії, додаємо до treeView1AddDirectories(e.Node);

// якщо вузод закритий, рлзкриваємо його одним кліком

treeView1.SelectedNode.Expand();

// отримуємо файли, додаємо до listView1

AddFiles(e.Node.FullPath.ToString());

statusBar1.Text = iDirectories.ToString() + " Folder(s) " + iFiles.ToString() + " File(s)";

}

Подія: вибір опцій меню

private void menuItem2_Click(object sender, System.EventArgs e)

{

//закриття програми

this.Close();

}

private void menuItem4_Click(object sender, System.EventArgs e)

{

//інформація про emailавтора

MessageBox.Show("Управление атрибутами файлов\n\nВопросы? email:\nadjustment00x@gmail.com");

}

Результат виконання при запуску програми:

Рис2.6. Вид головного вікна при запуску програми

РОЗДІЛ 3. Зміна атрибутів доступу до файлів за вибором користувача

3.1 Дизайн та події діалогового вікна зміни атрибутів

Діалогове вікно для зміни атрибутів обраного файлу має наступний дизайн (рис.3.1).

Рис.3.1. Діалогове вікно

Вікно активізується при виборі файлу в елементі listView1 на основній формі. Відповідна подія:

Подія: вибір файлу у listView1 (подвійний клік)

private void listView1_ItemActivate(object sender, System.EventArgs e)

{

try

{

//для обміну інформацію в процесі іалогу

TV_LV_Basic.Form2 dialForm = new TV_LV_Basic.Form2();

dialForm.mainForm = this;

//відкриваємо діалогове вікно як модальне

//(поки не закриємо, головна форма недоступна)

dialForm.ShowDialog();

//освіжаємо дані listView1 після діалогу

string sPath = treeView1.SelectedNode.FullPath;

AddFiles(sPath);

}

catch(Exception Exc){MessageBox.Show(Exc.ToString());}

}

При натисканні кнопки «Показати атрибути» відбувається наступне:

Подія: натискання кнопки «Показати атрибути»

private void button1_Click(object sender, EventArgs e)

{

try

{

//файл, обраний у listView1

string sPath = mainForm.treeView1.SelectedNode.FullPath;

string sFileName = mainForm.listView1.FocusedItem.Text;

string filePath = sPath + "\\" + sFileName;

//заповнюємо масив атрибутами файлу

attr[0] = ((File.GetAttributes(filePath) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly);

attr[1] = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden);

attr[2] = ((File.GetAttributes(filePath) & FileAttributes.Archive) == FileAttributes.Archive);

attr[3] = ((File.GetAttributes(filePath) & FileAttributes.System) == FileAttributes.System);

//показуємо атрибути

if (attr[0]) label5.Text = " + ";

if (attr[1]) label7.Text = " + ";

if (attr[2]) label9.Text = " + ";

if (attr[3]) label11.Text = " + ";

//активізуємо другу кнопку

button2.Visible = true;

//прибираємо першу кнопку

button1.Visible = false;

}

catch(Exception Exc){MessageBox.Show(Exc.ToString());}

}

При натисканні кнопки «Виконати зміни» відбувається наступне:

Подія: натискання кнопки «Виконати зміни»

private void button2_Click(object sender, EventArgs e)

{

try

{

string sPath = mainForm.treeView1.SelectedNode.FullPath;

string sFileName = mainForm.listView1.FocusedItem.Text;

string filePath = sPath + "\\" + sFileName;

if (comboBox1.SelectedIndex == 0)

attr[0] = true;

if (comboBox1.SelectedIndex == 1)

attr[0] = false;

if (comboBox2.SelectedIndex == 0)

attr[1] = true;

if (comboBox2.SelectedIndex == 1)

attr[1] = false;

if (comboBox3.SelectedIndex == 0)

attr[2] = true;

if (comboBox3.SelectedIndex == 1)

attr[2] = false;

if (comboBox4.SelectedIndex == 0)

attr[3] = true;

if (comboBox4.SelectedIndex == 1)

attr[3] = false;

// очистити всі атрибути файлу

File.SetAttributes(filePath, FileAttributes.Normal);

//установити (додати) визначені атрибути

if(attr[0])

File.SetAttributes(filePath, File.GetAttributes(filePath) | FileAttributes.ReadOnly);

if (attr[1])

File.SetAttributes(filePath, File.GetAttributes(filePath) | FileAttributes.Hidden);

if (attr[2])

File.SetAttributes(filePath, File.GetAttributes(filePath) | FileAttributes.Archive);

if (attr[3])

File.SetAttributes(filePath, File.GetAttributes(filePath) | FileAttributes.System);

//закрити діалогову форму

this.Close();

}

catch (Exception Exc) { MessageBox.Show(Exc.ToString()); }

}

3.2 Результати тестування

В якості тестування змінимо атрибути двох файлів (pdf та doc), що знаходяться в папці ZNO_info на диску D.

1 етап

Активізуємо головне вікно і перейдемо до визначеної директорії (рис.3.2)

Рис.3.2.Директорія D:\ZNO_info з двома файлами, що мають атрибут «архівний»

2 етап

Змінимо атрибути pdf-файлу - додамо «Тільки для читання» і «Скритий»

Для цього робимо два кліки мишкою у відповідному рядку listView1

Відривається діалогове вікно (рис.3.3)

Рис.3.3 Активізація діалогового вікна

Натискаємо кнопку «Показати атрибути». Результат - на рис.3.4

Рис.3.4. Після натискання кнопки «Показати атрибути»

Обираємо опції для змін (рис.3.5)

Рис.3.5. Обрані опції для змін атрибутів

Натискаємо кнопку «Виконати зміни». Діалогове вікно закривається, і ми бачимо результат у головному вікні (рис.3.6).

каталог файл алгоритм програма тестування

Рис.3.6. Результат зміни атрибутів першого файлу

3 етап

Змінимо атрибути doc-файлу - уберемо «Архівний» і додамо «Системний» (рис.3.7).

Рис. 3.7

Результат - на рис.3.8.

Рис.3.8. Результат зміни атрибутів другого файлу

РОЗДІЛ 4. Практичне використання програми

4.1 Засоби попередження помилок користувача та аварійних виходів

Дизайн додатку надає можливості попередження помилок користувача та аварійних виходів за рахунок:

використання блоків try - catch при роботі з файловою системою

однозначної послідовності дій, щоб досягнути результату

відсутності «пустих» опцій при виборі тих чи інших параметрів змін.

4.2 Підготовка установочного пакету

Для підготовки установочного пакету необхідно в середовищі Visual Studio зібрати розроблений проект в режимі Release (рис.4.1).

Рис.4.1 Установка опції зборки проекту в режимі Release

Вміст папки Release можна подивитися за допомогою нашого ж додатку (рис.4.2).

Рис.4.2 Вміст папки Release

Для того, щоб додаток працював на будь-якому комп'ютері, вмісту лише папки Release недостатньо.

Попередньо необхідно установити The Microsoft Visual C++ 2010 Redistributable Package (x86) (vcredist_x86.exe), компоненти runtime бібліотеки Visual C++ Libraries, необхідні при виконанні проектів, зібраних у середовищі Visual, на комп'ютері, де таке середовище не встановлено. Цей пакет встановлює компоненти C Runtime (CRT), Standard C++, ATL, MFC, OpenMP та MSDIA libraries.

Отже, якщо при запуску TV-LV-basic.exe операційна система сповіщає про неможливість виконання, необхідно спочатку установити пакет x86.

4.3 Установка утілити користувачем

Установочний пакет має наступний вміст (рис.4.3).

Рис.4.3. Вміст установочного пакету

Для установки користувачеві необхідно:

скопіювати файли в обрану папку;

запустити на виконання файл vcredist_x86.exe , щоб встановити необхідні компоненти динамічних бібліотек.

Після цього програма працює на будь-якому комп'ютері, що задовольняє системним вимогам. Для початку роботи - запустіть файл TV-LV-basic.exe. При бажанні можна зробити ярлик на робочому столі.

ВИСНОВКИ

При виконанні курсової роботи були вирішені всі поставлені завдання.

Реалізація задачі в середовищі Visual Studio дозволила створити сучасний додаток, з інтуїтивним та дружнім для користувача інтерфейсом.

Використання блоків try - catch при роботі з файловою системою дозволяє уникати аварійного завершення програми.

В ході роботи користувач самостійно не вводить даних, а лише обирає задані опції. Отже, програма вільна від помилок користувача при вводі даних.

Додаток можна характеризувати як надійний інструмент, та рекомендувати для практичного використання.

СПИСОК ВИКОРИСТАНОЇ ЛІТЕРАТУРИ

1. Deitel Paul, Deitel Harvey. C# 2010 for programmers. Fourth edition. - 1239 p.

2. Freeman Adam. Introducing Visual C# 2010. - 1321 p.

3. Shildt Herbert. C#4.0 The Complete Reference. 2010. - 976 p.

ДОДАТКИ

Додаток А

Листінг модулю Form1.cs

using System;

using System.Windows.Forms;

using System.IO;

using System.Diagnostics;

// Date:2011-16-12

// Email:adjustment00x@gmail.com

// Oblectives:Control over File Attributes

public class Form1 : System.Windows.Forms.Form

{

// Counters for statusBar1 control

private int iFiles = 0;

private int iDirectories = 0;

// Windows Designer variables

private System.Windows.Forms.MainMenu mainMenu1;

private System.Windows.Forms.Panel panel1;

private System.Windows.Forms.MenuItem menuItem1;

private System.Windows.Forms.MenuItem menuItem2;

private System.Windows.Forms.StatusBar statusBar1;

public System.Windows.Forms.TreeView treeView1; //dialogue with Form 2

private System.Windows.Forms.Splitter splitter1;

public System.Windows.Forms.ListView listView1; //dialogue with Form 2

private System.Windows.Forms.ImageList imageList1;

private System.Windows.Forms.ColumnHeader columnHeader1;

private System.Windows.Forms.ColumnHeader columnHeader2;

private System.Windows.Forms.ColumnHeader columnHeader3;

private System.Windows.Forms.ColumnHeader columnHeader4;

private System.Windows.Forms.MenuItem menuItem3;

private System.Windows.Forms.MenuItem menuItem4;

private ColumnHeader columnHeader5;

private System.ComponentModel.IContainer components;

public Form1()

{

//

// Required for Windows Form Designer support

//

InitializeComponent();

//

// TODO: Add any constructor code after InitializeComponent call

//

}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.components = new System.ComponentModel.Container();

System.ComponentModel.ComponentResourceManager resources = new

System.ComponentModel.ComponentResourceManager(typeof(Form1));

this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components);

this.menuItem1 = new System.Windows.Forms.MenuItem();

this.menuItem2 = new System.Windows.Forms.MenuItem();

this.menuItem3 = new System.Windows.Forms.MenuItem();

this.menuItem4 = new System.Windows.Forms.MenuItem();

this.panel1 = new System.Windows.Forms.Panel();

this.listView1 = new System.Windows.Forms.ListView();

this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));

this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));

this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));

this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));

this.splitter1 = new System.Windows.Forms.Splitter();

this.treeView1 = new System.Windows.Forms.TreeView();

this.imageList1 = new System.Windows.Forms.ImageList(this.components);

this.statusBar1 = new System.Windows.Forms.StatusBar();

this.columnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));

this.panel1.SuspendLayout();

this.SuspendLayout();

//

// mainMenu1

//

this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {

this.menuItem1,

this.menuItem3});

//

// menuItem1

//

this.menuItem1.Index = 0;

this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {

this.menuItem2});

this.menuItem1.Text = "File";

//

// menuItem2

//

this.menuItem2.Index = 0;

this.menuItem2.Text = "Exit";

this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);

//

// menuItem3

//

this.menuItem3.Index = 1;

this.menuItem3.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {

this.menuItem4});

this.menuItem3.Text = "Help";

//

// menuItem4

//

this.menuItem4.Index = 0;

this.menuItem4.Text = "About";

this.menuItem4.Click += new System.EventHandler(this.menuItem4_Click);

//

// panel1

//

this.panel1.Controls.Add(this.listView1);

this.panel1.Controls.Add(this.splitter1);

this.panel1.Controls.Add(this.treeView1);

this.panel1.Controls.Add(this.statusBar1);

this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;

this.panel1.Location = new System.Drawing.Point(0, 0);

this.panel1.Name = "panel1";

this.panel1.Size = new System.Drawing.Size(958, 550);

this.panel1.TabIndex = 0;

//

// listView1

//

this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {

this.columnHeader1,

this.columnHeader2,

this.columnHeader3,

this.columnHeader4,

this.columnHeader5});

this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;

this.listView1.Location = new System.Drawing.Point(259, 0);

this.listView1.Name = "listView1";

this.listView1.Size = new System.Drawing.Size(699, 528);

this.listView1.TabIndex = 6;

this.listView1.UseCompatibleStateImageBehavior = false;

this.listView1.View = System.Windows.Forms.View.Details;

this.listView1.ItemActivate += new System.EventHandler(this.listView1_ItemActivate);

//

// columnHeader1

//

this.columnHeader1.Text = "Name";

this.columnHeader1.Width = 220;

//

// columnHeader2

//

this.columnHeader2.Text = "Size";

this.columnHeader2.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;

this.columnHeader2.Width = 100;

//

// columnHeader3

//

this.columnHeader3.Text = "Date";

this.columnHeader3.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;

this.columnHeader3.Width = 90;

//

// columnHeader4

//

this.columnHeader4.Text = "Time";

this.columnHeader4.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;

//

// splitter1

//

this.splitter1.Location = new System.Drawing.Point(256, 0);

this.splitter1.Name = "splitter1";

this.splitter1.Size = new System.Drawing.Size(3, 528);

this.splitter1.TabIndex = 5;

this.splitter1.TabStop = false;

//

// treeView1

//

this.treeView1.Dock = System.Windows.Forms.DockStyle.Left;

this.treeView1.HotTracking = true;

this.treeView1.ImageIndex = 0;

this.treeView1.ImageList = this.imageList1;

this.treeView1.Location = new System.Drawing.Point(0, 0);

this.treeView1.Name = "treeView1";

this.treeView1.SelectedImageIndex = 0;

this.treeView1.ShowPlusMinus = false;

this.treeView1.Size = new System.Drawing.Size(256, 528);

this.treeView1.TabIndex = 4;

this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);

//

// imageList1

//

this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));

this.imageList1.TransparentColor = System.Drawing.Color.Transparent;

this.imageList1.Images.SetKeyName(0, "");

this.imageList1.Images.SetKeyName(1, "");

this.imageList1.Images.SetKeyName(2, "");

this.imageList1.Images.SetKeyName(3, "");

this.imageList1.Images.SetKeyName(4, "");

this.imageList1.Images.SetKeyName(5, "");

this.imageList1.Images.SetKeyName(6, "");

this.imageList1.Images.SetKeyName(7, "");

this.imageList1.Images.SetKeyName(8, "");

this.imageList1.Images.SetKeyName(9, "");

this.imageList1.Images.SetKeyName(10, "");

this.imageList1.Images.SetKeyName(11, "");

this.imageList1.Images.SetKeyName(12, "");

//

// statusBar1

//

this.statusBar1.Location = new System.Drawing.Point(0, 528);

this.statusBar1.Name = "statusBar1";

this.statusBar1.Size = new System.Drawing.Size(958, 22);

this.statusBar1.TabIndex = 3;

this.statusBar1.Text = "Ready";

//

// columnHeader5

//

this.columnHeader5.Text = "Attributes";

this.columnHeader5.Width = 220;

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(958, 550);

this.Controls.Add(this.panel1);

this.Menu = this.mainMenu1;

this.Name = "Form1";

this.Text = "Управление атрибутами доступа к файлам";

this.Load += new System.EventHandler(this.Form1_Load);

this.panel1.ResumeLayout(false);

this.ResumeLayout(false);

}

#endregion

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

// Methods

private void AddDirectories(TreeNode tnSubNode)

{

// This method is used to get directories (from disks, or from other directories)

treeView1.BeginUpdate();

iDirectories = 0;

try

{

DirectoryInfo diRoot;

// If drive, get directories from drives

if(tnSubNode.SelectedImageIndex < 11)

{

diRoot = new DirectoryInfo(tnSubNode.FullPath + "\\");

}

// Else, get directories from directories

else

{

diRoot = new DirectoryInfo(tnSubNode.FullPath);

}

DirectoryInfo[] dirs = diRoot.GetDirectories();

// Must clear this first, else the directories will get duplicated in treeview

tnSubNode.Nodes.Clear();

// Add the sub directories to the treeView1

foreach(DirectoryInfo dir in dirs)

{

iDirectories++;

TreeNode subNode = new TreeNode(dir.Name);

subNode.ImageIndex = 11;

subNode.SelectedImageIndex = 12;

tnSubNode.Nodes.Add(subNode);

}

}

// Throw Exception when accessing directory: C:\System Volume Information // do nothing

catch{;}

treeView1.EndUpdate();

}

private void AddFiles(string strPath)

{

listView1.BeginUpdate();

listView1.Items.Clear();

iFiles = 0;

try

{

DirectoryInfo di = new DirectoryInfo(strPath + "\\");

FileInfo[] theFiles = di.GetFiles();

foreach(FileInfo theFile in theFiles)

{

iFiles++;

ListViewItem lvItem = new ListViewItem(theFile.Name);

lvItem.SubItems.Add(theFile.Length.ToString());

lvItem.SubItems.Add(theFile.LastWriteTime.ToShortDateString());

lvItem.SubItems.Add(theFile.LastWriteTime.ToShortTimeString());

lvItem.SubItems.Add(theFile.Attributes.ToString());

listView1.Items.Add(lvItem);

}

}

catch(Exception Exc){statusBar1.Text = Exc.ToString();}

listView1.EndUpdate();

}

// Events

private void menuItem2_Click(object sender, System.EventArgs e)

{

// The proper way to close any application.

this.Close();

}

private void Form1_Load(object sender, System.EventArgs e)

{

// This routine adds all computer drives to the root nodes of treeView1 control

string[] aDrives = Environment.GetLogicalDrives();

treeView1.BeginUpdate();

foreach(string strDrive in aDrives)

{

TreeNode dnMyDrives = new TreeNode(strDrive.Remove(2,1));

switch (strDrive)

{

case "A:\\":

dnMyDrives.SelectedImageIndex = 0;

dnMyDrives.ImageIndex = 0;

break;

case "C:\\":

// The next statement causes the treeView1_AfterSelect Event to fire once on startup.

// This effect can be seen just after intial program load. C:\ node is selected

// Automatically on program load, expanding the C:\ treeView1 node.

treeView1.SelectedNode = dnMyDrives;

dnMyDrives.SelectedImageIndex = 1;

dnMyDrives.ImageIndex = 1;

break;

case "D:\\":

dnMyDrives.SelectedImageIndex = 2;

dnMyDrives.ImageIndex = 2;

break;

default:

dnMyDrives.SelectedImageIndex = 3;

dnMyDrives.ImageIndex = 3;

break;

}

treeView1.Nodes.Add(dnMyDrives);

}

treeView1.EndUpdate();

}

private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)

{

// Get subdirectories from disk, add to treeView1 control

AddDirectories(e.Node);

// if node is collapsed, expand it. This allows single click to open folders.

treeView1.SelectedNode.Expand();

// Get files from disk, add to listView1 control

AddFiles(e.Node.FullPath.ToString());

statusBar1.Text = iDirectories.ToString() + " Folder(s) " + iFiles.ToString() + " File(s)";

}

private void listView1_ItemActivate(object sender, System.EventArgs e)

{

try

{ //for data exchange during the dialogue

TV_LV_Basic.Form2 dialForm = new TV_LV_Basic.Form2();

dialForm.mainForm = this;

//open as a modal form (main form not available while working with the dialog)

dialForm.ShowDialog();

//refresh listBox1 after the dialog

string sPath = treeView1.SelectedNode.FullPath;

AddFiles(sPath);

}

catch(Exception Exc){MessageBox.Show(Exc.ToString());}

}

private void menuItem4_Click(object sender, System.EventArgs e)

{

MessageBox.Show("Управление атрибутами файлов\n\nВопросы? email:\nadjustment00x@gmail.com");

}

}

Додаток Б

Листінг модулю Form2.cs

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.IO;

namespace TV_LV_Basic

{

public partial class Form2 : Form

{

//dialog with Form1

public Form1 mainForm;

public Form2()

{

InitializeComponent();

//default choice

comboBox1.SelectedIndex = 2;

comboBox2.SelectedIndex = 2;

comboBox3.SelectedIndex = 2;

comboBox4.SelectedIndex = 2;

}

//create array of attributes

bool[] attr = { false, false, false, false };

private void button1_Click(object sender, EventArgs e)

{

try

{ string sPath = mainForm.treeView1.SelectedNode.FullPath;

string sFileName = mainForm.listView1.FocusedItem.Text;

string filePath = sPath + "\\" + sFileName;

//fill the array with the initial attributes

attr[0] = ((File.GetAttributes(filePath) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly);

attr[1] = ((File.GetAttributes(filePath) & FileAttributes.Hidden) == FileAttributes.Hidden);

attr[2] = ((File.GetAttributes(filePath) & FileAttributes.Archive) == FileAttributes.Archive);

attr[3] = ((File.GetAttributes(filePath) & FileAttributes.System) == FileAttributes.System);

//show attributes

if (attr[0]) label5.Text = " + ";

if (attr[1]) label7.Text = " + ";

if (attr[2]) label9.Text = " + ";

if (attr[3]) label11.Text = " + ";

button2.Visible = true;

button1.Visible = false;

}

catch(Exception Exc){MessageBox.Show(Exc.ToString());}

}

private void button2_Click(object sender, EventArgs e)

{

try

{

string sPath = mainForm.treeView1.SelectedNode.FullPath;

string sFileName = mainForm.listView1.FocusedItem.Text;

string filePath = sPath + "\\" + sFileName;

if (comboBox1.SelectedIndex == 0)

attr[0] = true;

if (comboBox1.SelectedIndex == 1)

attr[0] = false;

if (comboBox2.SelectedIndex == 0)

attr[1] = true;

if (comboBox2.SelectedIndex == 1)

attr[1] = false;

if (comboBox3.SelectedIndex == 0)

attr[2] = true;

if (comboBox3.SelectedIndex == 1)

attr[2] = false;

if (comboBox4.SelectedIndex == 0)

attr[3] = true;

if (comboBox4.SelectedIndex == 1)

attr[3] = false;

// clear all file attributes

File.SetAttributes(filePath, FileAttributes.Normal);

//set (add) new attributes

if(attr[0])

File.SetAttributes(filePath, File.GetAttributes(filePath) | FileAttributes.ReadOnly);

if (attr[1])

File.SetAttributes(filePath, File.GetAttributes(filePath) | FileAttributes.Hidden);

if (attr[2])

File.SetAttributes(filePath, File.GetAttributes(filePath) | FileAttributes.Archive);

if (attr[3])

File.SetAttributes(filePath, File.GetAttributes(filePath) | FileAttributes.System);

//close Form2

this.Close();

}

catch (Exception Exc) { MessageBox.Show(Exc.ToString()); }

}

}

}

Размещено на Allbest.ru


Подобные документы

  • Особливості програмної реалізації алгоритму пошуку файлів з заданими атрибутами. Опис програмного комплексу на мові Turbo С. Розробка інструкції користувача. Тестування програмного продукту на операційних системах MS DOS 5.0/6.0/6.2 і Windows 95/98/Me/Xp.

    курсовая работа [27,0 K], добавлен 21.07.2011

  • MS-DOS - перша операційна система. Створення в операційній системі MS-DOS резидентної програми захисту файлів від видалення, її використання в випадках захисту файлів від випадкового видалення. Структура вхідних та вихідних даних, алгоритм рішення задачі.

    курсовая работа [35,5 K], добавлен 16.11.2012

  • Огляд переваг асемблера при роботі резидентної програми русифікатора клавіатури і дисплея. Вивчення різновидів дискет, нутрощів дисковода, функцій базової версії DOS. Аналіз можливостей створення і обробки дискових файлів послідовним і прямим доступом.

    курсовая работа [33,3 K], добавлен 20.04.2012

  • Інструменти середовища C++Builder, які були використані в програмі. Робота з файлами, їх відкриття, відображення та закриття. Розробка основних функцій для реалізації програми. Тестування програмного забезпечення. Блок-схема та алгоритм програми.

    курсовая работа [924,3 K], добавлен 14.01.2014

  • BMP як формат зберігання растрових зображень, огляд структури файлу. Створення програми для запису та перегляду графічних BMP-файлів на мові програмування Turbo Pascal 7.0, розробка функціональної схеми і алгоритмів, особливості проведення тестування.

    курсовая работа [325,8 K], добавлен 12.06.2011

  • Характеристика об’єкта автоматизації, вимоги до системи, склад та зміст системи. Розробка функціональної схеми програмного продукту. Тестування підпрограми програмного продукту. Розробка бази даних та налаштування ECO компонент в Borland Developer Studio.

    практическая работа [1,8 M], добавлен 05.06.2014

  • Створення програми, що видає результати голосування та підсумки виборів. Алгоритм розробки програми. Опис структури даних та вимоги до них, стандартних процедур та функцій, файлів та їх призначення. Приклад тестування та результати роботи програми.

    курсовая работа [1,0 M], добавлен 28.06.2012

  • Вирішення задач сортування в програмуванні та розробка ефективних алгоритмів сортування. Знайомство з теоретичним положенням, що стосуються методів сортування файлів, реалізації їх на мові програмування Turbo Pascal. Методи злиття впорядкованих серій.

    курсовая работа [46,9 K], добавлен 16.09.2010

  • Визначення та застосування фракталів. Огляд предметної області, вибір засобів розробки програмного забезпеченя. Побудова діаграми варіантів використання, послідовності дій, класів та компонентів, математичної моделі. Тестування програмного продукту.

    дипломная работа [1,9 M], добавлен 24.05.2015

  • Цілі і завдання розробки, її предмет і актуальність. Опис предметної області, цілі і завдання програми. Вибір методу рішення, опис процесу програмування і вибір інструментальних засобів для реалізації проекту, опис вхідних та вихідних даних, інтерфейсу.

    курсовая работа [327,1 K], добавлен 01.09.2014

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.