I have a solution that has two projects. one main project and one that serves as an Updater.
To perform the upgrade, within the main project, I call a console application as follows.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Lê arquivo xml e manipula arquivo xml
XmlDocument doc = new XmlDocument();
doc.Load("http://www.meusite.org.br/Cantina/arquivoXML.xml");
XmlNode node = doc.DocumentElement.SelectSingleNode("/Application/Version");
XmlNode node1 = doc.DocumentElement.SelectSingleNode("/Application/ZipFile");
string version = node.InnerText;
string zipfile = node1.InnerText;
string End = (@"\aps-serverweb\wwwroot\meusite.org.br\Cantina\");
string file = (End + zipfile);
string versionAssembly = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
//valida version (versão disponível no servidor para atualização) e versionAssembly (versão do sistema isntalado)
if (Convert.ToDouble(version) <= Convert.ToDouble(versionAssembly))
{
// MessageBox.Show("Sistema Atualizado" + version);
}
else
{
//chama o projeto de atualiação de sistema console application IASD.ASCS.Updater
Process myProc = Process.Start("Updater.exe");
}
}
When calling the Updater (console application) process, the following code is executed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using Ionic.Zip;
using System.Xml;
using System;
using System.IO;
using Microsoft.VisualBasic;
using System.Threading;
namespace Updater
{
class Program
{
static void Main(string[] args)
{
string nomeExecutavel = "IASD.ASCS.WPF.exe";
foreach (Process pr in Process.GetProcessesByName(nomeExecutavel))
{
if (!pr.HasExited) pr.Kill();
}
//Lê e manipula arquivo xml com as informações do arquivo zip contendo a atualização disponível
XmlDocument doc = new XmlDocument();
doc.Load("http://www.meusite.org.br/Cantina/arquivoXML.xml");
XmlNode node = doc.DocumentElement.SelectSingleNode("/Application/Version");
XmlNode node1 = doc.DocumentElement.SelectSingleNode("/Application/ZipFile");
string version = node.InnerText;
string zipfile = node1.InnerText;
string End = (@"\aps-serverweb\wwwroot\meusite.org.br\Cantina\");
string file = (End + zipfile);
string versionAssembly = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
//Utiliza os métodos da biblioteca dotnetzip chamada Ionic.zip para baixar e extrair arquivos zip
ZipFile zipFile = ZipFile.Read(file);
{
foreach (ZipEntry zipEntry in zipFile)
{
zipEntry.Extract(@"C:\IASD\CantinaEscolar\Temp\", ExtractExistingFileAction.OverwriteSilently);
}
}
foreach (Process pr in Process.GetProcessesByName(nomeExecutavel))
{
if (!pr.HasExited) pr.Kill();
}
//Transfere os arquivos baixados no diretório Temp para o diretório instalação em c:\IASD\CantinaEscolar
string dirTemp = @"c:\IASD\CantinaEscolar\Temp";
string dirInstalacao = @"c:\IASD\CantinaEscolar";
string[] arquivos = Directory.GetFiles(dirTemp);
foreach (string item in arquivos)
{
string nomedoarquivo = Path.GetFileName(item);
string destino = Path.Combine(dirInstalacao, nomedoarquivo);
File.Copy(item, destino, true);
}
string[] arquivosApagar = Directory.GetFiles(dirTemp);
foreach (string item in arquivosApagar)
{
File.Delete(item);
}
foreach (Process pr in Process.GetProcessesByName(nomeExecutavel))
{
if (!pr.HasExited) pr.Start();
}
//Encerra o processo Updater
string nomeExecutavel2 = "Updater.exe";
foreach (Process pr2 in Process.GetProcessesByName(nomeExecutavel2))
{
if (!pr2.HasExited) pr2.Kill();
}
}
}
}
The updater basically does the following
Terminates the main process
Checks if you have an update available in the directory through an xml file. (this is also done in the main process to enter the Updater).
Unpack to a temporary folder.
Copy to the main project installation folder.
Deletes files from the c:\IASD\CantinaEscolar\Temp
directory
This works flawlessly running within visual studio.
Now when installing the application on a computer, at the time of copying the 'update' files from the Temp folder to the installation directory, an error is returned stating that the file is running.
The process that needs to be terminated when I'm running the application in Visual Studio is called IASD.ASCS.WPF.vshost
. When the application is installed, the process changes name, becoming IASD.ASCS.WPF.exe
which is the name of the project inside the solution as well as the name of its executable that is in the bin\Debug
folder.
I tried to end this process in the following ways and did not succeed:
String nome = "IASD.ASCS.WPF.exe";
// Obtém lista de processos
Process[] processos = Process.GetProcesses();
foreach (Process p in processos)
{
if (p.ProcessName.ToUpper() == nome.ToUpper())
{
// Tenta fechar a janela principal,
// se falhar invoca o método Kill()
if (!p.CloseMainWindow())
{
p.Kill();
}
p.Close(); // Libera recursos associados.
}
}
Process[] processes = Process.GetProcessesByName("Login.exe");
foreach (Process process in processes)
{
process.Kill();
}
Process[] processes1 = Process.GetProcessesByName("Login");
foreach (Process process1 in processes1)
{
process1.Kill();
}
Process[] processes2 = Process.GetProcessesByName("IASD.ASCS.WPF.exe");
foreach (Process process2 in processes2)
{
process2.Kill();
}
Process[] processes3 = Process.GetProcessesByName("IASD.ASCS.WPF");
foreach (Process process3 in processes3)
{
process3.Kill();
}
Process[] processes4 = Process.GetProcessesByName("vshost32");
foreach (Process process4 in processes4)
{
process4.Kill();
}
Process[] processes5 = Process.GetProcessesByName("vshost32.exe");
foreach (Process process5 in processes5)
{
process5.Kill();
}
None of them work when the application is installed.
Note: The Login process mentioned in the code is the name of the WPF created according to the image of the Windows task manager:
How could I close the IASD.ASCS.WPF.exe process so that the application console will copy the files from the temp folder to the application's installation folder and then restart this process?