4
I have a solution that has two projects. a main project and another that serves as 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
Closes the main proceedings
Checks if you have an update available in the directory via an xml file. (This is also done in the main process to enter Updater).
Unzip to a temporary folder.
Copy to the installation folder of the main project.
Deletes the files from the directory
c:\IASD\CantinaEscolar\Temp
This works perfectly running inside the visual studio.
Now when installing the application on a computer, when copying the 'update' files from the Temp folder to the installation directory, an error is returned stating that the file is running.
The process needed to be terminated when running the application in Visual Studio is called IASD.ASCS.WPF.vshost
. Already when the application is installed, the process changes name, becoming IASD.ASCS.WPF.exe
which is the name of the project within Solution as well as the name of its executable that is in the folder bin\Debug
.
I tried to end this process in the following ways and I 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 cited in the code is the name of the WPF created as image of the Windows task manager:
How could you terminate the IASD.ASCS.WPF.exe process for the application console to copy the files from the temp folder to the application installation folder and then restart this process?
It didn’t work. Includes string wpfExe = @"c: IASD Cantinaescola IASD.ASCS.WPF.exe"; File.Delete(wpfExe); Inside the Updater before the line that copies the files and even then appears the message that the IASD.ASCS.WPF.exe files are being executed by another process. In debugging the error returns at line 56, right in foreach: foreach (string item in files) string filename = Path.Getfilename(item); string destination = Path.Combine(dirInstallacao, filename); File.Copy(item, destination, true); }
– Paulo Romeiro
In doing so, the application may be taking a while to close... so inside Updater, you may need to try several times to get access to the file, until it is released.
– Miguel Angelo