Время прочтения: 3 мин.
Для начала я создал мини установщик и направил его по Outlook коллегам.
Вся его работа сводилась к тому, что в его ресурсы сначала были загружены все файлы основного приложения, затем по указанному пути установщик копировал эти файлы и создавал заодно ярлыки на рабочем столе и в автозапуске.
private void button1_Click(object sender, EventArgs e)
{
try
{
path= textBox1.Text.Replace(@"\\",@"\");
richTextBox1.SelectedText = ("Создаю пути \n");
richTextBox1.SelectedText = ("_____________________________\n");
Directory.CreateDirectory(path); richTextBox1.SelectedText = ("Вставляю файлы \n");
richTextBox1.SelectedText = ("_____________________________ \n");
System.IO.File.WriteAllBytes(path + @"\Microsoft.Exchange.WebServices.dll", Установщик_Задачника.Properties.Resources.WebServices);
System.IO.File.WriteAllBytes(path + @"\Задачник.exe", Установщик_Задачника.Properties.Resources.Задачник);
System.IO.File.WriteAllText(path + @"\Задачник.exe.config", Установщик_Задачника.Properties.Resources.conf);
WshShell shell = new WshShell();
IWshShortcut shortcut = shell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Задачник.lnk");
shortcut.TargetPath = path + "\\Задачник.exe";
shortcut.Save();
if (checkBox1.Checked)
{
shortcut = shell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.Startup) + "\\Задачник.lnk");
shortcut.TargetPath = path + "\\Задачник.exe";
shortcut.Save();
}
try { System.Diagnostics.Process.Start(path + "\\Задачник"); }
catch { System.Diagnostics.Process.Start(path + "\\Задачник.exe"); }
MessageBox.Show("Закончил. После этого сообщения я закроюсь и меня можно удалить\n");
this.Close();
}
catch { MessageBox.Show("Невозможно установить программу по этому пути. \n попройбуйте указать другой путь."); };
}
Когда вносились какие-либо изменения в основное приложение, в установщике приходилось перезаписывать resources и снова отправлять по почте данный установщик коллегам.
Соответственно, я начал придумывать варианты по распространению без оповещения на почту и просьбами переустановить.
Так как в распоряжении была только БД, с которой брал данные, я решил просто создать таблицу, в которой хранился бы номер актуальной версии приложения, и так же само приложение в bin.
Как результат этой идеи, появилась маленькая программка.
Которая из exe делала bin
private void button2_Click(object sender, EventArgs e)
{
byte[] exe = File.ReadAllBytes(textBox1.Text);
File.WriteAllBytes("Задачник.bin", exe);
MessageBox.Show("ok");
}
и заливала в таблицу
private void button5_Click(object sender, EventArgs e)
{
byte[] bt = File.ReadAllBytes(AppDomain.CurrentDomain.BaseDirectory + "Задачник.bin");
SqlConnection connection = new SqlConnection("Data Source= Source \\prometheus ; Initial Catalog=SQL_TB42_SANDBOX; Integrated Security=SSPI");
SqlCommand command;
command = new SqlCommand("oakb.sp_tm_bin_upd", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@src",bt);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
File.Delete("Задачник.bin");
MessageBox.Show("ok");
}
Дальше в основное приложение добавил код на проверку актуальности
if (isActualVersion () == 0)
{
MessageBox.Show("Задачник устарел, начинаем устанавливать новый");
Updating();
System.Diagnostics.Process.GetCurrentProcess().Kill();
// this.Close(); Environment.Exit(0);
}
public int isActualVersion()
{
command = new SqlCommand("OAKB.sp_tm_ver_cntrl", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@ver", typeof(Main).Assembly.GetName().Version.ToString());
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
if (reader[0].ToString() == "ok") return 1;
if (reader[0].ToString() == "")
{
return 0;
}
else { MessageBox.Show(reader[0].ToString()); this.Close(); return 0; }
}
}
return 0;
} // проверка версии задачника
Ну и в случае устаревания, запуск обновления.
public void Updating()
{
File.WriteAllBytes("Задачник.bin", DownloadBinZad());
File.WriteAllBytes("Update.exe", Properties.Resources.Update);
System.Diagnostics.Process.Start("Update.exe");
return;
} //функция обновления
private byte[] DownloadBinZad()
{
command = new SqlCommand("OAKB.sp_tm_bin_extr", connection);
command.CommandType = CommandType.StoredProcedure;
byte[] bt = null;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
bt = (byte[]) reader[0];
}
}
return bt;
} // скачать бинарник задачника из БД
Запускается программка, которая ждет 3 секунды, пока закроется основное приложение и начинает менять файлы.
static void Main(string[] args)
{
Thread.Sleep(3000);
Console.WriteLine("Обновляемся! не трогайте меня");
File.Delete("Задачник.exe");
byte[] bin = File.ReadAllBytes("Задачник.bin");
File.WriteAllBytes("Задачник.exe", bin);
File.Delete("Задачник.bin");
ProcessStartInfo info = new ProcessStartInfo();
info.Arguments = "/C choice /C Y /N /D Y /T 3 & Del " + AppDomain.CurrentDomain.BaseDirectory + "Update.exe";
info.WindowStyle = ProcessWindowStyle.Hidden;
info.CreateNoWindow = true;
info.FileName = "cmd.exe";
Process.Start(info);
Process.GetCurrentProcess().Kill();
Process.Start(Directory.GetCurrentDirectory() + "\\Задачник.exe");
return;
}
На этом все. Теперь вы знаете оригинальный способ обновления своего приложения.
Успехов в разработке!