Pull to refresh
33
0
Andrey Helldar @Helldar

Senior PHP Developer

Send message
Это в примере код пустой, а так там обработчик стоит, у которого принцип работы довольно прост: передаем 3 переменные, 1-я из которых является текстовой строкой функции, вторая местом вызова (так как в функции может быть несколько обработчиков) и третья — текст ошибки.
Все это дело сохраняется в файл и по завершении работы программы архивируется. Архив в последствии пользователь может сам передать разработчику, так как функции автоматической отправки я не делал.
Действительно, у меня были кривые руки. В комментарии ниже приведен пример рабочего кода.
Я б плюс поставил, да кармы мало.
Спасибо за объяснение!
Просто от пользователя не пробовал. Я админ в системе и являюсь одной учетной записью на компе (из числа вручную созданных) при установке ОС.
Попробую сегодня запустить под обычным юзером на другой машине, сообщу о результатах.
Озвученная Вами проблема является актуальной, так как не так давно каким-то случайным образом в 3 часа ночи я умудрился добавить символ лишний в путь файла на сайте для скачивания обновлений, в следствие чего, несколько тестеров не смогли обновиться и запрашивали у меня ссылку для ручного обновления.

И здесь мне пришла мысль о том, что если ПО не может скачать файл исполняемой программы, то она будет выводить уведомление об этом (не каждый раз, а, скажем, раз в 5 дней) и открывать прямую (или не прямую) ссылку в браузере для скачивания данного файла.

А прочитав Ваш комментарий, возникло желание добавить функцию резервного обновления по следующему принципу:
— Основной апдейтер полностью вынести во внешний файл (как писалось в других комментариях не раз), а в теле основной программы оставить функцию резервного обновления.
Таким образом можно решить проблему с некорректным обновлением.
Спасибо на добром слове!
«Ученье — свет, а неученье — чуть свет и на работу» (с)
Ага! Вот где собака зарыта! Теперь понял для чего такие различия. Спасибо за подробное объяснение!
В таком разе логично предположить, что и созданные разработчиком функции также могут начинаться с маленькой буквы.
Я хоть и новичок в этой среде, но уже успел понять, что неважно с какой буквы функция начинается, главное — чтобы она при вызове была 1 в 1 с названием.

А раз функция, начинающаяся с маленькой буквы, работает, то и ее можно отнести к исключениям?
Нашел свою кривость рук!

Вот так код работает стабильно:

private bool Checksumm(string filename, string summ)
{
	using (FileStream fs = File.OpenRead(filename))
	{
		System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
		byte[] fileData = new byte[fs.Length];
		fs.Read(fileData, 0, (int)fs.Length);
		byte[] checkSumm = md5.ComputeHash(fileData);
		return BitConverter.ToString(checkSumm).Replace("-", String.Empty) == (summ).ToUpper() ? true : false;
	}
}
В таком случае не пойму почему обработчик на ту же кнопку выглядит так:
private void button1_Click(object sender, EventArgs e) { }

С маленькой же буквы начинается…

Исходя из этого могу предположить, что в документации лишь рекомендуемые понятия, а не принудительно выполняемые.
Правда, код в данной статье до вчерашней правки. После правки некоторая его часть выглядит так
Мсье, Вы сильно удивитесь…
Windows 7 x64. Скопировал файл в папку «c:\Program Files\myProgram\» — запустил.
Прога скачала все необходимые библиотеки с сайта, перезапустилась, нашла обновление — скачала, предложила обновиться — согласился. Обновилась, перезапустилась…
… ни единой ошибки! :)
Вестимо, был не прав? Я угадал?

Раз так, то и нижеприведенную функцию оцените, если желание будет:

        private bool checksum(string filename, string summ)
        {
            try
            {
                using (var md5 = MD5.Create())
                {
                    using (var stream = File.OpenRead(filename))
                    {
                        return md5.ComputeHash(stream).ToString() == summ ? true : false;
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

В параметре функции передается имя файла, для которого необходимо посчитать CRC-сумму, а во втором контрольная сумма, полученная с сайта (размещена в файле version.xml как дополнительный аттрибут).
Суть проста — считываем CRC-сумму файла и сравниваем ее с полученной с сайта. Если суммы совпадают, выводится true, если нет — false.
Вот только проблема в том, что сумма рассчитывается как-то не так — еще ни разу она не совпала. Уже голову сломал в чем проблема…
На сайте файл хранится под именем launcher.exe, локально — launcher.update.
Пробовал локально посчитать суммы обоих файлов — они одинаковы. Уже голова не варит что может быть. Может, подопнете в нужном направлении? Буду рад :)
Мне тоже так кажется, и вылезают лишь посмеяться над другими да вернуться обратно дебажить свой код. :)
На мой взгляд ничего плохого в нем нет, если он, так сказать, «к месту».
Излишнее его использование, согласен, вредит. А если в меру, то почему бы и нет?

Поэтому соглашусь что использование QR-кода в качестве дополнительной ссылки для не людей устройств — это есть хорошо.
Совсем не стыдно.

При поиске информации очень часто добавляют язык C# в запросе, дабы найти нужное и, поверьте, если ввести в любом поисковике запрос «автоматическое обновление C#», то вряд ли человек будет иметь ввиду Windows Phone.

Кто сказал, что самостоятельно придуманные методы начинаются с большой буквы? Это все глупый стереотип! Как метод ни назови — главное, чтобы он вызывался. Вот если бы в одном месте было написано «download», а в другом — «Download», тогда да, а в данном случае не пойму почём звон.

И по Вашему комментарию в целом: Вы сможете лучше? Примеры приведете? Думаю, многие были бы рады взглянуть на мастер-класс от профи…

P.S.: Если бы данный код был абсолютно совершенен, то вряд ли я стал его выкладывать на всеобщее…
Не ради кармы пишу статьи, а с целью донести информацию до начинающих пользователей, не исключая комментирование более опытных.
По поводу использования описанного метода в других приложениях, можно сам код апдейтера полностью вынести во внешний файл и, для универсальности, при запуске добавлять параметры где лежат обновления и какой файл заменять.
Часть проблем описал потому, что именно на них акцентировали внимание комментарии, некоторые же проблемы (вроде предложения BITS, windows installer и ClickOnce) нецелесообразны в моем проекте.
Да, возможно при создании универсального кода они найдут место, но, ведь, пример-то не на универсальность мной приводился, а на наглядное представление принципа автоматического обновления ПО.
Метод проверки целостности файла довольно примитивен: берем файл и считываем из него версию, если файл поврежден — это неизбежно вызовет ошибку. Легко и просто, нежели добавлять дополнительный код проверки CRC-суммы. Во всяком случае, в моем проекте нет нужды использовать более сложные методы, а так да, Вы правы, нужно использовать проверку контрольной суммы.
Здесь уже зависит от назначения самой программы — где-то уместно будет использовать сторонний апдейтер, а где-то — нет

так же желательно чтобы была возможность вообще отключить обновления.

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

По «в-третьих» — CRC-код добавлял, но либо у меня руки кривые, либо одно из двух — суммы не совпадают. Над этим вариантом я еще думаю где ошибка.
Это полезно при самостоятельном проекте.
Если приложение используется как вторичное, то само устанавливаться оно не будет, вот и используются вышеописанные методы.
В любом случае, любому новичку, я так думаю, данный пример пригодится.
Можно, но не особо нужно. В любом случае пользователь не сможет сам воспользоваться updater.exe, так как он работает только с определенным набором параметров (указаны в статье). Так что в конкретно моем случае размещение файла updater.exe вне ресурсов основной программы является оптимальным решение.

Information

Rating
4,853-rd
Location
Россия
Date of birth
Registered
Activity

Specialization

Backend Developer
Lead
From 350,000 ₽
PHP
MySQL
Git
OOP
Docker
Redis
SQL
Laravel
Elasticsearch