wip auto-update

This commit is contained in:
dovholuknf
2020-11-01 23:03:59 -05:00
parent 06eade3c1e
commit be16392571
5 changed files with 162 additions and 134 deletions
+9 -6
View File
@@ -8,7 +8,6 @@
<ROW Property="AI_FrameColor" Value="powderblue" MultiBuildValue="AnyCPU_Release:deepskyblue" MsiKey="AI_FrameColor"/>
<ROW Property="AI_ImagesColor" Value="powderblue" MsiKey="AI_ImagesColor"/>
<ROW Property="AI_PREDEF_LCONDS_PROPS" Value="AI_DETECTED_INTERNET_CONNECTION"/>
<ROW Property="AI_PROPPATH_PERBUILD_App.config" Value="..\ZitiUpdateService\bin\Release\App.config"/>
<ROW Property="AI_PROPPATH_PERBUILD_ZitiDesktopEdge.exe" Value="..\DesktopEdge\bin\Release\ZitiDesktopEdge.exe"/>
<ROW Property="AI_PROPPATH_PERBUILD_ZitiDesktopEdge.exe.config" Value="..\DesktopEdge\bin\Release\ZitiDesktopEdge.exe.config"/>
<ROW Property="AI_PROPPATH_PERBUILD_ZitiUpdateService.exe" Value="..\ZitiUpdateService\bin\Release\ZitiUpdateService.exe"/>
@@ -50,10 +49,12 @@
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
<ROW Component="AI_ExePath" ComponentId="{F9B15650-F37D-424A-B159-B54B9F36EC2C}" Directory_="APPDIR" Attributes="260" KeyPath="AI_ExePath"/>
<ROW Component="APPDIR" ComponentId="{B3881A25-6890-4920-9F69-CACA0C9ABA63}" Directory_="APPDIR" Attributes="0"/>
<ROW Component="App.config" ComponentId="{27FAD46C-8379-4680-8506-4BCBA5A012E8}" Directory_="APPDIR" Attributes="0" KeyPath="App.config" Type="0"/>
<ROW Component="App.config" ComponentId="{27FAD46C-8379-4680-8506-4BCBA5A012E8}" Directory_="APPDIR" Attributes="0" KeyPath="ZitiDesktopEdge.exe.config" Type="0"/>
<ROW Component="NLog.dll" ComponentId="{384D38B5-A4A0-4BC6-886A-82153E2687ED}" Directory_="APPDIR" Attributes="0" KeyPath="NLog.dll"/>
<ROW Component="Newtonsoft.Json.dll" ComponentId="{5D7B59CE-A1B5-4EE9-842E-0206408F8674}" Directory_="APPDIR" Attributes="0" KeyPath="Newtonsoft.Json.dll"/>
<ROW Component="ProductInformation" ComponentId="{4FC3A7CB-D334-466A-A919-E6A237EF4443}" Directory_="APPDIR" Attributes="260" KeyPath="Version"/>
<ROW Component="SHORTCUTDIR" ComponentId="{3A88A759-A3FE-443F-A6D9-0D97BA424B2E}" Directory_="SHORTCUTDIR" Attributes="0"/>
<ROW Component="ZitiDesktopEdge.Client.dll" ComponentId="{7834CBFB-BA9A-4337-9603-507C71135B01}" Directory_="APPDIR" Attributes="0" KeyPath="ZitiDesktopEdge.Client.dll"/>
<ROW Component="ZitiDesktopEdge.exe" ComponentId="{FDDCF14B-4FAF-469F-810E-0877A0DD5F3B}" Directory_="APPDIR" Attributes="0" KeyPath="ZitiDesktopEdge.exe"/>
<ROW Component="ZitiUpdateService.exe" ComponentId="{01B4F535-D4A3-44CD-BB2D-A3A905A095D6}" Directory_="APPDIR" Attributes="0" KeyPath="ZitiUpdateService.exe"/>
<ROW Component="libgcc_s_seh1.dll" ComponentId="{B97B6447-8941-4F04-AA22-50D34E0A0F1A}" Directory_="APPDIR" Attributes="256" KeyPath="libgcc_s_seh1.dll"/>
@@ -68,7 +69,6 @@
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
<ROW File="ZitiDesktopEdge.exe" Component_="ZitiDesktopEdge.exe" FileName="ZITIDE~1.EXE|ZitiDesktopEdge.exe" Attributes="0" SourcePath="&lt;AI_APPPATH_PERBUILD_ZitiDesktopEdge.exe&gt;" SelfReg="false" DigSign="true"/>
<ROW File="App.config" Component_="App.config" FileName="APP~1.CON|App.config" Attributes="0" SourcePath="&lt;AI_APPPATH_PERBUILD_App.config&gt;" SelfReg="false"/>
<ROW File="ZitiDesktopEdge.exe.config" Component_="App.config" FileName="ZITIDE~1.CON|ZitiDesktopEdge.exe.config" Attributes="0" SourcePath="&lt;AI_APPPATH_PERBUILD_ZitiDesktopEdge.exe.config&gt;" SelfReg="false"/>
<ROW File="ZitiUpdateService.exe" Component_="ZitiUpdateService.exe" FileName="ZITIUP~1.EXE|ZitiUpdateService.exe" Attributes="0" SourcePath="&lt;AI_APPPATH_PERBUILD_ZitiUpdateService.exe&gt;" SelfReg="false" DigSign="true"/>
<ROW File="ZitiUpdateService.exe.config" Component_="App.config" FileName="ZITIUP~1.CON|ZitiUpdateService.exe.config" Attributes="0" SourcePath="&lt;AI_APPPATH_PERBUILD_ZitiUpdateService.exe.config&gt;" SelfReg="false"/>
@@ -80,9 +80,10 @@
<ROW File="ziti.ico" Component_="App.config" FileName="ziti.ico" Attributes="0" SourcePath="ziti.ico" SelfReg="false"/>
<ROW File="Newtonsoft.Json.dll" Component_="Newtonsoft.Json.dll" FileName="NEWTON~1.DLL|Newtonsoft.Json.dll" Attributes="0" SourcePath="..\DesktopEdge\bin\Release\Newtonsoft.Json.dll" SelfReg="false"/>
<ROW File="collectlogs.ps1" Component_="App.config" FileName="COLLEC~1.PS1|collect-logs.ps1" Attributes="0" SourcePath="collect-logs.ps1" SelfReg="false"/>
<ROW File="ZitiDesktopEdge.Client.dll" Component_="ZitiDesktopEdge.Client.dll" FileName="ZITIDE~1.DLL|ZitiDesktopEdge.Client.dll" Attributes="0" SourcePath="..\ZitiDesktopEdge.Client\bin\Release\ZitiDesktopEdge.Client.dll" SelfReg="false"/>
<ROW File="NLog.dll" Component_="NLog.dll" FileName="NLog.dll" Attributes="0" SourcePath="..\ZitiUpdateService\bin\Release\NLog.dll" SelfReg="false"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.AppPathsComponent">
<ROW Name="AI_APPPATH_PERBUILD_App.config" Path="[|AI_PROPPATH_PERBUILD_App.config]" Type="2" Content="0"/>
<ROW Name="AI_APPPATH_PERBUILD_ZitiDesktopEdge.exe" Path="[|AI_PROPPATH_PERBUILD_ZitiDesktopEdge.exe]" Type="2" Content="0"/>
<ROW Name="AI_APPPATH_PERBUILD_ZitiDesktopEdge.exe.config" Path="[|AI_PROPPATH_PERBUILD_ZitiDesktopEdge.exe.config]" Type="2" Content="0"/>
<ROW Name="AI_APPPATH_PERBUILD_ZitiUpdateService.exe" Path="[|AI_PROPPATH_PERBUILD_ZitiUpdateService.exe]" Type="2" Content="0"/>
@@ -213,6 +214,8 @@
<ROW Feature_="MainFeature" Component_="ziti.dll"/>
<ROW Feature_="MainFeature" Component_="zititunnel.exe"/>
<ROW Feature_="MainFeature" Component_="Newtonsoft.Json.dll"/>
<ROW Feature_="MainFeature" Component_="ZitiDesktopEdge.Client.dll"/>
<ROW Feature_="MainFeature" Component_="NLog.dll"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
<ROW Name="ziti.exe" SourcePath="ziti.ico" Index="0"/>
@@ -267,11 +270,11 @@
<ROW Registry="Version" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Version" Value="[ProductVersion]" Component_="ProductInformation"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiServCtrlComponent">
<ROW ServiceControl="ZitiUpdateService.exe" Name="ziti-monitor" Event="160" Wait="0" Component_="ZitiUpdateService.exe"/>
<ROW ServiceControl="ZitiUpdateService.exe" Name="ziti-monitor" Event="161" Wait="0" Component_="ZitiUpdateService.exe"/>
<ROW ServiceControl="zititunnel.exe" Name="ziti" Event="161" Wait="0" Component_="zititunnel.exe"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiServInstComponent">
<ROW ServiceInstall="ZitiUpdateService.exe" Name="ziti-monitor" DisplayName="Ziti Desktop Monitor Service" ServiceType="16" StartType="2" ErrorControl="1" Component_="ZitiUpdateService.exe" Description="Monitors and updates the Ziti Access Service"/>
<ROW ServiceInstall="ZitiUpdateService.exe" Name="ziti-monitor" DisplayName="Ziti Desktop Monitor Service" ServiceType="16" StartType="2" ErrorControl="32769" Component_="ZitiUpdateService.exe" Description="Monitors and updates the Ziti Access Service"/>
<ROW ServiceInstall="zititunnel.exe" Name="ziti" DisplayName="Ziti Desktop Edge Service" ServiceType="16" StartType="2" ErrorControl="32769" Component_="zititunnel.exe" Description="Access your Networks Secured by Ziti"/>
</COMPONENT>
<COMPONENT cid="caphyon.advinst.msicomp.MsiShortsComponent">
+15
View File
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ZitiUpdateService {
interface IUpdateCheck {
bool IsUpdateAvailable(Version current);
string FileName();
void CopyUpdatePackage(string destinationFolder, string destinationName);
bool AlreadyDownloaded(string destinationFolder, string destinationName);
}
}
+88
View File
@@ -0,0 +1,88 @@
using System;
using System.IO;
using System.Net;
using NLog;
using Newtonsoft.Json.Linq;
namespace ZitiUpdateService {
internal class GithubCheck : IUpdateCheck {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
string url;
string downloadUrl = null;
string downloadFileName = null;
public GithubCheck(string url) {
this.url = url;
}
public bool AlreadyDownloaded(string destinationFolder, string destinationName) {
return File.Exists(Path.Combine(destinationFolder, destinationName));
}
public void CopyUpdatePackage(string destinationFolder, string destinationName) {
WebClient webClient = new WebClient();
string dest = Path.Combine(destinationFolder, destinationName);
Logger.Info("download started: {0}", downloadUrl);
webClient.DownloadFile(downloadUrl, dest);
Logger.Info("download complete. file at {0}", dest);
}
public string FileName() {
return downloadFileName;
}
public bool IsUpdateAvailable(Version current) {
HttpWebRequest httpWebRequest = WebRequest.CreateHttp(url);
httpWebRequest.Method = "GET";
httpWebRequest.ContentType = "application/json";
httpWebRequest.UserAgent = "OpenZiti UpdateService";
HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream());
string result = streamReader.ReadToEnd();
JObject json = JObject.Parse(result);
string serverVersion = json.Property("tag_name").Value.ToString() + ".0";
Version published = new Version(serverVersion);
int compare = current.CompareTo(published);
if (compare < 0) {
Logger.Info("an upgrade is available.");
} else if (compare > 0) {
Logger.Info("the version installed is newer than the released version");
return false;
}
JArray assets = JArray.Parse(json.Property("assets").Value.ToString());
foreach (JObject asset in assets.Children<JObject>()) {
downloadUrl = asset.Property("browser_download_url").Value.ToString();
break;
}
if (downloadUrl == null) {
Logger.Error("DOWNLOAD URL not found at: {0}", url);
return false;
}
downloadFileName = downloadUrl.Substring(downloadUrl.LastIndexOf('/') + 1);
return true;
}
}
internal class FilesystemCheck : IUpdateCheck {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public bool AlreadyDownloaded(string destinationFolder, string destinationName) {
return File.Exists(Path.Combine(destinationFolder, destinationName));
}
public void CopyUpdatePackage(string destinationFolder, string destinationName) {
throw new NotImplementedException();
}
public string FileName() {
return downloadFileName;
}
public bool IsUpdateAvailable(Version current) {
throw new NotImplementedException();
}
}
}
+48 -128
View File
@@ -18,6 +18,7 @@ using ZitiDesktopEdge.ServiceClient;
using NLog;
using Newtonsoft.Json.Linq;
using System.Reflection;
using NLog.Config;
namespace ZitiUpdateService {
public partial class UpdateService : ServiceBase {
@@ -25,29 +26,25 @@ namespace ZitiUpdateService {
private string _version = "";
private bool _isNew = true;
private System.Timers.Timer _updateTimer = new System.Timers.Timer();
private bool inUpdateCheck = false;
private string _rootDirectory = "";
private string _logDirectory = "";
private string _versionType = "latest";
private Client svc = new Client();
private bool running = false;
ServiceController controller;
public UpdateService() {
InitializeComponent();
Client svc = new Client();
Logger.Info("Initializing");
svc.OnClientConnected += Svc_OnClientConnected;
svc.OnTunnelStatusEvent += Svc_OnTunnelStatusEvent;
svc.OnClientDisconnected += Svc_OnClientDisconnected;
svc.OnShutdownEvent += Svc_OnShutdownEvent;
try {
svc.Connect();
} catch {
svc.Reconnect();
}
svc.WaitForConnection();
}
public void Debug() {
@@ -55,6 +52,7 @@ namespace ZitiUpdateService {
}
protected override void OnStart(string[] args) {
try {
if (ConfigurationManager.AppSettings.Get("Version") != null) _versionType = ConfigurationManager.AppSettings.Get("Version");
} catch (Exception e) {
@@ -64,16 +62,29 @@ namespace ZitiUpdateService {
if (!Directory.Exists(_rootDirectory)) Directory.CreateDirectory(_rootDirectory);
_logDirectory = Path.Combine(_rootDirectory, "Logs");
if (!Directory.Exists(_logDirectory)) Directory.CreateDirectory(_logDirectory);
Logger.Info("Setup Watchers");
SetupServiceWatchers();
if (!running) {
running = true;
Task.Run(() => {
SetupServiceWatchers();
});
}
Logger.Info("initialized and running");
}
protected override void OnStop() {
Logger.Info("Stopping update Service");
Logger.Info("stopping update service");
}
private void SetupServiceWatchers() {
Logger.Info("Setting Up Watchers");
Logger.Info("setting up watches");
try {
svc.Connect();
} catch {
//svc.Reconnect();
}
//svc.WaitForConnection();
var updateTimerInterval = ConfigurationManager.AppSettings.Get("UpdateTimer");
var upInt = TimeSpan.Zero;
@@ -95,142 +106,51 @@ namespace ZitiUpdateService {
private void CheckUpdate(object sender, ElapsedEventArgs e) {
if (inUpdateCheck) return;
inUpdateCheck = true; //simple semaphone
try {
Logger.Info("checking for update");
var updateUrl = ConfigurationManager.AppSettings.Get("UpdateUrl");
if (string.IsNullOrEmpty(updateUrl)) {
updateUrl = "https://api.github.com/repos/openziti/desktop-edge-win/releases/latest";
}
IUpdateCheck check = new GithubCheck(updateUrl);
var updateUrl = ConfigurationManager.AppSettings.Get("UpdateUrl");
if (string.IsNullOrEmpty(updateUrl)) {
updateUrl = "https://api.github.com/repos/openziti/desktop-edge-win/releases/latest";
}
try {/*
HttpWebRequest httpWebRequest = WebRequest.CreateHttp(updateUrl);
httpWebRequest.Method = "GET";
httpWebRequest.ContentType = "application/json";
httpWebRequest.UserAgent = "OpenZiti UpdateService";
HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream());
string result = streamReader.ReadToEnd();
JObject json = JObject.Parse(result);
string currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
string serverVersion = json.Property("tag_name").Value.ToString() + ".0";
string currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); //fetch from ziti?
Version installed = new Version(currentVersion);
Version published = new Version(serverVersion);
int compare = installed.CompareTo(published);
if (compare < 0) {
Logger.Info("an upgrade is available. starting update process.");
} else if (compare > 0) {
Logger.Info("the version installed is newer than the released version");
if (!check.IsUpdateAvailable(installed)) {
Logger.Debug("update check complete. no update available");
inUpdateCheck = false;
return;
}
JArray assets = JArray.Parse(json.Property("assets").Value.ToString());
string downloadUrl = null;
foreach (JObject asset in assets.Children<JObject>()) {
downloadUrl = asset.Property("browser_download_url").Value.ToString();
break;
}
if(downloadUrl == null) {
Logger.Error("DOWNLOAD URL not found at: {0}", updateUrl);
return;
}
*/
Logger.Info("update is available.");
var curdir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var updateFolder = $"{curdir}{Path.DirectorySeparatorChar}updates";
Directory.CreateDirectory(updateFolder);
var downloadUrl = "https://github.com/openziti/desktop-edge-win/releases/download/1.2.12/Ziti.Desktop.Edge.Client-1.2.13.exe";
string filename = downloadUrl.Substring(downloadUrl.LastIndexOf('/') + 1);
Logger.Info("copying update package");
string filename = check.FileName();
if (string.IsNullOrEmpty(filename)) {
Logger.Warn("filename not found from web request. using generic filename {0}", "Ziti.Desktop.Edge.Client.exe");
}
string fileDestination = Path.Combine(updateFolder, filename);
Logger.Info("Checking to see if the file has been downloaded previously");
if (File.Exists(fileDestination)) {
Logger.Info("file already exists at {0}. not downloading again", fileDestination);
} else {
Logger.Info("update found. downloading update from {0} to {1}", downloadUrl, fileDestination);
WebClient myWebClient = new WebClient();
myWebClient.DownloadFile(downloadUrl, fileDestination);
Logger.Info("update downloaded");
if (check.AlreadyDownloaded(updateFolder, filename)) {
Logger.Info("package has already been downloaded - moving to install phase");
} else {
Logger.Info("copying update package begins");
check.CopyUpdatePackage(updateFolder, filename);
Logger.Info("copying update package complete");
}
StopZiti();
// shell out to a new process and run the uninstall, reinstall steps which SHOULD stop this current process as well
string fileDestination = Path.Combine(updateFolder, filename);
Process.Start(fileDestination, "/passive");
} catch (Exception ex) {
Logger.Error(ex, "Unexpected error has occurred");
}
}
inUpdateCheck = false;
}
private void UpdateServiceFiles(string currentVersion, string _versionUrl, string _serviceUrl) {
var request = WebRequest.Create(_versionUrl) as HttpWebRequest;
var response = request.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
var result = readStream.ReadToEnd();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(result);
XmlNode node = xmlDoc.SelectSingleNode("metadata/versioning/"+_versionType);
string version = node.InnerText;
Logger.Info("Got Version: " + version+" from "+_versionType);
if (_version.Trim() == currentVersion.Trim()) {
_version = currentVersion;
Logger.Info("Version local is the same as the version remote: " + version);
return;
}
StopZiti();
string remoteService = _serviceUrl.Replace("${version}", version);
if (!Directory.Exists(Path.Combine(_rootDirectory, "Service"))) Directory.CreateDirectory(Path.Combine(_rootDirectory, "Service"));
string[] files = Directory.GetFiles(Path.Combine(_rootDirectory, "Service"));
foreach (string file in files) {
try {
Logger.Info("Delete: " + file);
File.Delete(file);
} catch (Exception e) {
EventLog.WriteEntry("Ziti", e.ToString(), EventLogEntryType.Error);
}
}
WebClient webClient = new WebClient();
Logger.Info("Get From: "+remoteService);
webClient.DownloadFile(remoteService, Path.Combine(_rootDirectory, "Service") + @"\windows-tunneler.zip");
Logger.Info("Zip Downloaded");
ZipFile.ExtractToDirectory(Path.Combine(_rootDirectory, "Service") + @"\windows-tunneler.zip", Path.Combine(_rootDirectory, "Service"));
Logger.Info("Zip UnZipped");
File.WriteAllText(Path.Combine(_rootDirectory, @"Service\Version.txt"), version);
_version = version;
if (_isNew) {
Logger.Info("Installing Service " + _version);
ProcessStartInfo installService = new ProcessStartInfo();
installService.CreateNoWindow = true;
installService.UseShellExecute = true;
installService.FileName = Path.Combine(_rootDirectory, "Service") + @"\ziti-tunnel.exe";
installService.WindowStyle = ProcessWindowStyle.Hidden;
installService.Arguments = "install";
Logger.Info("Install Using " + installService.FileName + " " + installService.Arguments);
try {
Process exeProcess = Process.Start(installService);
exeProcess.WaitForExit();
Logger.Info("Installed " + installService.FileName + " " + installService.Arguments);
} catch (Exception e) {
Logger.Info("Cannot Install Service - " + e.ToString());
}
} else {
// nothing to do
}
StartZiti();
}
private void StartZiti() {
controller = ServiceController.GetServices().FirstOrDefault(s => s.ServiceName == "ziti");
if (controller != null && controller.Status != ServiceControllerStatus.Running && controller.Status != ServiceControllerStatus.StartPending && controller.Status != ServiceControllerStatus.ContinuePending) {
@@ -103,6 +103,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="IUpdateCheck.cs" />
<Compile Include="Program.cs" />
<Compile Include="ProjectInstaller.cs">
<SubType>Component</SubType>
@@ -110,6 +111,7 @@
<Compile Include="ProjectInstaller.Designer.cs">
<DependentUpon>ProjectInstaller.cs</DependentUpon>
</Compile>
<Compile Include="UpdateCheckers.cs" />
<Compile Include="UpdateService.cs">
<SubType>Component</SubType>
</Compile>