using Emgu.CV.Face; using Emgu.CV.Structure; using Emgu.CV.Util; using Emgu.CV; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Windows.Media.Imaging; using Emgu.CV.CvEnum; using System.Runtime.CompilerServices; using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; using System.Data.SqlClient; using Emgu.CV.Ocl; using DirectShowLib; using System.Runtime.Serialization.Formatters.Binary; namespace T_FaceRecognizer { public partial class FormMain : Form { public FormMain() { InitializeComponent(); } private void CaptureTimer_Tick(object sender, EventArgs e) { ProcessFrame(); } #region <Переменные> SqlConnection SCon = new SqlConnection(@"Data Source=213.155.192.79,3002;Initial Catalog=FaceTrackApp;Persist Security Info=True;User ID=u20teresh;Password=bfg2"); public int SelectedCameraID { get; set; } = 0; Rectangle CurrentFace; public string UserName { get; set; } = "Лицо не обнаружено"; /// /// ID пользователя, который обнаружен /// private string CurrentUserID = string.Empty; /// /// тип операции 1 - вход, 0- выход /// private int TypeOperation = 0; private bool IsMenuOpened = true; //доступные видеокамеры private DsDevice[] WebCams = null; int CountCams = -1; HashSet HtBefore = new HashSet(); //включена ли на данный момент камера #endregion #region <Свойства> public event PropertyChangedEventHandler PropertyChanged; private VideoCapture Capture; private CascadeClassifier HaarCascade; private Image BgrFrame = null; private Image DetectedFace = null; private List FaceList = new List(); private VectorOfMat ImageList = new VectorOfMat(); private List NameList = new List(); private VectorOfInt LabelList = new VectorOfInt(); private EigenFaceRecognizer recognizer; private Timer CaptureTimer; private Timer CaptureTimerIdent; private bool IsRecognized = false; #region FaceName private string faceName; public string FaceName { get { return faceName; } set { faceName = value; if (faceName == "Лицо не обнаружено") { IsRecognized = false; } else { IsRecognized = true; } UserName = faceName; NotifyPropertyChanged(); } } #endregion #region CameraCaptureImage private Bitmap cameraCapture; public Bitmap CameraCapture { get { return cameraCapture; } set { cameraCapture = value; if (TabPages.SelectedIndex == 1) { DrawName(cameraCapture, CurrentFace); PbxIdentification.Image = cameraCapture; } else { PbxFaces.Image = cameraCapture; } NotifyPropertyChanged(); } } #endregion #region CameraCaptureFaceImage private Bitmap cameraCaptureFace; public Bitmap CameraCaptureFace { get { return cameraCaptureFace; } set { cameraCaptureFace = value; PbxFaces.Image = cameraCapture; NotifyPropertyChanged(); } } #endregion #endregion /// /// отрисовка имени над прямоугольком /// private void DrawName(Bitmap cameraCapture, Rectangle face) { Pen PenForFace = new Pen(Brushes.Red, 5); Brush BrushForFace = Brushes.White; Font MyFont = new Font("Segoe UI Variable Small Semibol; 12pt; style=Bold", 12, FontStyle.Regular); Brush BrushInfo = Brushes.White; Pen PenInfo = new Pen(Brushes.White, 4); Graphics Graph = Graphics.FromImage(cameraCapture); //Graph.DrawRectangle(PenForFace, face.X, face.Y, face.Width, face.Height); //позиция отрисовки имени человека Point PointName = new Point(face.X, face.Y - 25); Graph.DrawString($"{UserName}", MyFont, BrushForFace, PointName); } /// /// получение данных с камеры и обработка изображени /// private void ProcessFrame() { try { BgrFrame = Capture.QueryFrame().ToImage().Flip(FlipType.Horizontal); } catch { return; } if (BgrFrame != null) { try {//for emgu cv bug Image grayframe = BgrFrame.Convert(); Rectangle[] faces = HaarCascade.DetectMultiScale(grayframe, 1.2, 10, new System.Drawing.Size(50, 50), new System.Drawing.Size(200, 200)); //detect face FaceName = "Лицо не обнаружено"; foreach (var face in faces) { BgrFrame.Draw(face, new Bgr(0, 0, 255), 2); DetectedFace = BgrFrame.Copy(face).Convert(); FaceRecognition(); break; } CameraCapture = BgrFrame.ToBitmap(); } catch (Exception ex) { //todo log } } } /// /// распознавание лица /// private void FaceRecognition() { if (ImageList.Size != 0) { FaceRecognizer.PredictionResult result = recognizer.Predict(DetectedFace.Resize(100, 100, Inter.Cubic)); FaceName = NameList[result.Label]; CurrentUserID = FaceList[result.Label].UserID; CameraCaptureFace = DetectedFace.ToBitmap(); } else { FaceName = "Пожалуйста добавьте лицо"; } } /// /// добавление лица в систему /// private void BtnAdd_Click(object sender, EventArgs e) { if (DetectedFace == null) { MessageBox.Show("Лица не обнаружены!\r\nУбедитесь что лицо находится в кадре и обведено красным прямоугольником.", "ImpulseVision", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } string PhotoPath = string.Empty; //ProgressOperation.Value = 10; //TslStatus.Text = "Добавление нового пользователя..."; bool Flag = TbxLastname.Text.Trim() == "" || TbxName.Text.Trim() == "" || TbxMaskPhone.Text.Trim() == "" || TbxMaskSnils.Text.Trim().Replace(" ","").Length < 11; if (Flag) { MessageBox.Show("Заполните все поля и повторите попытку!", "Ошибка добавления!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } SCon.Open(); string QueryCheckPassport = $@"select UserID from Users where Snils = '{TbxMaskSnils.Text.Trim()}'"; SqlCommand CmdCheck = new SqlCommand(QueryCheckPassport, SCon); SqlDataReader Res = CmdCheck.ExecuteReader(); if (Res.HasRows) { MessageBox.Show("Такой пользователь уже зарегистрирован в системе!", "FaceTrack", MessageBoxButtons.OK, MessageBoxIcon.Error); SCon.Close(); return; } SCon.Close(); //изменить размеры изображения DetectedFace = DetectedFace.Resize(100, 100, Inter.Cubic); //сохранить изображение в папку DetectedFace.Save(Config.FacePhotosPath + $"{TbxName.Text.Trim()}{TbxMaskSnils.Text.Trim()}" + Config.ImageFileExtension); PhotoPath = Config.FacePhotosPath + $"{TbxName.Text.Trim()}{TbxMaskSnils.Text.Trim()}" + Config.ImageFileExtension; //добавление пользователя в БД SCon.Open(); string QueryAdd = $@"insert into Users (Lastname,Firstname,Patronymic,Phone,Snils,Photo) values (@last,@first,@patr,@phone,@snils,@photo) "; SqlCommand Cmd = new SqlCommand(QueryAdd, SCon); Cmd.Parameters.AddWithValue("@last", TbxLastname.Text.Trim()); Cmd.Parameters.AddWithValue("@first", TbxName.Text.Trim()); Cmd.Parameters.AddWithValue("@patr", TbxPatronymic.Text.Trim()); Cmd.Parameters.AddWithValue("@phone", TbxMaskPhone.Text.Trim()); Cmd.Parameters.AddWithValue("@snils", TbxMaskSnils.Text.Trim()); Cmd.Parameters.AddWithValue("@photo", PhotoPath); Cmd.ExecuteNonQuery();//выполнить запрос SCon.Close(); MessageBox.Show("Успешно сохранено!", "FaceTrack", MessageBoxButtons.OK, MessageBoxIcon.Information); } /// /// получение данных об изображениях /// public void GetFacesList() { if (!File.Exists(Config.HaarCascadePath)) { string text = "Файл каскада Хаара не обнаружен:\n\n"; text += Config.HaarCascadePath; DialogResult result = MessageBox.Show(text, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } HaarCascade = new CascadeClassifier(Config.HaarCascadePath); FaceList.Clear(); // Создать директорию, если она отсутствовала if (!Directory.Exists(Config.FacePhotosPath)) { Directory.CreateDirectory(Config.FacePhotosPath); } // Тренировать изображения if (ImageList.Size > 0) { recognizer = new EigenFaceRecognizer(ImageList.Size); recognizer.Train(ImageList, LabelList); } } protected virtual void NotifyPropertyChanged([CallerMemberName] String propertyName = "") { var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } private void FormMain_Load(object sender, EventArgs e) { //скрытие заголовков вкладок в TabControl TabPages.Appearance = TabAppearance.FlatButtons; TabPages.ItemSize = new Size(0, 1); TabPages.SizeMode = TabSizeMode.Fixed; GetCams(); SetFormParameters(); TabPages.SelectTab(4); } private void PbxMenu_Click(object sender, EventArgs e) { IsMenuOpened = !IsMenuOpened; if(SplitContainer.Panel1.Width != 45) { SplitContainer.SplitterDistance = 45; PanHome.BackColor = Color.FromArgb(206, 208, 223); PanAdd.BackColor = Color.FromArgb(206, 208, 223); PanIdentification.BackColor = Color.FromArgb(206, 208, 223); PanJournal.BackColor = Color.FromArgb(206, 208, 223); PanSettings.BackColor = Color.FromArgb(206, 208, 223); } else { SplitContainer.SplitterDistance = 250; PanHome.BackColor = Color.FromArgb(58, 166, 64); PanAdd.BackColor = Color.FromArgb(58, 166, 64); PanIdentification.BackColor = Color.FromArgb(58, 166, 64); PanJournal.BackColor = Color.FromArgb(58, 166, 64); PanSettings.BackColor = Color.FromArgb(58, 166, 64); } } /// /// котроль размеров меню /// /// открыто меню или нет private void ControlSizeMenu(bool isMenuOpened) { if (isMenuOpened) { SplitContainer.SplitterDistance = 250; } else { SplitContainer.SplitterDistance = 45; } } private void FormMain_Resize(object sender, EventArgs e) { ControlSizeMenu(IsMenuOpened); } private void BtnMain_Click(object sender, EventArgs e) { Task.Factory.StartNew(() => { RecognizeOff(); }); TabPages.SelectTab(4); } private void BtnAddUser_Click(object sender, EventArgs e) { CaptureTimer = new Timer() { Interval = Config.TimerResponseValue }; CaptureTimer.Tick += CaptureTimer_Tick; if (ImageList.Size == 0) { GetFacesList(); } TabPages.SelectTab(0); Capture = new VideoCapture(SelectedCameraID); Capture.SetCaptureProperty(CapProp.Fps, 30); Capture.SetCaptureProperty(CapProp.FrameHeight, 450); Capture.SetCaptureProperty(CapProp.FrameWidth, 370); CaptureTimer.Start(); } private void BtnIdent_Click(object sender, EventArgs e) { CaptureTimerIdent = new Timer() { Interval = Config.TimerResponseValue }; CaptureTimerIdent.Tick += CaptureTimerIdent_Tick; GetFacesListForIdentification(); Capture = new VideoCapture(SelectedCameraID); //настройка кадров Capture.SetCaptureProperty(CapProp.Fps, 30); Capture.SetCaptureProperty(CapProp.FrameHeight, 450); Capture.SetCaptureProperty(CapProp.FrameWidth, 370); CaptureTimerIdent.Start(); TabPages.SelectTab(1); } /// /// отключение камеры и распознавания /// private void RecognizeOff() { if (BgrFrame != null) { if (Capture != null) { Capture.Dispose(); Capture = null; } //BgrFrame = null; if (CaptureTimer != null) { CaptureTimer.Enabled = false; } if(CaptureTimerIdent != null) { CaptureTimerIdent.Enabled = false; } } } private void CaptureTimerIdent_Tick(object sender, EventArgs e) { ProcessFrameIndentification(); } /// /// получение данных с камеры и распознавание /// private void ProcessFrameIndentification() { try { BgrFrame = Capture.QueryFrame().ToImage().Flip(FlipType.Horizontal); } catch { return; } if (BgrFrame != null) { try { Image grayframe = BgrFrame.Convert(); Rectangle[] faces = HaarCascade.DetectMultiScale(grayframe, 1.2, 10, new System.Drawing.Size(50, 50), new System.Drawing.Size(200, 200)); FaceName = "Лицо не обнаружено"; foreach (var face in faces) { CurrentFace = face; BgrFrame.Draw(face, new Bgr(53, 23, 247), 2); DetectedFace = BgrFrame.Copy(face).Convert(); FaceRecognition(); break; } CameraCapture = BgrFrame.ToBitmap(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } /// /// получение информации о пользователе и тренировка модели для распознавания /// private void GetFacesListForIdentification() { //файл Хаара if (!File.Exists(Config.HaarCascadePath)) { string text = "Не удаётся найти файл данных - каскад Хаара:\n\n"; text += Config.HaarCascadePath; DialogResult result = MessageBox.Show(text, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } HaarCascade = new CascadeClassifier(Config.HaarCascadePath); FaceList.Clear(); FaceData FaceItem = null; //создать папку для фото, если она отсутствовала if (!Directory.Exists(Config.FacePhotosPath)) { Directory.CreateDirectory(Config.FacePhotosPath); } //получить из БД инфо о пользователе (id, имя, фамилия, путь до фото) SCon.Open(); string QueryGetInfoAboutUser = $@"select UserID ,Users.Lastname, Users.Firstname, Users.Patronymic, Photo from Users"; SqlCommand Cmd = new SqlCommand(QueryGetInfoAboutUser, SCon); SqlDataReader Res = Cmd.ExecuteReader(); if (Res.HasRows) { while (Res.Read()) { try { FaceItem = new FaceData(); FaceItem.FaceImage = new Image(Application.StartupPath + "\\" + Res["Photo"].ToString()); FaceItem.PersonName = Res["Firstname"].ToString(); FaceItem.LastName = Res["Lastname"].ToString(); FaceItem.Patronymic = Res["Patronymic"].ToString(); FaceItem.UserID = Res["UserID"].ToString(); FaceList.Add(FaceItem); } catch (Exception ex) { MessageBox.Show(ex.Message, "FaceTrack", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } else { SCon.Close(); MessageBox.Show("Данные о пользователях отсутствуют!", "FaceTrack", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } SCon.Close(); int i = 0; foreach (var face in FaceList) { ImageList.Push(face.FaceImage.Mat); NameList.Add(face.PersonName + " " + face.LastName); LabelList.Push(new[] { i++ }); } // Тренировка модели if (ImageList.Size > 0) { recognizer = new EigenFaceRecognizer(ImageList.Size); recognizer.Train(ImageList, LabelList); } } private void BtnIn_Click(object sender, EventArgs e) { TypeOperation = 1; RegisterVisit(TypeOperation); } private void RegisterVisit(int typeOperation) { if (!IsRecognized) { MessageBox.Show("Убедитесь, что лицо находится в кадре и обведено красным прямоугольником!", "Ошибка распознавания!"); return; } if (typeOperation == 1) { #region Предупреждение при попытке повторной идентификации пользователя за один день SCon.Open(); string QueryCheckExistsVisit = $@"select Count(ID) as Cnt from Visits where UsersID = '{CurrentUserID}' and [Date] = CAST(GETDATE() as date)"; SqlCommand CmdCheckVisit = new SqlCommand(QueryCheckExistsVisit, SCon); SqlDataReader Res = CmdCheckVisit.ExecuteReader(); Res.Read(); int n = int.Parse(Res["Cnt"].ToString()); if (n >= 1) { MessageBox.Show("Сегодня данный пользователь уже прошёл идентификацию при входе!", "ImpulseVision", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); SCon.Close(); return; } SCon.Close(); #endregion //регистрация посещения SCon.Open(); string QueryAddVisit = $@"set dateformat dmy insert into Visits (UsersID,[Date],TimeEntrance) values ('{CurrentUserID}',CAST(GETDATE() as date),'{DateTime.Now.ToString("HH:mm:ss")}') "; SqlCommand Cmd = new SqlCommand(QueryAddVisit, SCon); Cmd.ExecuteNonQuery(); SCon.Close(); MessageBox.Show("Вход зарегистрирован!", "FaceTrack", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { SCon.Open(); string QueryCheckRecord = $@"set dateformat dmy select * from Visits where UsersID = '{CurrentUserID}' and [Date] = cast(GETDATE() as date) and TimeExit is null "; SqlCommand CmdCheck = new SqlCommand(QueryCheckRecord, SCon); SqlDataReader Res = CmdCheck.ExecuteReader(); if (!Res.HasRows) { MessageBox.Show("Данный пользователь уже вышел!", "ImpulseVision", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); SCon.Close(); return; } SCon.Close(); //!!! Выход пользователя, который не прошёл идентификацию не регистрируется SCon.Open(); string QueryTimeExit = $@"update Visits set TimeExit = '{DateTime.Now.ToString("HH:mm:ss")}' where UsersID = '{CurrentUserID}' and [Date] = cast(GETDATE() as date)"; SqlCommand Cmd = new SqlCommand(QueryTimeExit, SCon); Cmd.ExecuteNonQuery(); SCon.Close(); MessageBox.Show("Выход зарегистрирован!", "FaceTrack", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void BtnOut_Click(object sender, EventArgs e) { TypeOperation = 0; RegisterVisit(TypeOperation); } private void BtnJournal_Click(object sender, EventArgs e) { Task.Factory.StartNew(() => { RecognizeOff(); }); GetInformationAboutVisiting(); TabPages.SelectTab(2); } /// /// получение списка пользователей для журнала посещений /// private void GetInformationAboutVisiting() { DgbJournal.Rows.Clear(); SCon.Open(); string QueryGetVisits = $@"select UserID,Lastname +' '+Firstname+' '+Patronymic as FIO,(select MAX([Date]) from Visits where UsersID = Users.UserID) as LastDateVisit from Users "; if(TbxSearch.Text.Trim() != string.Empty) { QueryGetVisits += $@" where Lastname +' '+Firstname+' '+Patronymic like '%{TbxSearch.Text.Trim()}%'"; } SqlCommand CommandGetVisits = new SqlCommand(QueryGetVisits, SCon); SqlDataReader Res = CommandGetVisits.ExecuteReader(); if(Res.HasRows) { string DateTemplate = string.Empty; while(Res.Read()) { try { DateTemplate = DateTime.Parse(Res["LastDateVisit"].ToString()).ToString("dd.MM.yyyy"); } catch(Exception ex) { DateTemplate = "нет"; } DgbJournal.Rows.Add(Res["UserID"].ToString(), Res["FIO"].ToString(), DateTemplate); } } else { MessageBox.Show("Посещения пользователей отсутствуют!", "FaceTrack", MessageBoxButtons.OK, MessageBoxIcon.Error); SCon.Close(); return; } SCon.Close(); } private void DgbJournal_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { int RowIndex = e.RowIndex; int SelectedUserID = int.Parse(DgbJournal.Rows[RowIndex].Cells[0].Value.ToString()); string SelectedUserName = DgbJournal.Rows[RowIndex].Cells[1].Value.ToString(); FormVisiting FVisiting = new FormVisiting(SelectedUserID, SelectedUserName); this.Hide(); FVisiting.ShowDialog(); this.Show(); } private void BtnSettings_Click(object sender, EventArgs e) { Task.Factory.StartNew(() => { RecognizeOff(); }); GetCams(); TabPages.SelectTab(3); } /// /// получение списка доступных камер /// private void GetCams() { WebCams = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); CountCams = WebCams.Length; CmbCams.Items.Clear(); for (int i = 0; i < CountCams; i++) { CmbCams.Items.Add(WebCams[i].Name); HtBefore.Add(WebCams[i].Name); } if (CountCams == 0) { MessageBox.Show("Камеры не обнаружены! Подключите камеру и перезапустите приложение.","FaceTrack",MessageBoxButtons.OK,MessageBoxIcon.Error); this.Close(); } else { CmbCams.SelectedIndex = SelectedCameraID; } } /// /// обработка ситуации изменения количества подключённых камер /// private void CamsPreview() { DsDevice[] Cams = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); int CountCams = Cams.Length; if(CountCams != HtBefore.Count) { GetCams(); RecognizeOff(); if (TabPages.SelectedIndex == 0) { BtnAddUser_Click(null, null); } else if (TabPages.SelectedIndex == 1) { BtnIdent_Click(null, null); } Application.Restart(); } } private void PanelMenu_Paint(object sender, PaintEventArgs e) { Invalidate(); } private void FormMain_FormClosing(object sender, FormClosingEventArgs e) { ApplyNewParameters(); RecognizeOff(); Application.ExitThread(); } /// /// применение настроек для формы /// private void ApplyNewParameters() { LocalSettings LocalSet = new LocalSettings(); LocalSet.SelectedCameraID = SelectedCameraID; if (CbxSaveLocationForm.Checked) { LocalSet.PositionLocationX = this.Location.X; LocalSet.PositionLocationY = this.Location.Y; } else { LocalSet.PositionLocationX = -1; LocalSet.PositionLocationY = -1; } if (CbxSaveSizeForm.Checked) { LocalSet.FormWidth = this.Width; LocalSet.FormHeight = this.Height; } else { LocalSet.FormWidth = -1; LocalSet.FormHeight = -1; } StreamWriter Sw = new StreamWriter(Application.StartupPath + "\\localSettings.txt"); Sw.WriteLine(LocalSet.SelectedCameraID); Sw.WriteLine(LocalSet.FormWidth); Sw.WriteLine(LocalSet.FormHeight); Sw.WriteLine(LocalSet.PositionLocationX); Sw.WriteLine(LocalSet.PositionLocationY); Sw.Close(); } /// /// получение ранее схранённых параметров формы /// private void SetFormParameters() { if (!File.Exists(Application.StartupPath + "\\localSettings.txt")) { return; } StreamReader Sr = new StreamReader(Application.StartupPath + "\\localSettings.txt"); LocalSettings CurrentSettings = new LocalSettings(); CurrentSettings.SelectedCameraID = int.Parse(Sr.ReadLine()); CurrentSettings.FormWidth = int.Parse(Sr.ReadLine()); CurrentSettings.FormHeight = int.Parse(Sr.ReadLine()); CurrentSettings.PositionLocationX = int.Parse(Sr.ReadLine()); CurrentSettings.PositionLocationY = int.Parse(Sr.ReadLine()); Sr.Close(); CbxSaveLocationForm.Checked = false; CbxSaveSizeForm.Checked = false; SelectedCameraID = CurrentSettings.SelectedCameraID; try { CmbCams.SelectedIndex = SelectedCameraID; } catch { SelectedCameraID = 0; } if (CurrentSettings.FormWidth != -1 && CurrentSettings.FormHeight != -1) { CbxSaveSizeForm.Checked = true; this.Size = new Size(CurrentSettings.FormWidth, CurrentSettings.FormHeight); } if (CurrentSettings.PositionLocationX != -1 && CurrentSettings.PositionLocationY != -1) { CbxSaveLocationForm.Checked = true; this.Location = new Point(CurrentSettings.PositionLocationX, CurrentSettings.PositionLocationY); } } private void CmbCams_SelectedIndexChanged(object sender, EventArgs e) { SelectedCameraID = CmbCams.SelectedIndex; } private void BtnSaveParameters_Click(object sender, EventArgs e) { ApplyNewParameters(); MessageBox.Show("Выбранные параметры успешно применены!", "FaceTrack", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void TbxSearch_TextChanged(object sender, EventArgs e) { GetInformationAboutVisiting(); } private void TimerCamsControl_Tick(object sender, EventArgs e) { CamsPreview(); } private void LblLinkHelp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { if (!File.Exists(Application.StartupPath + "\\Source\\help.chm")) { MessageBox.Show("В данный момент времени справочная система приложения недоступна!", "Внимание!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } System.Diagnostics.Process.Start(Application.StartupPath + "\\Source\\help.chm"); } private void label6_Click(object sender, EventArgs e) { } private void label8_Click(object sender, EventArgs e) { } private void label9_Click(object sender, EventArgs e) { } private void label10_Click(object sender, EventArgs e) { } } }