/// <summary> /// Проверить неоходимость обновления и скачать обновление программы. /// Обновление работает так: /// Для того чтобы скачать обновление и обновиться нужно обновление закачать на сервер. /// Обновление exe файлов и других файлов клиента возможно только из рабочей базы данных. /// Обновление из файловой шары или из ресурса в интернете не сделано. /// Закачивает обновление на сервер программа Utility.exe. /// В её коде присаны все файлы, папки, которые нужно закачать на сервер. /// Там же указывается список папок или файлов, котороые подлежат удалению. /// Все файлы закачиваются на сервер в табличку fbaUpdate. В обновлении участвует только одна табличка. /// После этого при запуске Клиент обращается к этой табличку и смотрит, есть ли обновление (проверка по полю Version и CurrentVersion) /// Сравниваеся с текущей версии EXE файла. Если обновить нужно, то все файлы скачиваются клиентом в папку Update, предназначенную для этого. /// Перед скачиванием папка Update очищается полностью. /// Далее клиент запускает файл Updater.exe передавая в параметрах свое имя файла, а сам завершает работу. /// Updater.exe полностью независимый EXE, он независит от других файлов программы. Updater.exe заменяет файлы программы файлами из папки Update, /// Если при копировании происходит ошибка, то он пытается вернуть прежние версии файлов. После копирования он запускает EXE файл, /// имя которого было передано в параметрах, а сам завершает работу. /// Download - true - скачать файлы обновления, false - только получить данные об обновлении. /// ResultUpdate - описание выполненых действий. /// </summary> /// <param name="version"></param> /// <param name="numberUpdate"></param> /// <param name="resultMessage"></param> /// <param name="needUpdate"></param> /// <param name="showMes">false - тихий режим, сообщений пользователю не выдаем. </param> /// <returns>Результат - true - требуется обновить, false - обновление не требуется.</returns> public static bool UpdateDownload(string version, string numberUpdate, out string resultMessage, out bool needUpdate, bool showMes) { resultMessage = ""; DataTable dT1; DataTable dT2; string sqlLocal; long fileSize = 0; var fileCount = 0; var listDelete = new List <string>(); string[] listNotDeleted; //Очищаем полность папку sys.PathUpdate. if (!FBAFile.DirClean(FBAPath.PathUpdate, out listNotDeleted, true)) { needUpdate = false; return(false); } sqlLocal = "select ID, MD5, Path, FullName, ContentType, Operation, Size from fbaUpdate WHERE Version = '" + version + "' ORDER BY Numberupdate, Numberfile; "; sys.SelectDT(DirectionQuery.Remote, sqlLocal, out dT1); if (dT1.Rows.Count == 0) { resultMessage = ""; //Ошибка обновления. Не удается найти последниюю версию приложения!"; needUpdate = false; return(false); } var progress = new FormProgress("Обновление программы", "Получение файлов для обновления", dT1.Rows.Count); if (showMes) { progress.Show(); } for (var i = 0; i < dT1.Rows.Count; i++) { var id = dT1.Value(i, "ID"); var md5Update = dT1.Value(i, "MD5"); var pathValue = dT1.Value(i, "Path"); var fullName = dT1.Value(i, "FullName"); var contentType = dT1.Value(i, "ContentType"); var operationL = dT1.Value(i, "Operation"); var size = dT1.Value(i, "Size"); var fileNameLocal = fullName.Replace(pathValue, FBAPath.PathMain); var FileNameUpdate = fullName.Replace(pathValue, FBAPath.PathUpdate); if (operationL == "DELFILE" || operationL == "DELDIR") { listDelete.Add(operationL + ": " + fullName); } if (operationL == "ADDDIR") { Directory.CreateDirectory(Path.GetDirectoryName(FileNameUpdate)); } if (operationL == "ADDFILE") { var MD5Local = Crypto.FileHashMD5Calc(fileNameLocal); //MD5 локального файла. var MD5Download = Crypto.FileHashMD5Calc(FileNameUpdate); //MD5 уже скаченного ранее файла. //Если рабочий файл не совпадает с обновлением: if (md5Update != MD5Local) { fileSize = fileSize + Convert.ToInt64(size); fileCount = fileCount + 1; //Если MD5 не совпадает между локальным файлом и файлом для обновления, то скачиваем файл. sqlLocal = "SELECT FileData FROM fbaUpdate WHERE ID = " + id; sys.SelectDT(DirectionQuery.Remote, sqlLocal, out dT2); var FileData = dT2.Value("FileData"); Directory.CreateDirectory(Path.GetDirectoryName(FileNameUpdate)); if (!FBAFile.FileWriteFromBase64(FileData, FileNameUpdate, out resultMessage, showMes)) { resultMessage = "Ошибка обновления. Не удается найти последниюю версию приложения!" + Var.CR + resultMessage; needUpdate = false; return(false); } } } if (listDelete.Count > 0) { //Просто сохраняем в список то, что нужно удалить. var fileName = FBAPath.PathUpdate + "ListDelete.txt"; var listStr = string.Join(Var.CR, listDelete.ToArray()); File.WriteAllText(fileName, listStr, Encoding.Default); } if (showMes) { progress.Inc(); } } progress.Dispose(); if (fileCount == 0 && listDelete.Count == 0) { resultMessage = "Обновление не требуется. Все текущие версии файлов совпадают с файлами обновления " + version; needUpdate = false; return(true); } //Если нужно только удалить папки или файлы, то ставим размер обновления 1 кб, //чтобы не пугать пользователя. if (fileSize == 0) { fileSize = 1024; } var ResStr = "Порядковый номер обновления: " + numberUpdate + Var.CR + "Версия: " + version + Var.CR + "Размер обновления: " + FBAFile.GetFileSizeStr(fileSize, true, true) + Var.CR + "Количество файлов и папок: " + (fileCount + listDelete.Count) + Var.CR + "Текущая версия программы: " + Var.ApplicationVersion; resultMessage = "Файлы для обновления скачаны и готовы для установки." + Var.CR + ResStr; needUpdate = true; return(true); //true - обновлять нужно, false - обновление не требуется. }
//Показывает список доступных обновлений. //Сохранить все файлы программы на сервере. // //UserUpdate - обновление доступно пользователям. //Upload - Загрузить файлы на сервер. //ContentList - Cписок файлов и папок для обновления в определенном формате: // ADDDIR: CustomDorectoryName // DELDIR: CustomDorectoryName // ADDFILE: CustomFileName.txt // DELFILE: CustomFileName.txt /// <summary> /// /// </summary> /// <param name="dt"></param> /// <param name="contentList"></param> /// <param name="doUserUpdate"></param> /// <param name="uploadToServer"></param> /// <returns></returns> private bool UpdateUploadFiles(out System.Data.DataTable dt, string[] contentList, bool doUserUpdate, bool uploadToServer) { dt = new System.Data.DataTable(); string sql = ""; //Для вставки полей в DT. string numberFile; int numberUpdate; string dateRecord = sys.DateTimeToSQLStr(DateTime.Now); string userUpdate = (!doUserUpdate).ToInt().ToString(); string contentType = ""; string operation = ""; string version = Var.ApplicationVersion; string fullName = ""; string path = FBAPath.PathMain; string fileName = ""; string extension = ""; string creationTime; string lastWriteTime; string lastAccessTime; long SizeFile; string hashMD5; string fileData = ""; //Данные в Base64. //Последняя версия в таблице обновлений. sql = "SELECT MAX(NumberUpdate) AS NumberVersion FROM fbaUpdate; "; string NumberUpdateStr = sys.GetValue(DirectionQuery.Remote, sql); if (NumberUpdateStr == "") { NumberUpdateStr = "0"; } numberUpdate = NumberUpdateStr.ToInt() + 1; //Новая варсия. bool ff = true; Type tp = ff.GetType(); dt.Columns.Add("Check", tp); //Выбрать файл для заливки dt.Columns.Add("NumberFile"); //Порядковый номер файла или папки в обновлении dt.Columns.Add("NumberUpdate"); //Порядковый номер обновления. dt.Columns.Add("DateRecord"); //Текущая дата. dt.Columns.Add("UserUpdate"); //true-Пользователям нужно обновляться из это обновления. false-не нужно. false-нужно для тестирования, для отложенного обновления и др. dt.Columns.Add("ContentType"); //1-папка, 2-файл dt.Columns.Add("Operation"); //1-создать, 2-удалить. dt.Columns.Add("Version"); //Версия программы вида 1.0.6335.33362 dt.Columns.Add("FullName"); //Полное имя файла с путем. dt.Columns.Add("Path"); //Начальный каталог программы, т.е. sys.PathMain dt.Columns.Add("Name"); //Имя файла/папки dt.Columns.Add("Extension"); //Расширение файла (для папки здесь пусто) dt.Columns.Add("CreationTime"); //Дата создания папки/файла dt.Columns.Add("LastWriteTime"); dt.Columns.Add("LastAccessTime"); dt.Columns.Add("Size"); //размер файла в байтах. Для папки здесь 0. dt.Columns.Add("MD5"); //Хеш MD5 //DT.Columns.Add("FileData"); //Содержимое файла в кодировке Base64. sql = "DELETE FROM fbaUpdate WHERE Version = '" + version + "'; "; if (!sys.Exec(DirectionQuery.Remote, sql)) { return(false); } var fileprop = new string[16]; var progress1 = new FormProgress("Обновление", "Получение свойств файлов", contentList.Length); progress1.Show(); for (int i = 0; i < contentList.Length; i++) { fullName = contentList[i]; numberFile = (i + 1).ToString(); if (!File.Exists(fileName)) { continue; } var file = new FileInfo(fullName); fileName = file.Name; extension = file.Extension; creationTime = sys.DateTimeToSQLStr(file.CreationTime); lastWriteTime = sys.DateTimeToSQLStr(file.LastWriteTime); lastAccessTime = sys.DateTimeToSQLStr(file.LastAccessTime); SizeFile = file.Length; hashMD5 = Crypto.FileHashMD5Calc(fullName); fileprop[0] = numberFile; fileprop[1] = numberUpdate.ToString(); fileprop[2] = dateRecord; fileprop[3] = userUpdate; fileprop[4] = ""; //ContentType.ToString(); fileprop[5] = ""; //Operation.ToString(); fileprop[6] = version; fileprop[7] = fullName; fileprop[8] = path; fileprop[9] = fileName; fileprop[10] = extension; fileprop[11] = creationTime; fileprop[12] = lastWriteTime; fileprop[13] = lastAccessTime; fileprop[14] = SizeFile.ToString(); fileprop[15] = hashMD5; DataRow row = dt.NewRow(); row.ItemArray = fileprop; dt.Rows.Add(row); if (uploadToServer) { fileData = ""; string errorMes; const bool showMes = true; if (!FBAFile.FileReadToBase64(fullName, out fileData, out errorMes, showMes)) { return(false); } const bool saveHashToEndFile = false; if (!FBAFile.FileGetBase64WithHashMD5(fileName, saveHashToEndFile, out fileData, out hashMD5)) { return(false); } sql = @"INSERT INTO fbaUpdate (NumberFile, NumberUpdate, DateRecord, UserUpdate, " + "ContentType, Operation, Version, CurrentVersion, FullName, Path, Name, Extension, " + "CreationTime, LastWriteTime, LastAccessTime, Size, MD5, " + "FileData) " + "VALUES (" + "'" + numberFile + "','" + numberUpdate + "','" + dateRecord + "','" + userUpdate + "'," + "'" + contentType + "','" + operation + "','" + version + "','" + version + "','" + fullName + "','" + path + "','" + fileName + "','" + extension + "'," + "'" + creationTime + "','" + lastWriteTime + "','" + lastAccessTime + "'," + SizeFile.ToString() + ", '" + hashMD5 + "'," + "'" + fileData + "'); " + Var.CR; if (!sys.Exec(DirectionQuery.Remote, sql)) { return(false); } } progress1.Inc(); } //В конце загрузки файлов на сервер обновляем информцию о текущей версии. if (uploadToServer) { sql = @"UPDATE fbaUpdate SET CurrentVersion = '" + version + "'; " + Var.CR; if (!sys.Exec(DirectionQuery.Remote, sql)) { return(false); } } progress1.Dispose(); return(true); }
/// <summary> /// Получить список файлов решения /// </summary> /// <returns></returns> private bool GetFilesFBA() { //Последняя версия в таблице обновлений. int numberUpdate = GetLastUpdate() + 1; //Новая версия. if (dt.Columns.Count == 0) { dt.Columns.Add("NumberFile"); //Порядковый номер файла или папки в обновлении dt.Columns.Add("NumberUpdate"); //Порядковый номер обновления. dt.Columns.Add("Version"); //Версия программы вида 1.0.6335.33362 dt.Columns.Add("FullName"); //Полное имя файла с путем. dt.Columns.Add("Path"); //Начальный каталог программы, т.е. sys.PathMain dt.Columns.Add("Name"); //Имя файла/папки dt.Columns.Add("Extension"); //Расширение файла (для папки здесь пусто) dt.Columns.Add("CreationTime"); //Дата создания папки/файла dt.Columns.Add("LastWriteTime"); dt.Columns.Add("LastAccessTime"); dt.Columns.Add("Size"); //размер файла в байтах. Для папки здесь 0. dt.Columns.Add("MD5"); //Хеш MD5 } dt.Rows.Clear(); string[] contentList = FBAFile.FilesInFolder(FBAPath.PathDebug, "*.*", "", "", true, true, true);; //Для вставки полей в DT. string numberFile = ""; string dateRecord = sys.DateTimeToSQLStr(DateTime.Now); string version = Var.ApplicationVersion; string fullName = ""; string filePath = ""; string fileName = ""; string extension = ""; string creationTime = ""; string lastWriteTime = ""; string lastAccessTime = ""; long SizeFile; string hashMD5; var progress1 = new FormProgress("Обновление", "Получение свойств файлов", contentList.Length); progress1.Show(); var fileprop = new string[dt.Columns.Count]; for (int i = 0; i < contentList.Length; i++) { try { fullName = contentList[i]; if (string.IsNullOrEmpty(fullName)) { continue; } if (!File.Exists(fullName)) { continue; } var file = new FileInfo(fullName); filePath = file.DirectoryName; fileName = file.Name; numberFile = (i + 1).ToString(); extension = file.Extension; creationTime = sys.DateTimeToSQLStr(file.CreationTime); lastWriteTime = sys.DateTimeToSQLStr(file.LastWriteTime); lastAccessTime = sys.DateTimeToSQLStr(file.LastAccessTime); SizeFile = file.Length; hashMD5 = Crypto.FileHashMD5Calc(fullName); fileprop[0] = numberFile; fileprop[1] = numberUpdate.ToString(); fileprop[2] = version; fileprop[3] = fullName; fileprop[4] = filePath;; fileprop[5] = fileName; fileprop[6] = extension; fileprop[7] = creationTime; fileprop[8] = lastWriteTime; fileprop[9] = lastAccessTime; fileprop[10] = SizeFile.ToString(); fileprop[11] = hashMD5; DataRow row = dt.NewRow(); row.ItemArray = fileprop; dt.Rows.Add(row); progress1.Inc(); } catch (Exception ex) { sys.SM("File Number " + numberFile + Var.CR + "File name: " + fullName + Var.CR + ex.Message); continue; } } const bool ff = true; Type tp = ff.GetType(); dt.Columns.Add("Check", tp); //Выбрать файл для заливки dt.Columns["Check"].SetOrdinal(0); CheckFiles(false); //dt.Columns[0].DataType = tp; progress1.Close(); return(true); }
/// <summary> /// Загрузка обновления на сервер. /// </summary> /// <returns></returns> private bool UploadNewUpdate() { string version = dt.Value("Version"); if (!DeleteUpdate(version)) { return(false); } string fileName = ""; string sql = ""; var progress1 = new FormProgress("Обновление", "Загрузка файлов обновления на сервер", dt.Rows.Count); progress1.Show(); for (int i = 0; i < dt.Rows.Count; i++) { try { string fullName = dt.Value(i, "FullName"); if (!File.Exists(fullName)) { continue; } string fileData; string errorMes; const bool showMes = true; bool check = dt.Value(i, 0).ToBool(); if (!check) { continue; } string numberFile = progress1.Progress.ToString(); string numberUpdate = dt.Value(i, "NumberUpdate"); string dateRecord = sys.GetDateTimeNow(); string userUpdate = Var.UserID.ToString(); const string contentType = ""; const string operation = ""; string path = dt.Value(i, "Path"); fileName = dt.Value(i, "Name"); string extension = dt.Value(i, "Extension"); string creationTime = dt.Value(i, "CreationTime"); string lastWriteTime = dt.Value(i, "LastWriteTime"); string lastAccessTime = dt.Value(i, "LastAccessTime"); string sizeFile = dt.Value(i, "Size"); string hashMD5 = dt.Value(i, "MD5"); if (!FBAFile.FileReadToBase64(fullName, out fileData, out errorMes, showMes)) { return(false); } sql = @"INSERT INTO fbaUpdate (NumberFile, NumberUpdate, DateRecord, UserUpdate, " + "ContentType, Operation, Version, CurrentVersion, FullName, Path, Name, Extension, " + "CreationTime, LastWriteTime, LastAccessTime, Size, MD5, " + "FileData) " + "VALUES (" + "'" + numberFile + "','" + numberUpdate + "','" + dateRecord + "','" + userUpdate + "'," + "'" + contentType + "','" + operation + "','" + version + "','" + version + "','" + fullName + "','" + path + "','" + fileName + "','" + extension + "'," + "'" + creationTime + "','" + lastWriteTime + "','" + lastAccessTime + "'," + sizeFile.ToString() + ", '" + hashMD5 + "'," + "'" + fileData + "'); " + Var.CR; if (!sys.Exec(DirectionQuery.Remote, sql)) { return(false); } } catch (Exception ex) { sys.SM("Ошибка загрузки файла обновления: " + Var.CR + fileName + Var.CR + ex.Message); } progress1.Inc(); } //В конце загрузки файлов на сервер обновляем информцию о текущей версии. sql = @"UPDATE fbaUpdate SET CurrentVersion = '" + version + "'; " + Var.CR; if (!sys.Exec(DirectionQuery.Remote, sql)) { return(false); } progress1.Dispose(); return(true); }
///Вместо button1.PerformClick(); private void Action(CommandType commandType) { if (commandType == CommandType.Ok) { Close(); } if (commandType == CommandType.Filter) { if (!FormFilter.Filter( this, listParams.EntityBrief, grid1.Left, grid1.Top, ref filter, listParams.OuterWHERE )) { FilterSet = false; return; } FilterSet = true; RefreshGridForm(DirectionQuery.Remote, grid1, filter); } if (commandType == CommandType.ExecSQL) { FilterSet = false; filter.FullQuerySQL = listParams.СustomSQLQuery; RefreshGridForm(DirectionQuery.Remote, grid1, filter); } if (commandType == CommandType.ExecMSQL) { FilterSet = false; filter.FullQuerySQL = sys.Parse(listParams.СustomMSQLQuery); RefreshGridForm(DirectionQuery.Remote, grid1, filter); } if (commandType == CommandType.Refresh) { RefreshGridForm(DirectionQuery.Remote, grid1, filter); } if (commandType == CommandType.Add) { EditObject(""); } if (commandType == CommandType.Edit) { this.listParams.ObjectID = grid1.Value(0, true); if (listParams.DoubleClickReturn) { Close(); } //показываем форму свойств выбранного объекта. EditObject(this.listParams.ObjectID); } if (commandType == CommandType.Del) { int countDeleted = 0; string objectCaption = ""; string[] arrID = grid1.GetSelectedValues(0, true); if (arrID == null) { return; } if (arrID.Length == 0) { return; } string entityName = sys.GetEntityName("", listParams.EntityBrief); if (entityName != "") { objectCaption = entityName; } if (arrID.Length == 1) { objectCaption = objectCaption + " ИД Объекта " + arrID[0]; } else { objectCaption = objectCaption = objectCaption + " Всего объектов " + arrID.Length.ToString(); } if (!sys.SM("Вы действительно ходите удалить " + objectCaption, MessageType.Question)) { return; } if (arrID.Length == 1) { objectCaption = "'" + entityName + "'. ИД Объекта " + arrID[0]; var Obj = new FBA.ObjectRef(); if (!Obj.DeleteObject(DirectionQuery.Remote, "Contract", arrID[0])) { return; } countDeleted = 1; sys.SM(objectCaption + " удален", MessageType.Information); } if (arrID.Length > 1) { var progress1 = new FormProgress("Удаление", "Удаление объектов" + entityName, arrID.Length); progress1.Show(); for (int i = 0; i < arrID.Length; i++) { objectCaption = "'" + entityName + "'. ИД Объекта " + arrID[i]; var Obj = new FBA.ObjectRef(); if (!Obj.DeleteObject(DirectionQuery.Remote, "Contract", arrID[i])) { return; } countDeleted++; progress1.Inc(); } progress1.Dispose(); if (countDeleted == arrID.Length) { objectCaption = "Все объекты " + entityName + " удалены. Всего: " + countDeleted; sys.SM(objectCaption, MessageType.Information); } if (countDeleted < arrID.Length) { objectCaption = "Объекты " + entityName + " удалены. Всего: " + countDeleted + " из " + arrID.Length.ToString(); sys.SM(objectCaption, MessageType.Warning); } if (countDeleted == 0) { objectCaption = "Объекты " + entityName + " удалены не были."; sys.SM(objectCaption); } if (countDeleted > 0) { if (sys.SM("Обновить содержимое справочника " + entityName + "?", MessageType.Question)) { RefreshGridForm(DirectionQuery.Remote, grid1, filter); } } ; } } if (commandType == CommandType.ShowSQL) { sys.SM(filter.FullQuerySQL, MessageType.Information); } if (commandType == CommandType.ShowMSQL) { sys.SM(filter.FullQueryMSQL, MessageType.Information); } if (commandType == CommandType.Details) { grid1.GridInformation(); } if (commandType == CommandType.ExportToExcel) { grid1.SourceGridToExcel(); } if (commandType == CommandType.ExportToCSV) { grid1.SourceGridToCSV(); } if (commandType == CommandType.Search) { dtSearch = FormSearch.FormSearchShow(this.Name, null, grid1); } if (commandType == CommandType.Copy) { grid1.CopyRegion(false, false); } if (commandType == CommandType.CopyAll) { grid1.CopyRegion(true, true); } if (commandType == CommandType.CopyWithCaptions) { grid1.CopyRegion(true, false); } //if (Operation == "Copy") //{ // string Value = sys.GetValueByColumnIndex(DG2, -1, true); // Value.CopyToClipboard(); //} if (commandType == CommandType.SelectAll) { SourceGridSelectAll(grid1); //DG2.SelectAll()); } if (commandType == CommandType.SelectRows) { SourceGridSelectRows(grid1); } if (commandType == CommandType.SelectColumns) { SourceGridSelectColumns(grid1); } if (commandType == CommandType.SelectionModeCell) { SetSelectionMode(SourceGrid.GridSelectionMode.Cell); } if (commandType == CommandType.SelectionModeRow) { SetSelectionMode(SourceGrid.GridSelectionMode.Row); } if (commandType == CommandType.SelectionModeColumn) { SetSelectionMode(SourceGrid.GridSelectionMode.Column); } if (commandType == CommandType.Cancel) { this.listParams.ObjectID = ""; this.Close(); } //Копирование ссылок на выделенные документы. if (commandType == CommandType.CopyDocumentLink) { var links = new StringBuilder(); string[] arrID = grid1.GetSelectedValues(0, true); if (arrID.Length == 0) { return; } for (int i = 0; i < arrID.Length; i++) { links.Append("FBALink.Entity:" + listParams.EntityBrief + ",ObjectID:" + arrID[i] + Var.CR); } links.ToString().CopyToClipboard(); } }